Problem with creating a Tree from another+histogram

  • Thread starter Thread starter ChrisVer
  • Start date Start date
  • Tags Tags
    Tree
Click For Summary

Discussion Overview

The discussion revolves around the process of creating a new tree from an existing tree and a histogram in the context of ROOT, a data analysis framework commonly used in high-energy physics. Participants explore how to associate weights derived from a histogram with entries in a tree, addressing both the logic of the implementation and the technical aspects of using ROOT functions.

Discussion Character

  • Technical explanation
  • Mathematical reasoning
  • Debate/contested

Main Points Raised

  • One participant proposes using the histogram values as weights for tree entries, suggesting a loop to check the bin corresponding to each entry's value.
  • Another participant suggests simplifying the bin-checking logic using the FindBin method, which directly retrieves the appropriate bin index for a given value.
  • There is a discussion about defining a new branch in the tree to store the weights and using the Fill method to populate this branch within a loop.
  • Concerns are raised about the risks of overwriting existing trees and the potential space implications, leading to the suggestion of using friend trees instead of cloning existing trees.
  • One participant expresses uncertainty about the TTree::Fill method, noting discrepancies in the output tree compared to expected results, and questions the definition of a variable used in the filling process.
  • Another participant points out a potential issue with data types, indicating that defining weight as a double while filling it as a float could lead to problems.

Areas of Agreement / Disagreement

Participants generally agree on the need to associate weights from a histogram with tree entries, but there are multiple competing views on the best approach to implement this, particularly regarding the use of friend trees versus cloning existing trees. The discussion remains unresolved regarding the specific implementation details and the issues encountered with the TTree::Fill method.

Contextual Notes

Participants mention potential limitations related to data types and the implications of overwriting existing trees, but these points remain unresolved and are subject to further clarification.

ChrisVer
Science Advisor
Messages
3,372
Reaction score
465
Suppose I have a histogram : h(x)
and I want to take the different values h(x_i) 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 50 ~\text{GeV} and the value x of the iEntry is x_{i} and lies between 250 &lt; x_i &lt; 300, then the value of iEntry-th value of the weight should be the value of the histogram h(x) 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)
 
Technology 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

Similar threads

  • · Replies 7 ·
Replies
7
Views
4K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 1 ·
Replies
1
Views
5K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
471
  • · Replies 175 ·
6
Replies
175
Views
28K
Replies
2
Views
3K
  • · Replies 43 ·
2
Replies
43
Views
13K
  • · Replies 7 ·
Replies
7
Views
6K