Root crashing when drawing from many trees

Hello,

I am experiencing the following error when looping
over a set of trees and drawing a variable:

i=48 expression> WlPt >> hist_bg_48
Error: Symbol G__exception is not defined in current scope overlay_scaled_zadnji.C:99:
Error: type G__exception not defined FILE:/users/vuko/phan/tgc/modelId/CMSSW_1_6_7/src/Vuko/WZAnalysis/test/./overlay_scaled_zadnji.C LINE:99
*** Interpreter error recovered ***

The critical part of the code is the following loop, and
the crash happens in the Tree->Draw(…) line:

TH1F * bghistos[200];
TString variable = “WlPt”;
for (int i=0; i<nfiles; i++) {
TString key = “hist_bg_”;
key += i;
bghistos[i] = new TH1F(key,“Background”,nbins,xmin,xmax);
TString expression_b = variable + " >> hist_bg_"; // + i;
expression_b += i;
trees[i]->Draw(expression_b); // <===== IT CRASHES HERE
}

It must be memory related because it does not happen immediately
but only after the n-th tree (where n seems to depend on the machine
where I am running, i.e. on its RAM?). I have indeed used this script
for long time with a smaller number of trees and it ran flawlessly.

I am trying to read O(100) root trees, their summed total size
being somewhat above 300 MB. The bizarre thing is that I see
root memory consumption (VIRT column in top command)
go above 1.5 GB.

I am using root version 5.14/00f
(the one coming with the CMS software version CMSSW_1_6_7)

For reference I append the full script: what it does

  • read a list of root trees from an ascii files and open each
    one of them and stores a pointer to a tree in each tree
  • loop over all trees and draw one variable

If it is helpful, I can copy all the root files to some
location.

If am guilty for the memory leak, I really can’t see it.
Am I doing something wrong?

Most grateful for any help!
Vuko

The full script:

#include “fstream.h”
#include “iomanip.h”
#include <strstream.h>
#include

///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////

void overlay_scaled_zadnji(const TString inputFile, int useCuts=1,TString add_cut="")
//(const TString &file1,const TString &file2)
// useCuts
// 0: do not apply final analysis cuts (allcuts below)
// 1: apply final analysis cuts (allcuts below)
{

// INPUT: read list of root trees from inputFile and open them all

ifstream  input(inputFile);

const int linesize=1024;
char inbuf[linesize];

const int max_files = 200;

TFile * files[max_files];
TTree * trees[max_files];
TString keys[max_files];
Float_t x_sections[max_files];

int nfiles=0;

while (input.getline(inbuf,linesize)) {

  if (inbuf[0] == '#') { // skip comment line
continue;
  }
  
  istrstream istline(inbuf);
  
  TString filename,name;
  float x_section;
  int group;
  
  istline >> filename
      >> name
      >> x_section
      >> group;
  
  cout << "reading file   : " << nfiles << " : "  << filename << endl;

  TFile *f;
  f = new TFile(filename);
  
  //	f->cd("T1");
  
  TTree *wz_t=WZTree;
  
  trees[nfiles] = wz_t;
  
  keys[nfiles] = name;
  x_sections[nfiles] = x_section*1000;  // N = x_section (pb) * luminosity (pb-1)

  cout << "x_section : " << x_section
   << "\t stored: " << x_sections[nfiles] << endl;
  
  files[nfiles] = f;
  cout<<" nfile="<< nfiles << endl;
  nfiles++;
  
}

cout <<“entering overlayshapes” << endl;
TH1F * bghistos[200]; // didn’t manage to allocate size dynamically, this should be enough

for (int i=0; i<nfiles; i++) {
bghistos[i] = 0;
}

int nbins = 50;
float xmin = -10.;
float xmax = 200.;

TString variable = “WlPt”;
for (int i=0; i<nfiles; i++) {
TString key = “hist_bg_”;
key += i;
bghistos[i] = new TH1F(key,“Background”,nbins,xmin,xmax);
TString expression_b = variable + " >> hist_bg_"; // + i;
expression_b += i;
cout <<“i=”<< i << " expression> " << expression_b << endl;
trees[i]->Draw(expression_b);
cout <<“after drawing \n”;
}

for (int i=0; i<nfiles; i++) {

bghistos[i]->Draw();

}

}

What you do is not good at all! You are opening 200 files , including the tree from each file.
You need to open only one file at the time. I strongly suggest you consider using a TChain instead, othrwise you will run out of memory very quickly.
Anyhow, there is an implicit big problem with your line

TTree *wz_t=WZTree;
I assume that WZTree is the name of youtr Tree in the file. You should change this statement to:

TTree *wz_t= (TTree*)f->Get("WZTree");
Rene

Hi Rene,
Thanks for your reply! I modified the code so as to
have only one open file at a time:

  for (int i=0; i<nfiles; i++) {
   (...)
    files[i] = new TFile(fileNames[i]);
    TTree *  tree= (TTree*) files[i]->Get("WZTree");
    tree->Draw(expression_b);
    files[i]->Close();
  }

and this works :slight_smile:

You’re suggesting to use TChain and I was thinking about
it but there is something I am not sure about: my files contains
more than one tree. The TChain examples I saw seem to
assume there is only one tree per file. In my case, how would
chain->Draw(…) know from which tree it should draw?

Thanks,
Vuko

Vuko,

In the TChain constructor, you specify the name of the tree to be processed.

Rene