I am trying to read a tree and “copy” to another tree - The problem is, that exactly at GetEntry method, I get a segmentation violation error— Any reason why ?
Thanks
TFile *input_ = TFile::Open ("../test/Delphes.root");
TTree *events;
events = (TTree *) input_->Get ("Analysis");
cout << events->GetEntriesFast () << endl;
fout_ = new TFile ("TopTreeRecoDelphes.root", "RECREATE");
TTree *eventTree;
eventTree_ = new TTree ("eventTreeReco", " Events");
//Create some branches in the new file
elecs = new TClonesArray ("TopTree::TRootElectron", 0);
eventTree_->Branch ("Electrons", "TClonesArray", &elecs);
Long64_t nentries = events->GetEntriesFast ();
fChain->SetBranchStatus("*",0);
nentries = 2;
for (Long64_t jentry = 0; jentry < nentries; jentry++)
{
fChain->SetBranchStatus("Electron",1);
fChain->SetBranchAddress ("Electron", &init_elecs, &b_input_Electrons);
Chain->GetEntry (jentry);
ElectronAnalyzer EleA;
///////loop for Elecs
elecs->Clear ("C");
for (int ie = 0; ie < init_elecs->GetEntriesFast (); ie++)
EleA.AnalysisE (ie, (TRootElectron *) init_elecs->At (ie), elecs);
eventTree_->Fill ();
}
if (verbose)
cout << " All info succesfully for " << nentries << " events " << endl;
eventTree_->Write ();
fout_->Write ();
Code like: fChain->SetBranchStatus("Electron",1);
fChain->SetBranchAddress ("Electron", &init_elecs, &b_input_Electrons); is usually executed before the main loop ; any particular reason why you put in inside the loop? What is the type of init_elecs and b_input_Electrons? What is the complete stack trace at the time of the crash? What does valgrind report if you run it with your example?
I am attaching the complete file that I actually use --You are right for your comments, but unfortunatelly, valgrid does not compile in my UI…
Nevertheless, I am using a namespace TopTree, as MY output file has branches inherited from TRoot classes, while the input file (Delphes .root ) also uses the same name (by accident) for the same object , and this is why I had to introduced this namespace
Thanks for your time, would be obliged if you could point me the solution DelphesRecoObjects.cpp (4.6 KB)
I see init_muons = new TClonesArray ("TopTree::TRootMuon", 1000);
init_elecs = new TClonesArray ("TopTree::TRootElectron", 1000);
init_jets = new TClonesArray ("TRootCaloJet", 1000);
init_mets = new TClonesArray ("TRootETmis", 1000);are the class name in the input TTree really in the namespace TopTree?
I see init_muons = new TClonesArray ("TopTree::TRootMuon", 1000);
init_elecs = new TClonesArray ("TopTree::TRootElectron", 1000);
init_jets = new TClonesArray ("TRootCaloJet", 1000);
init_mets = new TClonesArray ("TRootETmis", 1000);are the class name in the input TTree really in the namespace TopTree?
Philippe.[/quote]
Hi Philippe
indeed, TRootMuon and TRootElectron had to put in the namespace TopTree as Delphes uses the sames names – while TRootEtmis and TRootCaloJet were not “duplicated” in that sence . I tried to comment out everything, except TRootElectron for example, in an effort to just open the input file, read the electron collection and write a TClonesArray TRootElectron class in the output file…Nevertheless, still the same segmentation fault error…
I am bit a confused. If I understood correctly ‘init_muons’ is intended to be for reading the input file, the input file is Delphes.root and Delphes.root use ‘TRootMuon’ as the name of the class, so why do you ‘change’ the name of the class that is being read in?
I am bit a confused. If I understood correctly ‘init_muons’ is intended to be for reading the input file, the input file is Delphes.root and Delphes.root use ‘TRootMuon’ as the name of the class, so why do you ‘change’ the name of the class that is being read in?
Philippe.[/quote]
Because, the output file, needs to have a collection (using a TClonesArray TopTree:: ) inherited from TRootMuon class --not the one the Delphes uses, but a TRoot Class - So, actually, input and output have common name for TRootMuon (as well as TRootElectron) , but completely different methods / members - This is where the EleAnalyzer “enters” and copies the members I need from the input to the output file - In any case, my previous version, using TRoot object for 22X was working, but not for this one, which is based in CMSSW 35X version - (For example, TRootCaloJet is a class which is only present in 35X )
Your code was actually ‘accidentally’ working in v5.22. You are reading one class and storing in memory in an unrelated class (as far as the I/O is concerned), you happen to be lucky that in v5.22 the two classes had the same exact in-memory layout. In the trunk the layout of an emulated class (a class without a dictionary) and the same class with a dictionary is no longer the same so that we can support polymorphism for emulated classes.
You really need to use the ‘old’ class name when constructing the TClonesArray (and have the dictionary for this ‘old’ class).
Your code was actually ‘accidentally’ working in v5.22. You are reading one class and storing in memory in an unrelated class (as far as the I/O is concerned), you happen to be lucky that in v5.22 the two classes had the same exact in-memory layout. In the trunk the layout of an emulated class (a class without a dictionary) and the same class with a dictionary is no longer the same so that we can support polymorphism for emulated classes.
You really need to use the ‘old’ class name when constructing the TClonesArray (and have the dictionary for this ‘old’ class).
Philippe.[/quote]
But, for both cases, I do have a dictionary, ie a lib which corresponds to Delphes classes, which also the case for 5.26, ie I do have different .so files for each one that I load when g ++ …
So, if I got it correctly, you mean that the same version, actually accidentally worked, while for 5.26 is not the case due to different in-memory handling ? Is this what you want to say ? Still, the working root version is 5.18…So, how can I correct this, can you give me an example?
[quote]So, how can I correct this, can you give me an example? [/quote]I am not sure … I meant: init_muons = new TClonesArray ("TRootMuon", 1000);
init_elecs = new TClonesArray ("TRootElectron", 1000);
init_jets = new TClonesArray ("TRootCaloJet", 1000);
init_mets = new TClonesArray ("TRootETmis", 1000);
[quote]But, for both cases, I do have a dictionary, ie a lib which corresponds to Delphes classes, which also the case for 5.26, ie I do have different .so files for each one that I load when g ++ … [/quote]humm … so the difference is not the one I was thinking about. If you sent a complete running example, I will try out a solution or two.
so, I ve put some files under /alkaloge/public (lxplus) area, (also a .root “input” file as well as the .so files) - Nevertheless , you can co from the cvs are the package
Problem solved… I just had to remove the TopTree:: from some branches and first do a SetBranchAddress ("*",0) and then one-by-one to ("…",1) just before reading it…