Something strange for TTreeformula working with TChain


_ROOT Version: Binary distribution ROOT 6.12/06
_Platform: MacOS


I try to make TTreeformula work with TChain, and from https://root-forum.cern.ch/t/ttreeformula-and-tchain/15155 I got the information that this feature has already been implanted in root from v6.10. But I still don’t know how to make it work correctly.

Here is my codes for test:

void formula_test(){
   TChain* chain = new TChain("tree");

   chain->Add("tuple2.root");
   chain->Add("tuple1.root");
   //chain->Add("tuple_all.root/tree");        
   int nentries = chain->GetEntries();
   //int nentries = 1500;

   cout << "total entries: " << nentries <<endl;

   TTreeFormula* formula = new TTreeFormula("test", "random", chain);
   chain->SetNotify(formula);

   for(int jentry=0; jentry<nentries; jentry++){
       chain->LoadTree(jentry);
       chain->GetEntry(jentry);
       float value = formula->EvalInstance(0);
       //float value = formula->EvalInstance();
       if(jentry%100==0)
            cout << jentry << ": "<< value << endl;
  }
}

where I add two trees to a chain, and want to use TTreeformula to get value of specific branch in every entry.
If I don’t add “chain->SetNotify(formula);” after the definition of formula , the scripts will collapse at:
a). The first time to process “formula->EvalInstance(0)” , if using “int nentries = chain->GetEntries()”;
b). The first entry of the second tree to process “formula->EvalInstance(0)”, if not using “int nentries = chain->GetEntries()”.

Then, I add “chain->SetNotify(formula)”, no error occur, but I find the value gotten from the first tree is 0, which is definitely wrong.

By the way, I also tried the TTreeFormulaGroup method mentioned in https://root-forum.cern.ch/t/ttreeformula-and-tchain/15155, but the value from the first tree is 0, too!
Did I do something wrong? Or what can I do to make TTreeformula works well with TChain?

SetNotify is (still) required for that use case. Try the following tweak

void formula_test(){
   TChain* chain = new TChain("tree");

   chain->Add("tuple2.root");
   chain->Add("tuple1.root");
   //chain->Add("tuple_all.root/tree");        
   int nentries = chain->GetEntries(); // This should not be needed.
   //int nentries = 1500;

   cout << "total entries: " << nentries <<endl;

   chain->LoadTree(0);
   TTreeFormula* formula = new TTreeFormula("test", "random", chain);
   chain->SetNotify(formula);

   for(int jentry=0; jentry<nentries; jentry++){
// the following for statement should be sufficient
//  for(Long64_t jentry=0; jentry< chain->GetEntriesFast(); ++jentry){
       chain->LoadTree(jentry);
       chain->GetEntry(jentry); // This should not be needed.
       float value = formula->EvalInstance(0);
       //float value = formula->EvalInstance();
       if(jentry%100==0)
            cout << jentry << ": "<< value << endl;
  }
}

Sorry, I tried your codes, but strange thing still happened. In my tuples, tuple2 contains 1000 entry and tuple1 contains 500.
First, I tried

for(int jentry=0; jentry<nentries; jentry++)

and the print is like:

root [0] 
Processing formula_test.C...
0: 0
100: 0
200: 0
300: 0
400: 0
500: 0
600: 0
700: 0
800: 0
900: 0
1000: 0.998933
1100: 1.11332
1200: -0.656914
1300: 0.311403
1400: 0.921704

Then I tried:

for(Long64_t jentry=0; jentry< chain->GetEntriesFast(); ++jentry){

The print is like:

0: 0.652062
100: 0.0408537
200: 0.694784
300: 0.440973
400: 0.2719
500: 0.243604
600: 0.965867
700: 0.10182
800: 0.988573
900: 0.776108
1000: 0
1100: 0
1200: 0
1300: 0
1400: 0

the 0 in both the situations is wrong!
Because I also tried to only add “tuple_all.root” in the chain, which is generated from:

hadd tuple_all.root tuple2.root tuple1.root

the result seems quite normal:

0: 0.652062
100: 0.0408537
200: 0.694784
300: 0.440973
400: 0.2719
500: 0.243604
600: 0.965867
700: 0.10182
800: 0.988573
900: 0.776108
1000: 0.998933
1100: 1.11332
1200: -0.656914
1300: 0.311403
1400: 0.921704

Can you provide a standalone reproducer so we can look into this further?

OK, sorry for the misleading question I raised above. I missed " chain->LoadTree(0);" before “chain->SetNotify(formula)” when testing " for(int jentry=0; jentry<nentries; jentry++){", really sorry about that.

However, things are still not going on well. OK, this time I put everything I have done here.
First, I generate two tuples with:

from ROOT import *
from array import array
def GenerateTree():
    nentries1 = 500
    nentries2 = 1000

    f1 = TFile("tuple1.root","recreate")
    t1 = TTree("tree","tree")

    a1 = array("f",[0])
    t1.Branch("random",a1,"a1/F")

    for jentry in xrange(nentries1):
        a1[0] = gRandom.Gaus()
        t1.Fill()

    print "event1:",  t1.GetEntries()
    t1.Write()
    f1.Close()

    f2 = TFile("tuple2.root","recreate")
    t2 = TTree("tree","tree")

    a2 = array("f",[0])
    t2.Branch("random",a2,"a2/F")

    for jentry in xrange(nentries2):
        a2[0] = gRandom.Uniform()
        t2.Fill()
    print "event2:",  t2.GetEntries()

    t2.Write()
    f2.Close()

GenerateTree()

And then I just copy your codes:

void formula_test(){
   TChain* chain = new TChain("tree");

   chain->Add("tuple2.root");
   chain->Add("tuple1.root");
   //chain->Add("tuple_all.root/tree");        
   int nentries = chain->GetEntries(); // This should not be needed.
   //int nentries = 1500;

   cout << "total entries: " << nentries <<endl;

   chain->LoadTree(0);
   TTreeFormula* formula = new TTreeFormula("test", "random", chain);
   chain->SetNotify(formula);

   for(int jentry=0; jentry<nentries; jentry++){
// the following for statement should be sufficient
//  for(Long64_t jentry=0; jentry< chain->GetEntriesFast(); ++jentry){
       chain->LoadTree(jentry);
       chain->GetEntry(jentry); // This should not be needed.
       float value = formula->EvalInstance(0);
       //float value = formula->EvalInstance();
       if(jentry%100==0)
            cout << jentry << ": "<< value << endl;
  }
}

And the print is:

root [0] 
Processing formula_test.C...
total entries: 1500
0: 0.652062
100: 0.0408537
200: 0.694784
300: 0.440973
400: 0.2719
500: 0.243604
600: 0.965867
700: 0.10182
800: 0.988573
900: 0.776108
1000: 0
1100: 0
1200: 0
1300: 0
1400: 0

where the "0"s are strange. It seems formula didn’t work for the second tree.
I also did crosscheck by using “tuple_all.root” as input, which is from:

hadd tuple_all.root tuple1.root tuple2.root

The result seems fine.

Thank you indeed!!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.