Hello everyone,
I’m (almost) new to root, my problem is: I have a tree with some “raw data”, I want to do some analysis and save the output to another tree but keeping a “link” between the two trees.
More detailed version: in the first tree I have signals from several detectors. The analysis consists in putting toghether the right data (signals coming from same detector, same plane, same bar, etc…) and creating new things, for example a “hit” (which will be described by more than one variable, e.g. “hit position”, etc…).
The so created “hit” comes from a well defined subset of entries of the first tree.
According to your expertise, which could be the best approach to save this “hits” in a second tree, keeping track of which entries of the first tree they come from?
My searches led me to a lot of pages from the User Manual, I read about Friend trees, BuildIndex, EntryLists … and some threads of this forum as well (as an example this [url=https://root-forum.cern.ch/t/ttree-with-a-fixed-branch/13996/6 with a “fixed” branch[/url] which seems to be similar to what I need), but I still cannot put all the things togheter to build a simple working model. I think I need some smart hint!
I wrote a simple macro modifying some tutorials to describe my problem in a more pratical way.
In the macro below the first tree is “T” and it has a single branch n which is a random integer. T has 10 entries. The (stupid) analysis consists in taking all the even numbers and computing the average, and the same thing for the odd ones. Then I save these (two) averages to an output tree called AVE. Then I save both T and AVE to a file called “outfile.root”. Then AVE will have 2 entries.
Here is the code for this simple working model:
[code]#include “TTree.h”
#include “TFile.h”
#include "TRandom.h"
void TheFirstTree() {
// create a simple tree with integers
TFile *f = new TFile(“firstfile.root”,“recreate”);
TTree *T = new TTree(“T”,“tree with random integers”);
int n ;
TRandom1 r;
T->Branch(“n”,&n,“n/I”);
for (int i=0;i<10;i++) {
r.SetSeed(0);
n=int(100*r.Rndm(0)) ;
// fill T tree with the random integers
T->Fill();
}
f->cd();
T->Write();
f->Close();
}
void SecondTree() {
// open the first tree with the integers
TFile *f = new TFile(“firstfile.root”,“READ”);
// open another file for the output
TFile *f2 = new TFile(“outfile.root”,“RECREATE”);
// get the first tree
TTree * T = (TTree*)f->Get(“T”);
int n ;
T->SetBranchAddress(“n”,&n);
// prepare another tree for the the “average”
// of a given subset of the orginal tree
TTree *AVE = new TTree(“AVE”,“tree for the averages”);
float a;
AVE->Branch(“a”,&a,“a/f”);
// define an array in which some “averages” will be stored
const int max_possible_average_type=2;
float averages[max_possible_average_type]={0.};
int avcounter[max_possible_average_type]={0};
// LOOP on entries of the first tree
// => do some analysis
for (int i=0 ; i< T->GetEntries() ; i++) {
T->GetEntry(i);
cout << "reading entry nr. "<< i << ", n is "<<n ;
// if n is EVEN (average type 0)...
if (n%2==0) {
averages[0] = (averages[0]*avcounter[0] + n) / (avcounter[0]+1) ;
avcounter[0]++;
cout << " EVEN => average now is "<< averages[0] << endl;
}
// if n is ODD (average type 1)...
if (n%2==1) {
averages[1] = (averages[1]*avcounter[1] + n) / (avcounter[1]+1) ;
avcounter[1]++;
cout << " ODD => average now is "<< averages[1] << endl;
}
}
// end of the LOOP ==> write results to the output tree
for (int atype=0 ; atype < max_possible_average_type ; atype++) {
a = averages[atype] ;
AVE->Fill();
}
// write both the 1st tree and the 2nd one to the output file
f2->cd();
T->Write();
AVE->Write();
f2->Close();
}
void test(){
cout << “START…”<<endl;
TheFirstTree();
SecondTree();
cout << “…END”<<endl;
}
[/code]
Well, my question applied to this model is: how do I have to create AVE in a way that I can open outfile.root and plot
T->Draw(“n”,mysmartcut)
where mysmartcut is “consider only the entries of T which have been used to create the ODD average during the analysis”?
[size=85](well, I know that the result can be obtained with T->Draw(“n”,“n%2==1”), but it’s not what I need. I hope it’s clear from my post)[/size]
Thanks a lot in advance!