tree.GetEntry(x) triggers a Traceback in PyRoot

Hello, when I was a summer student I wrote a C++ code using ROOT that is still used in my university.

Now I want to “translate” this code to Python, I have solved several problems but this one has proven the hardest.

The code is supposed to go through the entries of a tree and get jet, met and lepton data to analyze.

In each iteration of the for-loop I used tree->GetEntry(ientry); to automatically fill several TClonesArrays, and this works with C++.

I thought I could translate this command as tree.GetEntry(ientry) since I have tested that this works for all the other ROOT methods, but the terminal gives me this message:

Traceback (most recent call last):
File “aprendiendo.py”, line 163, in
tree.GetEntry(ientry)
SystemError: int TTree::GetEntry(Long64_t entry = 0, int getall = 0) =>
problem in C++; program state has been reset

I have been toying around with it but all the other ways I can come up to fill the TClonesArrays in each iteration are too complex, so I want to find a way to make this method work, or something very similar to it.

Here are the important sections of both of my codes.
Thanks

C++ code that works

#include "Analysis_Libraries.hh"
#include "nero_07.hh"

#define minintu nero_07

minintu *d;   

int main(int argc, char* argv[])
{ 

  TFile* file = TFile::Open("/Users/Fer/Documents/traajo/samples/NeroNtuples_9.root");

  TTree *tree=(TTree*)file->Get("nero/events");

  int nentries = tree->GetEntries();

  TClonesArray *leptondata = new TClonesArray::TClonesArray ( "TLorentzVector", nentries);

  tree->SetBranchAddress("lepP4", &leptondata);

  TClonesArray *metdata = new TClonesArray::TClonesArray ( "TLorentzVector", nentries);

  tree->SetBranchAddress("metP4", &metdata);

  TClonesArray *jetdata = new TClonesArray::TClonesArray ( "TLorentzVector", nentries);

  tree->SetBranchAddress("jetP4", &jetdata);


  for(int ientry = 0; ientry < nentries-1; ientry++) 
  {
    //Reset the data
    leptondata->Clear();
    metdata->Clear();
    jetdata->Clear();

    //This line stores the proper data in the TClonesArrays
    tree->GetEntry(ientry);

        //Store all the data of the electron in this lorentz vector
        TLorentzVector * lorentz_leptondata = (TLorentzVector *)leptondata->At(i);

        //Get the transverse momentum of that lorentz vector
        mass=lorentz_leptondata.Pt();

    TLorentzVector * lorentz_metdata = (TLorentzVector *) metdata->At(0);

    //Get the invariant transverse energy of that lorentz vector
    mass=mass + lorentz_metdata.Et();

        TLorentzVector * lorentz_jetdata = (TLorentzVector *)jetdata->At(i);

        //Get the transverse energy of that lorentz vector
        mass=mass+orentz_jetdata.Et();

  }//This closes the main for loop


  // cleanup
  delete file; // automatically deletes "tree" too
  delete lepPdgId;
  delete leptondata;
  delete metdata;
  delete jetdata;
  return 0; 
}

PyRoot code that will eventually work

# -*- coding: cp1252 -*-
import sys
import ROOT
from ROOT import TLatex,TPad,TList,TH1,TH1F,TH2F,TH1D,TH2D,TFile,TTree,TCanvas,TLegend,SetOwnership,gDirectory,TObject,gStyle,gROOT,TLorentzVector,TGraph,TMultiGraph,TColor,TAttMarker,TLine,TDatime,TGaxis,TF1,THStack,TAxis,TStyle,TPaveText,TAttFill,TCutG

import numpy as np
ROOT.gROOT.SetBatch()

file = TFile("/Users/Fer/Documents/traajo/samples/NeroNtuples_9.root")

tree=file.Get("nero/events")

nentries = tree.GetEntries()

leptondata = TClonesArray( "TLorentzVector", nentries)

tree.SetBranchAddress("lepP4", leptondata)

metdata = TClonesArray("TLorentzVector", nentries)

tree.SetBranchAddress("metP4", metdata)

jetdata = TClonesArray("TLorentzVector", nentries)

tree.SetBranchAddress("jetP4", jetdata)

for ientry in xrange(0,nentries-1):

  #Reset the data
  leptondata=TClonesArray( "TLorentzVector", nentries)
  metdata=TClonesArray( "TLorentzVector", nentries)
  jetdata=TClonesArray( "TLorentzVector", nentries)

  #This line stores the proper data in the TClonesArrays
  tree->GetEntry(ientry);

  #Store all the data of the electron in this lorentz vector
  lorentz_leptondata = leptondata.At(i)

  #Get the transverse momentum of that lorentz vector
  mass=lorentz_leptondata.Pt()

  lorentz_metdata = metdata.At(0)

  #Get the invariant transverse energy of that lorentz vector
  mass=mass + lorentz_metdata.Et()

  lorentz_jetdata = jetdata.At(i)

  #Get the transverse energy of that lorentz vector
  mass=mass+orentz_jetdata.Et();


#cleanup
del file
del leptondata
del metdata
del jetdata

In C++:

    //Reset the data
    leptondata->Clear();
    metdata->Clear();
    jetdata->Clear();

yet in Python:

  #Reset the data
  leptondata=TClonesArray( "TLorentzVector", nentries)
  metdata=TClonesArray( "TLorentzVector", nentries)
  jetdata=TClonesArray( "TLorentzVector", nentries)

and you’re surprised that the behavior differs, why?

To be specific, that “problem in C++; program state has been reset” means you got a segfault on the C++ side. The reason is that by overwriting the XYZdata references, the old values are garbage collected even as you had passed pointers to them to C++. Then the GetEntry touches that deleted memory.

Just call Clear() on the clones arrays in Python like you do in C++ …

Thanks, to be honest I don’t know much python.

I used

	leptondata.Clear()
	metdata.Clear()
	jetdata.Clear()

but I got the same problem, then I checked the documentation for the clones arrays and found void TClonesArray::Clear ( Option_t * option = "" ).
So decided to use

	leptondata.Clear( option = "C")	
	metdata.Clear(option = "C")	
	jetdata.Clear(option = "C")

but I get “keyword arguments are not yet supported”, currently readding what does that mean

I have no idea what option “C” does for Clear() and I don’t see why it’s needed if the default as used in C++ is the empty string, but if you want to call with “C”, the syntax is:

leptondata.Clear("C")
# etc.

By setting ‘option = “C”’ you are not passing a positional function argument, but a keyword dictionary. The latter are not supported in PyROOT (but are in general Python).

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