I can't redo CloneTree on the Tree made using CloneTree(0)

Hello,
I have a TTree in file A.root. I want to select some of the events, and store them in a new file.

To do that, first I make a new TTree, using initialTree->CloneTree(0).

Then I loop through the events of my initialTree, and if an event passes my filter then I write it to the new TTree (using newTree->Fill()). When the loop is over, the newTree is stored in file B.root (using newTree->Write()).

The problem comes now. I need to filter again the events in B.root, this time with different selection criteria, and store any events that pass into C.root.

To do that, I try to do the same that I did to go from A.root to B.root. Namely, I give as input the file B.root, and I expect the output to go into C.root.
But, this time, ROOT crashes at the command initialTree->CloneTree(0).

So, it seems that I can use CloneTree(0) the first time (on A.root), I write out into B.root a healthy TTree, but then I can’t use CloneTree(0) on that produced TTree.

Is there any way around that problem, please?

Below is my code snippet, and the information I get using gdb.

Thank you.
Georgios

void gammaJetAnalysis::FilterOutEvents(string outputFilename)  {
  //produce a new TTree, based on the fChain here, and fill it with a subset of events.
  if (fChain == 0) return;
  
  Long64_t nentries = fChain->GetEntriesFast();
  cout << "DEBUG " << nentries << endl << flush;
  
  TFile fout(outputFilename.c_str(),"recreate");
  TTree* newTree;
  cout << "DEBUG we made newTree" << endl << flush;

  newTree = fChain->CloneTree(0);
  cout << "DEBUG we cloned fChain" << endl << flush;
  for (Long64_t e=0; e<nentries; e++) { 
    Long64_t ientry = LoadTree(e); 
    if (ientry < 0) break;
    fChain->GetEntry(e);
    cout << "DEBUG will check event " << e << endl << flush;
    if(!PassesEventFilter()) continue;
    newTree->Fill();
  }
  fout.cd();
  newTree->Write();
  fout.Close();
  return;
}

And the gdb output:

Hi,

(What does valgrind say in your case?).

It seems that the problem would be located in the handling of the 2nd TTree in between the 2 calls to FilterOutEvents. i.e. the code snippets looks fine and I do not know any reason why what you tried would not work.

Cheers,
Philippe.

Hi Philippe,

Here is the output of runnign

valgrind root -l -q -b filterEvents.C

I hadn’t used valgrind before, so I may not be using it right. Let me know please if there is anything else to try.

Thanks a lot,
Georgios

Hi,

Try:valgrind root.exe -l -q -b filterEvents.C(note the extra .exe which is required for valgrind to give useful information).

Cheers,
Philippe

Oh, I see, Philippe.
I did as you said, and here is the output (kind of long)

Thank you,
Georgios

Hi,

Ok. It seems the issue is in the life of the TBranch objects … well maybe.

Would be able to send me a complete version of the code? In particular to see the liftetime of the TFile and TTree.

Cheers,
Philippe

Hi Philippe,

Here is the macro filterEvents.C :

/*
example:
export inputNtuple='GJ1'
export outputNtuple='GJ1_filtered'
root -l -q -b filterEvents.C
*/

void filterEvents() {

  cout << "STARTING" << endl;
  gROOT->Reset();
  gSystem->Load("gammaJetAnalysis_C.so"); //load analysis class

  TChain * chain = new TChain("CollectionTree","");
  if (gSystem->Getenv("inputNtuple")==NULL) {
    cout << "ERROR: Must specify inputNtuple" << endl;
    return 1;
  }
  string inputNtuple=gSystem->Getenv("inputNtuple");
  cout << "inputNtuple=" << inputNtuple << endl;
  
  chain->Add(inputNtuple.c_str());
  gammaJetAnalysis* ana = new gammaJetAnalysis(chain);

  ana->Loop(4);
  cout << "Total Events: " << ana->fChain->GetEntriesFast() << endl;

  cout << "Filtering" << endl;
  if (gSystem->Getenv("outputNtuple")==NULL) {
    cout << "ERROR: Must specify outputNtuple" << endl;
    return 1;
  }
  string outputFile = gSystem->Getenv("outputNtuple");
  cout << "outputFile=" << outputFile << endl;

  //Filter events from input file into output file
  ana->FilterOutEvents(outputFile);

  cout << "DEMONSTRATE" << endl;

  TChain * chainNew = new TChain("CollectionTree","");
  chainNew->Add((outputFile).c_str());
  ana->Init(chainNew);
  
  ana->Loop(4);
  cout << "Total Events: " << ana->fChain->GetEntriesFast() << endl;
  
  cout << "ENDING" << endl;

  return;
}

I am attaching also the .h and .C files that I compile into gammaJetAnalysis_C.so.

Many thanks,
Georgios
gammaJetAnalysis.C (46.1 KB)
gammaJetAnalysis.h (20.5 KB)

Hi,

Unfortunately I still can’t spot anything obvious :frowning:. So I think what I need is your data file to try to reproduce the problem.

Cheers,
Philippe.

Hi Philippe,

I’ll try to post here an ntuple.

I had to split it into smaller bits, and rename the pieces into “.txt” to fool the forum software.
To retrieve the file, please download the three files attached, and do the obvious:

cat xaa.txt xab.txt xac.txt > B.root

(I hope this will not corrupt the file)

This B.root is the kind of file that I called B.root in my first message. It’s produced after filtering A.root (which is huge and I can’t send).
The code that I sent in my previous post should filter it even smaller, and produce C.root (or whatever you want to call it). But for me it crashes.

Oh, wait, sorry, in order to filter it even smaller, the function PassesEventFilter() may need to be modified a little. I think that in its current form it will just accept all events. An easy way to change that is to go into PassesEventFilter() and replace

  if (RunNumber==108001) {
    if (hardestPt<20 || hardestPt>70) return false;
  }
  else if (RunNumber==108002) {
    if (hardestPt<70 || hardestPt>150) return false;
  }
  else if (RunNumber==108003) {
    if (hardestPt<150 || hardestPt>220) return false;
  }
  else if (RunNumber==108004) {
    if (hardestPt<220) return false;
  }

with this:

  if (RunNumber==105802) {
    if (hardestPt<0 || hardestPt>100) return false;
  }
  else if (RunNumber==105807) {
    if (hardestPt<100 || hardestPt>140) return false;
  }
  else if (RunNumber==105814) {
    if (hardestPt<140) return false;
  }

Thanks a lot for your time,
Georgios
xac.txt (33.8 KB)
xab.txt (977 KB)
xaa.txt (977 KB)

Hi,

I can not reproduce your problem :frowning: (neither with the head of the trunk nor with 5.18). Which version of ROOT are you using.

Also the valgrind report open dlopen seem ‘fishy’. Did you compile the shared library and root with the same compiler version?

Cheers,
Philippe.

Hello P.

I use this root version:

Hm… I wonder if the compiler version would have changed. Ubuntu updates its packages every now and then, and it’s not unlikely that the compiler version changed since when I installed ROOT.

Currently, I have on my system this version of gcc (and c++):

I’m not sure what it was when I installed ROOT, though…

Would you recommend re-compiling ROOT?

Thanks,
Georgios

Hi,

Yes I would recommend it (it is fast after all :slight_smile:).

You can find information on which compiler was used to build root in the file $ROOTSYS/include/compiledata.h

Cheers,
Philippe.

Hello Philippe,

I recompiled, and it still doesn’t work.
I think at this point I’m giving up.

Thank you very much for trying to help me.
Best,
Georgios

P.S. For the record, after re-compilation here is the file $ROOTSYS/include/compiledata.h :

/* This is file is automatically generated */
#define BUILD_ARCH "linuxx8664gcc"
#define BUILD_NODE "Linux myComputer 2.6.24-23-generic #1 SMP Mon Jan 26 01:04:16 UTC 2009 x86_64 GNU/Linux" 
#define COMPILER "-path: not found g++ is /usr/bin/g++" 
#define COMPILERVERS "gcc424"
#define MAKESHAREDLIB  "cd $BuildDir ; g++ -c $Opt -pipe -m64 -Wall -W -Woverloaded-virtual -fPIC -pthread $IncludePath $SourceFiles ;  g++ $ObjectFiles -shared -Wl,-soname,$LibName.so -m64 -O2  $LinkedLibs -o $SharedLib"
#define MAKEEXE "cd $BuildDir ; g++ -c  -pipe -m64 -Wall -W -Woverloaded-virtual -fPIC -pthread $IncludePath $SourceFiles; g++ $ObjectFiles -m64 -O2  -o $ExeName $LinkedLibs -lm -ldl  -pthread -rdynamic"
#define CXXOPT "-O2"
#define CXXDEBUG "-g"
#define ROOTBUILD ""
#define LINKEDLIBS "-L$ROOTSYS/lib -lCore -lCint -lMathCore -lRint "
#define INCLUDEPATH "-I$ROOTSYS/include"
#define OBJEXT "o" 
#define SOEXT "so" 

Hi,

For the record, with Ubuntu 4.3.2-lubuntu12, g++ 4.3.2 and the head of the svn trunk, it works fine (i.e. you could try next to upgrade to a newer version of ROOT and if it still does not work to upgrade to a new version of Ubuntu).

Cheers,
Philippe.