Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Problem with creating a Tree from another+histogram

  1. Feb 24, 2016 #1

    ChrisVer

    User Avatar
    Gold Member

    Suppose I have a histogram : [itex]h(x)[/itex]
    and I want to take the different values [itex]h(x_i)[/itex] as weights which I can pass in a tree...

    The code I wrote so far, which (theoriticially) would do this job for me looks like this:
    Code (C):

    TFile* fin = new TFile("file_contains_tree_and_histo.root");

    TH1F* h_x = (TH1F*) fin->Get("histo_X");
    TTree* myTree = (TTree*) fin->Get("Tree");
    Float_t x, w;
    float binwidth= h->GetXaxis()->GetBinWidth(1);

    myTree->SetBranchAddress("variable_x", &x)
    Long64_t N_entries = myTree->GetEntries();
    for( int iEntry=0; iEntry<N_entries ; iEntry++){
        myTree->GetEntry(iEntry);  //Get entry i from the existing tree
        int j=0;
        while(j<100){
             if(x> j *binwidth && x<(j+1)*binwidth){
                  //checks if value x is in the range of bin j+1,
                  //if yes then the weight is the value of the histogram
                 //at that value or bin.
                  w= h->GetBinContent(j+1);
                  break; //leave while
             }
             j++;
        }
        // Here I need help to pass w in a new tree
    }
     
    my problem then is that I am not sure if my logic is plausible, I can't think of any other way to do what I am trying to.
    So for example if the histo's binwidth is [itex]50 ~\text{GeV}[/itex] and the value x of the iEntry is [itex]x_{i}[/itex] and lies between [itex]250 < x_i < 300[/itex], then the value of iEntry-th value of the weight should be the value of the histogram [itex]h(x)[/itex] at the bin# 6.
    Then again I am not sure how I can pass/Fill a new tree with the w's... (afterwards I'll try to make the tree friends, and so it will be equivalent to adding safely a new Branch)
     
  2. jcsd
  3. Feb 24, 2016 #2

    mfb

    User Avatar
    2016 Award

    Staff: Mentor

    Where is the point of the while loop? x/binwidth, rounded down, will do the job for equal bin sizes starting at zero.
    Even better, you can use ROOT to directly get the right bin:
    TAxis *xaxis = h->GetXaxis();
    Int_t binx = xaxis->FindBin(x);
    Should also work in one line:
    h->GetXaxis()->FindBin(x);

    is h=h_x? More descriptive variable names would help.

    You have to define a branch and add it to the tree, afterwards you can use Fill() in the loop as usual.
    Example code
     
  4. Feb 24, 2016 #3

    ChrisVer

    User Avatar
    Gold Member

    yes sorry... The point to what I'm trying to do is associate an extra variable I was able to determine from a histogram (QCD fake factors) to trees I obtained from running the derivations on some QCD datasets. The variable x for example is the pT, since my fake factors are given from a histogram h_FakeFactor(pT).
    So the while etc I used because I wanted to tell "if the QCD object has pT=100GeV, go and take the fake factor from the histogram FF= h_FakeFactor(pT=100GeV)".
    I didn't know/thought of the FindBin method, thanks.
    So I guess it should be something like this:
    Code (C):

    w= h -> GetBinContent(   h->GetXaxis()->FindBin(x)   )
     

    That's what I am trying to understand too. So for example I should have defined a new tree:
    Code (C):

    TTree*  tree_friend = new TTree("T_output","weight");
    TBranch* branch_weight = tree_friend->Branch("weight", &w , "w/F");
     
    and in the end of the for loop do:
    Code (C):

    branch_weight->Fill();
     
    ?
     
    Last edited: Feb 24, 2016
  5. Feb 24, 2016 #4

    mfb

    User Avatar
    2016 Award

    Staff: Mentor

    You can make a new tree, but then you should clone the old one to keep all the other branches in. It is easier to update the existing one, see the example I linked to.
    The downside of the update method: it appears as two trees in a TBrowser afterwards, for reasons I don't understand.
     
  6. Feb 24, 2016 #5

    ChrisVer

    User Avatar
    Gold Member

    Yes I've seen that example of "immediately adding branches to a tree". However after some small discussion I was informed that it's quiet risky to try and overwrite my existing trees from the derivation and it can be very heavy for the available space [I think?]... So I think the safest way would be to proceed with friend trees [that's why I'm trying to build a seperate 2nd tree]...Afterwards the treatment of the two trees will be identical and I'll be able to call from my original tree [the one I'm working with] the variable that I created in the other.

    I didn't understand this one?
     
  7. Feb 24, 2016 #6

    mfb

    User Avatar
    2016 Award

    Staff: Mentor

    Ah, friend trees. Then you do not have to clone anything. Just create a new tree with a single branch then. Cloning would create a new tree that has all the old stuff plus your new variable. More handy than friend trees, but if you process TB of data a friend tree is probably better.
     
  8. Feb 25, 2016 #7

    ChrisVer

    User Avatar
    Gold Member

    I am not sure, but there seems to be a problem when I try to use the TTree::Fill() method.
    Code (C):

    Double_t weight, pT;
    Int_t ID;

    //DEFINE THE INPUT STUFF
    TFile* f_input = new TFile("sum.root");
    TTree*  myTree=(TTree*) f_input->Get("T");
    myTree->SetBranchAddress(  "pt",&pT);
    myTree->SetBranchAddress( "ID", &ID );

    TH1* h_Weights_vs_pT = (TH1*) f_input->Get("h_FakeFactor");

    //MAKE THE TREE TO FILL
    TFile* f_output = new TFile("weightOut.root","recreate");
    TTree* myTree_friend = new TTree("weight","weight");
    TBranch* myBranch = myTree_friend->Branch("weight",&weight,"weight/F");

    //MAKE A HISTOGRAM TO FILL TO COMPARE
    TH1F* h_test = new TH1F("h2","h2",100,0.,0.4);

    for(Int_t iEntry=0; iEntry< myTree->GetEntries() ; iEntry++){
        myTree->GetEntry(iEntry);
        if(ID==0)  weight= h_Weights_vs_pT ->GetBinContent( h_Weights_vs_pT ->GetXaxis()->FindBin(pT) );
        else weight=0.0;
        h_test->Fill(FF);
        myTree_friend->Fill();
      }

    h_test->Write();
    f_output->Write();
    f_output->Close();
     
    The result I get is shown in the pdfs : 1 the histogram's fill h_test which looks reasonable but the tree's in 2 is very off (even checking the mean ~e+35)...
     

    Attached Files:

    • 1.pdf
      1.pdf
      File size:
      14.1 KB
      Views:
      45
    • 2.pdf
      2.pdf
      File size:
      13.9 KB
      Views:
      51
  9. Feb 25, 2016 #8

    mfb

    User Avatar
    2016 Award

    Staff: Mentor

    What is FF?

    You define weight as double but fill it as float. That does not work. It is one of the rare cases where the difference really matters.
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook




Similar Discussions: Problem with creating a Tree from another+histogram
  1. Another problem with C (Replies: 7)

  2. Histograms in IDL (Replies: 0)

Loading...