Accessing branches of a tree friend in a loop

Hi everybody,

here it is my problem right now.
I have a starting TChain, let’s call it T1. It contains many branches with various quantities related to an event. With the data stored there I calculate new variables for each event which I save then in a new Tree. The idea is to declare this new tree (let’s call it TF) as a friend of the initial chain. Then to select a restricted subsample of events which satisfies a certain selection running on both the old variables in T1 and the new in TF.
I want to do this two times with two different selections (at the hadron and the detector level of my MC sample,namely) and then compare the two subsamples event per event, in order to see if the same event passed both the selections and in order to compare a variable V1 in the first selection with another variable V2 (similar to V1) which passed the second selection.
I don’t want / cannot use the method Draw because the best way that I found for doing it was to keep in memory the list of the quantites in arrays and then to loop on the arrays and to compare them.

(...)

//HADRON LEVEL
  TH1F *htetagpdij = new TH1F("hadr_etagpdijet","hadr_etagpdijet",nbinseta1gp,eta1gpbin);
 
  fchain->SetEventList(hadlist);//hadlist is a TEventList generated previously
                                              //with the selection needed at the had level
const Int_t hadsel=hadlist->GetN(); //events selected at had level, many 10k
Double_t hmatr[5][hadsel];
  fchain->Draw("etajet_gphad[0]:etajet_gphad[1]","","goff");
  for(i=0;i<hadsel>GetV1()[i];
    hmatr[1][i]=fchain->GetV2()[i];
  }
  htetagpdij->FillN(hadsel-1,hmatr[0],0);
  htetagpdij->FillN(hadsel-1,hmatr[1],0);

//DET LEVEL
  TH1F *dtetagpdij = new TH1F("det_etagpdijet","det_etagpdijet",nbinseta1gp,eta1gpbin);
  fchain->SetEventList(0);
  fchain->SetEventList(detlist);//detlist is a TEventList generated previously
                                              //with the selection needed at the det level
 const Int_t detsel=detlist->GetN(); //selected events, many 10K
 Double_t dmatr[5][detsel];
   fchain->Draw("diffr.etajet_gp_corr[0]:diffr.etajet_gp_corr[1]","","goff");
  for(i=0;i<detsel>GetV1()[i];
    dmatr[1][i]=fchain->GetV2()[i];
  }
  dtetagpdij->FillN(detsel-1,dmatr[0],0);
  dtetagpdij->FillN(detsel-1,dmatr[1],0);

//Now fill a histo with events which are in the same bin both at hadr and det level

 TH1F *btetagpdij = new TH1F("both_etagpdijet","both_etagpdijet",nbinseta1gp,eta1gpbin);
  for(i=0;i<hadentries>GetEntry(i);
    detent = detlist->GetIndex(hadent); //detent is the index on the det list

    if(detent != -1){ //If hadent is not in detlist GetIndex will give you back -1

      /*
	Arrays element are ordered in the same way of entries in the respective 
	lists. So we can use the indexes defined above to select just the arrays elements
	which satisfy the previous filter 
	(->the event must be selected both at had and det level) 
      */
       if(htetagpdij->FindBin(hmatr[0][i]) == dtetagpdij->FindBin(dmatr[0][detent])){
	btetagpdij->Fill(hmatr[0][i]);
      }
      if(htetagpdij->FindBin(hmatr[1][i]) == dtetagpdij->FindBin(dmatr[1][detent])){
	btetagpdij->Fill(hmatr[1][i]);
      }

}

If I try to run this code, it crashes even before starting the DET level part, I think because
the arrays are huge and the memory runs out.
The point is that until I need only one variable it can still do it but here (because of the definition of the quantity that I want to fill in the histos) I need to keep many arrays at the same time (up to 5 arrays exactly).

Another possibility would be to loop on all the entries in the chain one by one, it would be much less memeory consuming I guess. But the problem that I faced today is that I don’t know exactly how to access the variables in the friend tree in the loop


void DiffrAn::CFactLoop(char *hfkname){

  TFile *hf = new TFile(hfkname,"UPDATE"); 
  ActivateBranches();
  AddressBranches();

(...some other declarations...)
  for(i=0;i<totent>Get(fmyname);
    fchain->AddFriend(fdiff,"diffr");

and in the methods ActivateBranches and AddressBranches i try to do things like


  fchain->SetBranchStatus("diffr.W2_da",1);
  fchain->SetBranchStatus("diffr.Mx2_zufo",1);
  fchain->SetBranchStatus("diffr.Log10X_pom",1);

(...)

  fchain->SetBranchAddress("diffr.W2_da",&w2_da);
  fchain->SetBranchAddress("diffr.Mx2_zufo",&mx2zufo);
  fchain->SetBranchAddress("diffr.Log10X_pom",&log10xpom);

It doesn’t like them, it says that

Error in : unknown branch -> diffr.W2_da
Error in : unknown branch -> diffr.Mx2_zufo
Error in : unknown branch -> diffr.Log10X_pom

How can I access in the loop at the variables in the friend tree? I looked on the web page and in the forum but I didn’t find anything (maybe I searched in the wrong way…).
Of course if you have suggestions for solving the problem accessing the cahin with the Draw method you are welcome :wink:

Thanks very much for the time given to me in reading the post and for any help that you can give.

Alessio

PS: I am using a pretty old version of root, the 4.00/08.

Ooops, ok, maybe I found the right example in the tutorials…
I am trying it and then I will tell you if the try was succesfull.

Cheers
Alessio

Hi to everybody,

I followed the example proposed in root.cern.ch/root/html/examples/ … end.C.html
in order to access my ntuples in the way described in the post above.
I found only a problem
In my code I have a method ActivateBranches and another one AddressBranches.
The two of them don’t do anything else than calling other methods which activate (address) branches separately for the chain and the friend tree. The ActivateFriendBranches method for example is nothing else than:


void DiffrAn::ActivateBranches(){
  ActivateChainBranches();
  ActivateFriendBranches();
}

void DiffrAn::ActivateFriendBranches(){
  fdiff->SetBranchStatus("*",0);

  fdiff->SetBranchStatus("MC_flag",1);
  fdiff->SetBranchStatus("W2_da",1);
  fdiff->SetBranchStatus("Mx2_zufo",1);
  fdiff->SetBranchStatus("Log10X_pom",1);
(...all the branches that I need)
}

and ActivateChainBranches() is similar to the one shown but works on the chain fchain rather than the friend tree fdiff.
I call them before starting the loop, first I activate the branches and then I address them.
Then I declare the tree fdiff as friend of fchain

Int_t DiffrAn::AddMyFriend(){

(..retrieve the friend tree named fdiff...)

    ActivateBranches();
    AddressBranches();
    fchain->AddFriend(fdiff,"diffr");

(...)

and then I start looping on the entries.

void DiffrAn::CFactLoop(char *hfkname){

  AddMyFriend();
(...declare the histos)

  ///////////////
  //MAIN LOOP (Cfactors)
  for(i=0;i<totent>GetEntry(i);
(...apply selections and fill histos)
}//end loop

But as soon as I invoke fchain->GetEntry(i)
the branches in the friend tree are all deactivated. The code can read the values stored in the branches only if at every step of the loop I repeat the activation of the branches.
I think that this slows a lot my code, how can I solve the problem?

Thanks
Alessio

Hi,

Please note that a lot the code you pasted in your post has been mangled by the Forum HTML parser. To correct the situation, you must either click on ‘Disable HTML in this post’ or do the same in your profile or upload your code as attachement.

Cheers,
Philippe

Hi,

Your original error is a bug in the SetBranchStatus that will be correct shortly.

To work around the problem you should move from using SetBranchStatus and calling tree->GetEntry to explicitly calling GetEntry on the branch you want.

In the lastest version of ROOT, you can use[code]
TBranch *br_w2_da;
TBranch *br_mx2zufo;
TBranch *br_log10xpom;

fchain->SetBranchAddress(“diffr.W2_da”,&w2_da,br_w2_da);
fchain->SetBranchAddress(“diffr.Mx2_zufo”,&mx2zufo,br_mx2zufo);
fchain->SetBranchAddress(“diffr.Log10X_pom”,&log10xpom,br_log10xpom);


localEntry = chain->LoadEntry(chainEntry);
br_w2_da->GetEntry(localEntry);
br_mx2zufo->GetEntry(localEntry);
br_log10xpom->GetEntry(localEntry);[/code]

Cheers,
Philippe

Your original problem is now fixed in the CVS repository.

Cheers,
Philippe