GetCorrelationFactor from TTree

Hello!

What I want to do is this - Loop inside two files with a TTree structure (the two files have the same branches) and then drop event by event to a TH2 and get the Correlation Factor.

Of course, I need only to get one branch from the 1rst file and compare it with all the branches of the second file .The thing is , that TTree’s do not have always the some branches, which means, that I cannot loop inside by using “constant” SetBranchAdress method, as the branches number itself depend on the dataset I run (but the two files have always the same number of branches, ie after every run/dataset). Furthermore, the branches are around 100, so I would like avoiding all this typing, even if the branches have “constant” members always

So, I was trying to do some kind of looping by key (just like it is in the hadd.c example) but can you provide me a full example?

-Get in the 1rst file’s TTree and read 1rst Branch’s event
-Loop in the 2nd file’s TTree and correlate the 1rst file’s Branch entries with all of the second file’s branches
-Put entry into a TH2 histo

Thanks in advance
Alex

use a friend Tree, see TTree::AddFriend at root.cern.ch/root/html/TTree.htm … :AddFriend

Rene

Hi Rene

Thanks for your reply - The only remaining problem, is that (I see in the TreeFriend.C example) I need to know exactly the Branches in order to SetAddress method , but in my case, the Branches, are not constant ones, in the sense that my code generates the TTree (previous step) according to some variables, which are dependant on the dataset itself - So, the input TTree now, does not have always the same Branches - Si,how can I actually read the TTree’s braches (which should be done by key cycling I guess?) and use the TFriend class together to link and then Fill a TH2 histo?

Again, sorry for these naive questions, but would really appreciate some script example

Thanks in advance
A

Hi,

To get the list of branches from the main TTree use TTree::GetListOfBranches and to get the list of friends use GetListOfFriends (which returns a TFriendElement from which you can get the underlying TTree object via TFriendElement::GetTree on which you can call GetListOfBranches()).

Cheers,
Philippe.

see example below

Rene

void correl() { TFile *f1 = new TFile("hsimple1.root"); TFile *f2 = new TFile("hsimple2.root"); TTree *T1 = (TTree*)f1->Get("ntuple"); TTree *T2 = (TTree*)f2->Get("ntuple"); T1->AddFriend(T2,"T2"); TObjArray *lb1 = T1->GetListOfBranches(); Int_t nb = lb1->GetEntries(); for (Int_t i=0;i<nb;i++) { TBranch *b = (TBranch*)lb1->At(i); T1->Draw(Form("%s:T2.%s>>hcor",b->GetName(),b->GetName()),"","goff"); TH2 *hcor = (TH2*)gDirectory->Get("hcor"); printf("branch: %s, correl factor = %g\n",b->GetName(),hcor->GetCorrelationFactor()); } }

Thanks a lot Rene - You are a life-saver!

Yours
Alexis

This solution works very well indeed -

Now, what if one wants to Correlate not the 1rst variable from the ttree1_ with all of the variables of ttree2_, but, “all with all”? ie

1rst from ttree1_ with (1,2,3,4…all rest of ttree2_)
2nd from ttre1_ with(2,3,4,… all rest of ttree2_)

etc
etc

I tried something like

[code] tree1_ = treeSignal;
tree2_ = treeBkg;
tree1_->AddFriend(tree2_,“tree2_”);
TObjArray *lb1 = tree1_->GetListOfBranches();
TObjArray *lb2 = treeBkg->GetListOfBranches();

Int_t nb = lb1->GetEntries();
TBranch *c;TBranch *b;

for (Int_t i=0;i<nb;i++) {
b = (TBranch*)lb1->At(i);
for ( Int_t j=i;j<nb;j++) {
if (j+1<nb) { c = (TBranch*)lb2->At(j+1);}
else {c = (TBranch*)lb2->At(j);}
///to avoid reaching end of nb and crashing at j>nb
tree1_->Draw(Form("%s:tree2_.%s>>hcor",b->GetName(),c->GetName()),"",“goff”);
TH2 hcor = (TH2)gDirectory->Get(“hcor”);

    cout<<"branch:   "<<b->GetName()<<'\t'<< " with " <<c->GetName()<<'\t'<< "   correl factor =   "

<<’\t’<GetCorrelationFactor()<<" "<<var<<endl;
[/code]

but, although loops correctly insides the different TTree branches, the hcor is always zero…

Would really appreciate an answer (again…:wink:

Again, thanks for you help in advance

Hello again

As must as I hate to spam your forum and wasting your time, is there any solution /answer to my problem?

Thanks once again
Alex

You should extend yourself the algotithm that I posted above to include as many loops as necessary for your logic, but you should be able to expend it easily if you understand well each single line in the code that I posted.

Rene

Hi again!

Indeed, should not be complicated, but still cannot find why the loop / sample code / I posted above does not work and returns always hcor=0…

B

[quote]I posted above does not work and returns always hcor=0.
[/quote]Did you try the draw command ‘by hand’ outside of the loop (i.e. with 2 ‘random’ branch from the list)? Was there any error or warnings?

Also in for (Int_t i=0;i<nb;i++) { b = (TBranch*)lb1->At(i); for ( Int_t j=i;j<nb;j++) { if (j+1<nb) { c = (TBranch*)lb2->At(j+1);} else {c = (TBranch*)lb2->At(j);} why not use more simply: for (Int_t i=0;i<nb;i++) { b = (TBranch*)lb1->At(i); for ( Int_t j=i;j<nb;j++) { c = (TBranch*)lb2->At(j); }

Cheers,
Philippe.

Hi Philippe, thanks for your time

What do you mean ? Can you provide an example of your thought?

the additional lines are for avoiding crashing when reaching end of the nb integer, but in principle , the problem remains no matter what of this will I use…It looks strange, as the code “depends” on the last integer value you give , ie if you do

for (Int_t i=0;i<nb;i++) {
     
     for ( Int_t j=i;j<nb;j++) {
     b = (TBranch*)lb1->At(i+j);
     c = (TBranch*)lb2->At(j); 
}

then it works for the i+j Branch (but never for i alone!), but of course it does not loop properly, but the output is the correct GetName and a value for hcor…

Best
Alexis

[quote]What do you mean ? Can you provide an example of your thought? [/quote]humm simply: tree1_ = treeSignal; tree2_ = treeBkg; tree1_->AddFriend(tree2_,"tree2_"); tree1_->Draw(Form("%s:tree2_.%s>>hcor",some_name,some_other_name,"","goff"); TH2 *hcor = (TH2*)gDirectory->Get("hcor");

[quote]the additional lines are for avoiding crashing when reaching end of the nb integer[/quote]Humm … I assumed that you have the exact same number of branch in both TTree … and if you do, the loop as I provided can not go pass nb … by definition!

Cheers,
Philippe.

Yes, exactly, the two trees have exactly the same number of branches…so, what is the cure??

I am not sure!. A priori the loop I gave you should not lead to any “crashing when reaching end of the nb integer” (and from your description it is not clear why it would for you and even if it does). Also I do not know yet if on your files, running tree1_ = treeSignal; tree2_ = treeBkg; tree1_->AddFriend(tree2_,"tree2_"); tree1_->Draw(Form("%s:tree2_.%s>>hcor",some_name,some_other_name,"","goff"); TH2 *hcor = (TH2*)gDirectory->Get("hcor");works and if it does not how does it fail (error message, etc.) …

Philippe.

Hi Philippe.

To make it more clear , the idea is, that as the 2 trees have the same branches, there is reason to start to correlate the ith event from the 1rst tree with the ith from the 2nd tree(the correlation should be 1), so, I loop the ith with the ith+1 , then the ith+2 …etc. but, now, if you always do

for (Int_t i=0;i<nb;i++) { b = (TBranch*)lb1->At(i); for ( Int_t j=i;j<nb;j++) { c = (TBranch*)lb2->At(j); }

then if you take the integer nb+1 it will crash…so, in order to avoid that, I do this

for (Int_t i=0;i<nb;i++) { b = (TBranch*)lb1->At(i); for ( Int_t j=i;j<nb;j++) { if (j+1<nb) { c = (TBranch*)lb2->At(j+1);} else {c = (TBranch*)lb2->At(j);}

which let’s say take the i+1, i+2… except if it is i=nb and so j=nb…

But, apart from this, (which is just matter of selection and it is not related to c++ /root itself) if I do as you say

for (Int_t i=0;i<nb;i++) { b = (TBranch*)lb1->At(i); for ( Int_t j=i;j<nb;j++) { c = (TBranch*)lb2->At(j); }

then

I get always zero for the correlation – So, how can I loop inside the loop and take the hcor???

Cheers
Alexis

[quote]then if you take the integer nb+1 it will crash[/quote]I don’t understand why that comes into play … the for loops insure that you have both i<nb and j<nb …
humm … maybe your earlier description had a typo:[quote]1rst from ttree1_ with (1,2,3,4…all rest of ttree2_)
2nd from ttre1_ with(2,3,4,… all rest of ttree2_) [/quote] and instead of this (for which my loop seems perfect to me), you meant:[quote]1rst from ttree1_ with ( 2,3,4…all rest of ttree2_)
2nd from ttre1_ with( 3,4,… all rest of ttree2_) [/quote]in which case the right loop would be:for (Int_t i=0;i<nb;i++) { b = (TBranch*)lb1->At(i); for ( Int_t j=i+1;j<nb;j++) { c = (TBranch*)lb2->At(j); }

[quote]I get always zero for the correlation – So, how can I loop inside the loop and take the hcor???[/quote]I still don’t know what is the result of creating hcorr out of the loop: tree1_ = treeSignal; tree2_ = treeBkg; tree1_->AddFriend(tree2_,"tree2_"); tree1_->Draw(Form("%s:tree2_.%s>>hcor",some_name,some_other_name,"","goff"); TH2 *hcor = (TH2*)gDirectory->Get("hcor");

Philippe.

Hi Philippe

Indeed, it was a typo of mine–sorry for that, but in principle the 2nd looping should be “controllable” ie j<nb should be enough as well :wink:

I tried to do what you proposed, ie work with somename etc… So, this what I thought, based on your help – I use a sprintf to pass the GetName of the Branch, like the next script (it also works if I pass a certain branchName, “MET” for example)

  tree1_ = treeSignal;
  tree2_ = treeBkg;
  //tree1_->AddFriend(tree2_,"tree2_");
  TObjArray *lb1 = tree1_->GetListOfBranches();
  TObjArray *lb2 = tree2_->GetListOfBranches();
 
   Int_t nb = lb1->GetEntries();
   
  for (Int_t i=0;i<10;i++) {

    TBranch *b = (TBranch*)lb1->At(i);

     for ( Int_t j=0;j<10;j++) {
    
      TBranch *c = (TBranch*)lb2->At(j);

        char name[20];char name2[20];
      
        sprintf(name,"%s",b->GetName());   //could also work if  "MET"
        sprintf(name2,"%s",c->GetName());

        tree1_->Draw(Form("%s:%s>>hcor",name,name2,"","goff")); 
       TH2 *hcor = (TH2*)gDirectory->Get("hcor");
     }}

So, the difference here is that I do not use AddFriend method, and it works ie returns non-zero values . Now, I guess, if I would do


tree1_ = treeSignal;
  tree2_ = treeBkg;
  tree1_->AddFriend(tree2_,"tree2_");
  TObjArray *lb1 = tree1_->GetListOfBranches();
  TObjArray *lb2 = treeBkg->GetListOfBranches();
  Int_t nb = lb1->GetEntries();
   
  for (Int_t i=0;i<10;i++) {

    TBranch *b = (TBranch*)lb1->At(i);

     for ( Int_t j=0;j<10;j++) {
    
      TBranch *c = (TBranch*)lb2->At(j);

        char name[20];char name2[20];
      
        sprintf(name,"%s",b->GetName());  
        sprintf(name2,"%s",c->GetName());

        tree1_->Draw(Form("%s:tree2_.%s>>hcor",name,name2,"","goff")); 
       TH2 *hcor = (TH2*)gDirectory->Get("hcor");
     }}

would in principle be the same , with the first script no? I mean, what if I do not use the AddFriend method, and just assing 2 TObjects to the ttree1_ and ttree2_? Is there any great difference I should worry about?

Also, what really amazed me, is that if the nb integer is greater than one specific value (like 15 for example,but this value depends on the total number of entries I run, but in any case is really less than the real nb value), I get always zeros (no crash or warnings) --this is why actually I got all these zeros before --if nb > some value, the hcor->zero … but not crash/warnings etc …Any ideas why?

Best
Alexis

Hi Alexis,

Rather than sprintf and Form, you ought to use TString::Format:tree1_->Draw(Format("%s:%s>>hcor",b->GetName(),c->GetName(),"","goff"));with sprintf your code will fail if one of the branch name is more than 19 characters.

[quote] I mean, what if I do not use the AddFriend method, and just assing 2 TObjects to the ttree1_ and ttree2_? Is there any great difference I should worry about? [/quote]Then TTree::Draw will be unable to correlate the 2 trees …

[quote]I get always zeros (no crash or warnings) [/quote]Where do you get zeros?

[quote]but not crash/warnings etc …Any ideas why? [/quote]No idea. You could try to see if there is any memory overwrite by using valgrind (see valgrind.org)

Cheers,
Philippe.