# Problem with creating a Tree from another+histogram

1. Feb 24, 2016

### ChrisVer

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:
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);

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 < x_i < 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)

2. Feb 24, 2016

### 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

3. Feb 24, 2016

### ChrisVer

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
4. Feb 24, 2016

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

5. Feb 24, 2016

### ChrisVer

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?

6. Feb 24, 2016

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

7. Feb 25, 2016

### ChrisVer

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");

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:

File size:
14.1 KB
Views:
55
• ###### 2.pdf
File size:
13.9 KB
Views:
56
8. Feb 25, 2016

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