Problem with creating a Tree from another+histogram

  • Thread starter Thread starter ChrisVer
  • Start date Start date
  • Tags Tags
    Tree
Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
7 replies · 2K views
Messages
3,372
Reaction score
465
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:
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)
 
Physics news on Phys.org
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
 
  • Like
Likes   Reactions: ChrisVer and Silicon Waffle
mfb said:
is h=h_x? More descriptive variable names would help.
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:
C:
w= h -> GetBinContent(   h->GetXaxis()->FindBin(x)   )
mfb said:
You have to define a branch and add it to the tree, afterwards you can use Fill() in the loop as usual.
That's what I am trying to understand too. So for example I should have defined a new tree:
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:
C:
branch_weight->Fill();
?
 
Last edited:
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.
 
  • Like
Likes   Reactions: ChrisVer
mfb said:
It is easier to update the existing one, see the example I linked to.

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 separate 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.

mfb said:
but then you should clone the old one to keep all the other branches in
I didn't understand this one?
 
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.
 
I am not sure, but there seems to be a problem when I try to use the TTree::Fill() method.
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)...
 

Attachments

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.
 
  • Like
Likes   Reactions: ChrisVer