#1369 closed How to (fixed)
Why does calling treeReader->UseBranch(... change outcome even if the pointer isn't used?
Reported by: | flyingMoggy | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | Delphes code | Version: | Delphes 3 |
Keywords: | Cc: | Pavel Demin |
Description
Apologies, I know this is the second time posting this but two of my colleagues (Alexander Titterton and Dr Emmanuel Olaiya) are just as perplexed as I am by this behavior.
I suspect I did not do a very good job of explaining what I observed in the first post, and it was closed based on a misunderstanding.
The class $ROOTSYS/Delphes/examples/Example3.C can be stripped down to simply read the momentum and energy values of particles on a jet by jet basis (as seen below).
It might be expected that branchJet would return a combination of Tracks and Towers. It will certainly contain references to objects held in other branches, perhaps branchEFlowTrack/branchEFlowPhoton/branchEFlowNeutralHadron. What is surprising is that branchJet only contains Tracks and Towers *if* a pointers to branchEFlowTrack & branchEFlowPhoton & branchEFlowNeutralHadron are created, otherwise it contains GenParticles!
Why does the contents of branchJet vary according to the the existence of other pointers? And why would it end up containing GenParticles?
Many thanks,
Henry Day-Hall
#ifdef __CLING__ R__LOAD_LIBRARY(libDelphes) #include "classes/DelphesClasses.h" #include "external/ExRootAnalysis/ExRootTreeReader.h" #include "external/ExRootAnalysis/ExRootResult.h" #else class ExRootTreeReader; class ExRootResult; #endif void AnalyseEvents(ExRootTreeReader *treeReader) { { // Some files to write results to. ~~~~ ofstream jetOut("jetPts.csv"); ofstream trackOut("trackPts.csv"); ofstream towerOut("towerPts.csv"); ofstream genOut("genPts.csv"); //Now get the addresses of the branches that contain the data we want ~~~~~~~~~~~~~~~~ TClonesArray *branchParticle = treeReader->UseBranch("Particle"); //TClonesArray *branchElectron = treeReader->UseBranch("Electron"); //TClonesArray *branchPhoton = treeReader->UseBranch("Photon"); //TClonesArray *branchMuon = treeReader->UseBranch("Muon"); //~~~~~ Uncommenting this give tracks //TClonesArray *branchEFlowTrack = treeReader->UseBranch("EFlowTrack"); //~~~~~ Uncommenting this give towers //TClonesArray *branchEFlowPhoton = treeReader->UseBranch("EFlowPhoton"); //~~~~~ Uncommenting this give towers //TClonesArray *branchEFlowNeutralHadron = treeReader->UseBranch("EFlowNeutralHadron"); //~~~~~~~ Why are the existance of unused pointers changing the output? TClonesArray *branchJet = treeReader->UseBranch("Jet"); //Decide when to end the loop ~~~~~~~~~~~~~~~~ Long64_t allEntries = treeReader->GetEntries(); cout << "** Chain contains " << allEntries << " events" << endl; // make a variable to store the object found in the branch in ~~~~~~~~~~~~~~~~ GenParticle *particle; //Electron *electron; //Photon *photon; //Muon *muon; Track *track; Tower *tower; Jet *jet; TObject *object; TLorentzVector momentum; //Float_t Eem, Ehad; //Bool_t skip; Long64_t entry; Int_t i, j; //, pdgCode; // Loop over all events for(entry = 0; entry < allEntries; ++entry) { // Load selected branches with data from specified event treeReader->ReadEntry(entry); cout << "-- New event -- " << endl; // Loop over all jets in event for(i = 0; i < branchJet->GetEntriesFast(); ++i) { jet = (Jet*) branchJet->At(i); momentum.SetPxPyPzE(0.0, 0.0, 0.0, 0.0); cout<<"Looping over jet constituents. Jet pt: "<<jet->PT<<", eta: "<<jet->Eta<<", phi: "<<jet->Phi<<endl; jetOut << jet->PT; // Loop over all jet's constituents for(j = 0; j < jet->Constituents.GetEntriesFast(); ++j) { object = jet->Constituents.At(j); // Check if the constituent is accessible if(object == 0) continue; // object->IsA() will change depending on which lines are commented/uncommented above! // but why? object always comes out of branchJet, why do other branches change it's behavior? if(object->IsA() == GenParticle::Class()) { particle = (GenParticle*) object; cout << " GenPart pt: " << particle->PT << ", eta: " << particle->Eta << ", phi: " << particle->Phi << endl; momentum += particle->P4(); genOut << particle->PT << ","; } else if(object->IsA() == Track::Class()) { track = (Track*) object; cout << " Track pt: " << track->PT << ", eta: " << track->Eta << ", phi: " << track->Phi << endl; momentum += track->P4(); trackOut << track->PT << ","; } else if(object->IsA() == Tower::Class()) { tower = (Tower*) object; cout << " Tower pt: " << tower->ET << ", eta: " << tower->Eta << ", phi: " << tower->Phi << endl; momentum += tower->P4(); towerOut << tower->ET << ","; } } jetOut << endl; towerOut << endl; genOut << endl; trackOut << endl; } } } } //------------------------------------------------------------------------------ void jet_constits(const char *inputFile) { gSystem->Load("libDelphes"); TChain *chain = new TChain("Delphes"); chain->Add(inputFile); ExRootTreeReader *treeReader = new ExRootTreeReader(chain); AnalyseEvents(treeReader); cout << "** Exiting..." << endl; delete treeReader; delete chain; } //------------------------------------------------------------------------------
Attachments (2)
Change History (5)
by , 6 years ago
Attachment: | jet_constits.C added |
---|
by , 6 years ago
Attachment: | tag_1_delphes_events.root added |
---|
comment:2 by , 6 years ago
What is surprising is that branchJet only contains Tracks and Towers *if* a pointers to branchEFlowTrack & branchEFlowPhoton & branchEFlowNeutralHadron are created, otherwise it contains GenParticles?!
If the branches containing the referenced objects aren't loaded, then the reference could point to an object with the same UID from a previous event.
For example, if in the current event a jet has its first constituent of type Track with UID 2646 and branch EFlowTrack isn't loaded but if the previous event contained a particle from the branch Particle with the same UID 2646, then it's the particle from the previous event that is returned by jet->Constituents.At(0).
comment:3 by , 6 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
The Constituents list in the class Jet contains only the *references* to constituents not the constituents themselves.
The constituents are stored in other branches (Track, Tower, etc).
If you comment out the lines that call the methods UseBranch("EFlowTrack"), UseBranch("EFlowPhoton"), etc, then the constituents from these branches aren't loaded from the ROOT file to the memory and can't be accessed via the references.
More information about the references can be found at the following links:
https://root.cern.ch/doc/master/classTRef.html
https://root.cern.ch/doc/master/classTRefArray.html