ATLAS Offline Software
Loading...
Searching...
No Matches
TruthDerivationTester.cxx File Reference
#include "POOLRootAccess/TEvent.h"
#include "GaudiKernel/SmartIF.h"
#include <boost/program_options.hpp>
#include "PATInterfaces/MessageCheck.h"
#include "AsgTools/AnaToolHandle.h"
#include "PMGAnalysisInterfaces/IPMGTruthWeightTool.h"
#include "xAODTruth/TruthEventContainer.h"
#include "xAODTruth/TruthParticleContainer.h"
#include "xAODEventInfo/EventInfo.h"
#include "xAODMissingET/MissingETContainer.h"
#include "xAODJet/JetContainer.h"
#include "xAODTruth/TruthVertexContainer.h"
#include "xAODTruth/TruthMetaDataContainer.h"
#include "AthContainers/ConstAccessor.h"
#include <TFile.h>
#include <TChain.h>
#include <TH1D.h>
#include <iostream>
#include <cmath>
#include <format>

Go to the source code of this file.

Macros

#define CHECK_RETRIEVE(container, name)

Functions

int countChildren (const xAOD::TruthParticle *p)
int countParents (const xAOD::TruthParticle *p)
int main (int argc, char **argv)

Macro Definition Documentation

◆ CHECK_RETRIEVE

#define CHECK_RETRIEVE ( container,
name )
Value:
{ \
if (!event.retrieve( container , name ).isSuccess()){ \
Error( APP_NAME , "%s", std::format ("Could not load event {} from the file!" , name ).c_str()); \
throw std::runtime_error("Container retrieval failed"); \
} \
}
#define APP_NAME

Definition at line 57 of file TruthDerivationTester.cxx.

57#define CHECK_RETRIEVE( container , name ) { \
58 if (!event.retrieve( container , name ).isSuccess()){ \
59 Error( APP_NAME , "%s", std::format ("Could not load event {} from the file!" , name ).c_str()); \
60 throw std::runtime_error("Container retrieval failed"); \
61 } \
62 }

Function Documentation

◆ countChildren()

int countChildren ( const xAOD::TruthParticle * p)

Definition at line 65 of file TruthDerivationTester.cxx.

65 {
66 if (!p) return 0;
67 int children = 0;
68 for (size_t n=0;n<p->nChildren();++n){
69 children += countChildren( p->child(n) );
70 }
71 return children;
72}
int countChildren(const xAOD::TruthParticle *p)

◆ countParents()

int countParents ( const xAOD::TruthParticle * p)

Definition at line 75 of file TruthDerivationTester.cxx.

75 {
76 if (!p) return 0;
77 int parents = 0;
78 for (size_t n=0;n<p->nParents();++n){
79 parents += countParents( p->parent(n) );
80 }
81 return parents;
82}
int countParents(const xAOD::TruthParticle *p)
parents
print ("==> buf:",buf)

◆ main()

int main ( int argc,
char ** argv )

Definition at line 85 of file TruthDerivationTester.cxx.

85 {
86
87 // The application's name:
88 const char* APP_NAME = argv[ 0 ];
89
90 // Make sure things know we are not in StatusCode land
91 using namespace asg::msgUserCode;
93
94 // Setup for reading -- if this fails, we have major problems
95#ifdef XAOD_STANDALONE
96 if ( ! xAOD::Init().isSuccess() ) {
97 throw std::runtime_error("Cannot initialise xAOD access !");
98 }
99 ANA_MSG_INFO("Using xAOD access");
100#else
101 SmartIF<IAppMgrUI> app = POOL::Init();
102 ANA_MSG_INFO("Using POOL access");
103#endif
104
105 // Get and parse the command-line arguments
106 po::options_description desc("Running a simple truth analysis");
107 std::string outputName,inputName;
108 desc.add_options()
109 ("help,h", "print usage and exit")
110 ("output,o", po::value<std::string>(&outputName), "Output file name")
111 ("input,i", po::value<std::string>(&inputName), "Input file name")
112 ("nevents", po::value<int>()->default_value(-1), "number of events to run on (set to -1 to ignore it")
113 ;
114
115 po::variables_map vm;
116 po::store( po::command_line_parser(argc, argv).options(desc).run(), vm);
117 po::notify(vm);
118
119 if (vm.count("help")) {
120 std::cout << desc << std::endl;
121 return 1;
122 }
123
124 long long nevents = -1;
125 if (vm.count("nevents")) {
126 nevents = vm["nevents"].as<int>();
127 }
128
129 Info( "Reading from %s and writing to %s" , inputName.c_str() , outputName.c_str() );
130
131 // Input chain
132 std::unique_ptr< TFile > ifile( TFile::Open( inputName.c_str() , "READ" ) );
133 ANA_CHECK( ifile.get() );
134#ifdef XAOD_STANDALONE
136#else
138#endif
139 ANA_CHECK( event.readFrom( ifile.get() ) );
140
141 // Load metadata
142 event.getEntries();
143
144 // Make some temporary variables that we'll get out during the event loop
145 const size_t nParticleContainers = 9;
146 std::string particleKeyList[nParticleContainers] = { "TruthElectrons", "TruthMuons", "TruthPhotons", "TruthTaus", "TruthNeutrinos", "TruthBSM", "TruthBottom", "TruthTop", "TruthBoson" };
147 const xAOD::TruthEventContainer* xTruthEventContainer(nullptr);
148 const xAOD::EventInfo* xEventInfo(nullptr);
149 const xAOD::JetContainer* smallRJets(nullptr);
150 const xAOD::JetContainer* largeRJets(nullptr);
151 const xAOD::TruthMetaDataContainer* truthMeta(nullptr);
152 const xAOD::MissingETContainer* truthMET(nullptr);
153 const xAOD::TruthParticleContainer * truthParticles[nParticleContainers];
154 for (size_t n=0;n<nParticleContainers;++n) truthParticles[n] = nullptr;
155
156/*
157 Missing full collections with aux: TruthBosonsWithDecayParticles, TruthBosonsWithDecayVertices
158*/
159 // Make histograms
160 // MET histograms
161 TH1D* h_metNonInt = new TH1D("MET_NonInt","",50,0,500.);
162 TH1D* h_metInt = new TH1D("MET_Int","",50,0,200.);
163 TH1D* h_metIntOut = new TH1D("MET_IntOut","",50,0,100.);
164 TH1D* h_metIntMuons = new TH1D("MET_IntMuons","",50,0,300.);
165 // Particle collections: pT and connections for all
166 TH1D* h_partPt[nParticleContainers];
167 for (size_t n=0;n<nParticleContainers;++n) h_partPt[n] = new TH1D((particleKeyList[n]+"_pT").c_str(),"",50,0.,500.);
168 TH1D* h_partConn[nParticleContainers];
169 for (size_t n=0;n<nParticleContainers;++n) h_partConn[n] = new TH1D((particleKeyList[n]+"_Connections").c_str(),"",35,-10,25);
170 // Isolation for e/y/u/tau
171 TH1D* h_elPtCone = new TH1D("ElPtCone","",50,0.,20.);
172 TH1D* h_elEtCone = new TH1D("ElEtCone","",50,0.,20.);
173 TH1D* h_muPtCone = new TH1D("MuPtCone","",50,0.,20.);
174 TH1D* h_muEtCone = new TH1D("MuEtCone","",50,0.,20.);
175 TH1D* h_phPtCone = new TH1D("PhPtCone","",50,0.,20.);
176 TH1D* h_phEtCone = new TH1D("PhEtCone","",50,0.,20.);
177 // MCTC decorations for e/y/u/tau/nu
178 TH1D* h_elType = new TH1D("ElType","",50,0,50);
179 TH1D* h_elOrig = new TH1D("ElOrigin","",50,0,50);
180 TH1D* h_muType = new TH1D("MuType","",50,0,50);
181 TH1D* h_muOrig = new TH1D("MuOrigin","",50,0,50);
182 TH1D* h_phType = new TH1D("PhType","",50,0,50);
183 TH1D* h_phOrig = new TH1D("PhOrigin","",50,0,50);
184 TH1D* h_taType = new TH1D("TaType","",50,0,50);
185 TH1D* h_taOrig = new TH1D("TaOrigin","",50,0,50);
186 TH1D* h_nuType = new TH1D("NuType","",50,0,50);
187 TH1D* h_nuOrig = new TH1D("NuOrigin","",50,0,50);
188 // Dressed momenta for e/mu/tau
189 TH1D* h_elDressedPt = new TH1D("ElDressedPt","",50,0.,200.);
190 TH1D* h_muDressedPt = new TH1D("MuDressedPt","",50,0.,200.);
191 TH1D* h_taDressedPt = new TH1D("TaDressedPt","",50,0.,200.);
192 // Truth jets: pT, three flavor classifiers
193 TH1D* h_jetPt = new TH1D("JetPt","",50,0,500.);
194 TH1D* h_jetFTAG = new TH1D("JetFTAG","",25,0,25);
195 TH1D* h_jetJeMe = new TH1D("JetJeMe","",25,0,25);
196 TH1D* h_jetFull = new TH1D("JetFull","",50,0,50);
197 // Large R : pT, tau2, D2
198 TH1D* h_jetLRPt = new TH1D("JetLRPt","",50,0,500.);
199 TH1D* h_jetLRT2 = new TH1D("JetLRT2","",50,0,500.);
200 TH1D* h_jetLRD2 = new TH1D("JetLRD2","",50,0,500.);
201 // Truth events: PDF info , cross section , filter outcome
202 TH1D* h_x1 = new TH1D("X1","",50,0,1.);
203 TH1D* h_x2 = new TH1D("X2","",50,0,1.);
204 TH1D* h_xsec = new TH1D("XSec","",50,0,1.);
205 TH1D* h_HTFilt = new TH1D("HTFilt","",50,0,1000.);
206 // Lazy for truth weights
207 asg::AnaToolHandle< PMGTools::IPMGTruthWeightTool > weightTool("PMGTools::PMGTruthWeightTool/PMGTruthWeightTool");
208 ANA_CHECK(weightTool.retrieve());
209
210 // For the weights in the file
211 std::vector<TH1D*> h_weights;
212 // For testing the truth metadata
213 uint32_t channelNumber = 0;
214 std::vector<std::string> weightNames;
215
216 // Into the event loop, with an optional cap
217 long long nEvents = nevents > 0 ? std::min(static_cast<long long>(event.getEntries()), nevents) : event.getEntries();
218 Info( APP_NAME , "Beginning event loop over %llu events." , nEvents );
219 for (long evt=0;evt<nEvents;++evt){
220 // Grab the data
221 event.getEntry(evt);
222 if (evt%1000==0) Info( APP_NAME , "Working on entry %lu" , evt );
223
224 // Get the containers out
225 CHECK_RETRIEVE( xTruthEventContainer , "TruthEvents" )
226 CHECK_RETRIEVE( xEventInfo , "EventInfo" )
227 CHECK_RETRIEVE( smallRJets , "AntiKt4TruthDressedWZJets" )
228 CHECK_RETRIEVE( largeRJets , "AntiKt10TruthTrimmedPtFrac5SmallR20Jets" )
229 CHECK_RETRIEVE( truthMET , "MET_Truth" )
230 for (size_t n=0;n<nParticleContainers;++n){
231 CHECK_RETRIEVE( truthParticles[n] , particleKeyList[n] )
232 }
233
234 if (!event.retrieveMetaInput( truthMeta , "TruthMetaData" ).isSuccess()){
235 Error( APP_NAME , "Could not load event TruthMetaData from the file!" );
236 throw std::runtime_error("Could not load event TruthMetaData from the file!");
237 }
238
239 // Metadata check
240 if (truthMeta->size()>1){
241 Error( APP_NAME , "Truth metadata size: %lu . No one will look past item 0!" , truthMeta->size() );
242 throw std::runtime_error("Truth metadata size >1");
243 }
244 if (channelNumber==0){
245 channelNumber = (*truthMeta)[0]->mcChannelNumber();
246 weightNames = std::vector<std::string>((*truthMeta)[0]->weightNames());
247 Info( APP_NAME , "Got channel number %u and %lu weight names" , channelNumber , weightNames.size() );
248 }
249 if (channelNumber != (*truthMeta)[0]->mcChannelNumber()){
250 Error( APP_NAME , "Channel number changed mid-file! Was: %u now: %u " , channelNumber , (*truthMeta)[0]->mcChannelNumber() );
251 throw std::runtime_error("Channel number changed mid-file!");
252 }
253 if (weightNames != (*truthMeta)[0]->weightNames() ){
254 Error( APP_NAME , "Weights have changed!" );
255 for (size_t n=0;n<std::max( weightNames.size() , (*truthMeta)[0]->weightNames().size() );++n){
256 std::cerr << " " << n << " ";
257 if (n<weightNames.size()) std::cerr << weightNames[n] << " ";
258 else std::cerr << "- ";
259 if (n<(*truthMeta)[0]->weightNames().size()) std::cerr << (*truthMeta)[0]->weightNames()[n] << " ";
260 else std::cerr << "- ";
261 std::cerr << std::endl;
262 }
263 throw std::runtime_error("Weights have changed!");
264 }
265 // Event weight handling
266 if (h_weights.size()==0){
267 // First event, init!
268 for (auto & name : weightNames ){
269 h_weights.push_back( new TH1D(("h_W_"+name).c_str(),"",100,-10.,10.) );
270 }
271 h_weights.push_back( new TH1D("h_W_nominalTest","",100,-10.,10.) );
272 }
273 for (size_t n=0;n<weightNames.size();++n) h_weights[n]->Fill( weightTool->getWeight(xEventInfo,weightNames[n]) );
274 // Eventually this should be the nominal weight without needing to give an explicit name
275 h_weights[weightNames.size()]->Fill( weightTool->getWeight(xEventInfo," nominal ") );
276 // Event info
277 float x1=0.,x2=0.;
278 (*xTruthEventContainer)[0]->pdfInfoParameter( x1 , xAOD::TruthEvent::X1 );
279 (*xTruthEventContainer)[0]->pdfInfoParameter( x2 , xAOD::TruthEvent::X2 );
280 h_x1->Fill( x1 );
281 h_x2->Fill( x2 );
282 h_xsec->Fill( (*xTruthEventContainer)[0]->crossSection() );
283 static const SG::ConstAccessor<float> GenFiltHTAcc ("GenFiltHT");
284 h_HTFilt->Fill( GenFiltHTAcc (*xEventInfo ) );
285 // For MET: NonInt, Int, IntOut, IntMuons
286 h_metNonInt->Fill( (*truthMET)["NonInt"]->met()*0.001 );
287 h_metNonInt->Fill( (*truthMET)["Int"]->met()*0.001 );
288 h_metNonInt->Fill( (*truthMET)["IntOut"]->met()*0.001 );
289 h_metNonInt->Fill( (*truthMET)["IntMuons"]->met()*0.001 );
290 // Truth particles
291 for (size_t n=0;n<nParticleContainers;++n){ // PT and connections for all
292 for (const auto * p : *truthParticles[n]){
293 h_partPt[n]->Fill( p->pt() );
294 h_partConn[n]->Fill( countChildren( p ) );
295 h_partConn[n]->Fill( -1-countParents( p ) );
296 }
297 }
298
299 static const SG::ConstAccessor<float> ptcone30Acc("ptcone30");
300 static const SG::ConstAccessor<float> ptcone20Acc("ptcone20");
301 static const SG::ConstAccessor<float> etcone20Acc("etcone20");
302 static const SG::ConstAccessor<float> pt_dressedAcc("pt_dressed");
303 static const SG::ConstAccessor<float> pt_vis_dressedAcc("pt_vis_dressed");
304 static const SG::ConstAccessor<float> Tau2_wtaAcc("Tau2_wta");
305 static const SG::ConstAccessor<float> D2Acc("D2");
306 static const SG::ConstAccessor<unsigned int> classifierParticleTypeAcc("classifierParticleType");
307 static const SG::ConstAccessor<unsigned int> classifierParticleOriginAcc("classifierParticleOrigin");
308 static const SG::ConstAccessor<int> HadronConeExclTruthLabelIDAcc("HadronConeExclTruthLabelID");
309 static const SG::ConstAccessor<int> PartonTruthLabelIDAcc("PartonTruthLabelID");
310 static const SG::ConstAccessor<int> TrueFlavorAcc("TrueFlavor");
311
312 for (const auto * p : *truthParticles[0]){ // Electrons
313 h_elPtCone->Fill( ptcone30Acc(*p)*0.001 );
314 h_elEtCone->Fill( etcone20Acc(*p)*0.001 );
315 h_elDressedPt->Fill( pt_dressedAcc(*p)*0.001 );
316 h_elType->Fill( classifierParticleTypeAcc(*p) );
317 h_elOrig->Fill( classifierParticleOriginAcc(*p) );
318 }
319 for (const auto * p : *truthParticles[1]){ // Muons
320 h_muPtCone->Fill( ptcone30Acc(*p)*0.001 );
321 h_muEtCone->Fill( etcone20Acc(*p)*0.001 );
322 h_muDressedPt->Fill( pt_dressedAcc(*p)*0.001 );
323 h_muType->Fill( classifierParticleTypeAcc(*p) );
324 h_muOrig->Fill( classifierParticleOriginAcc(*p) );
325 }
326 for (const auto * p : *truthParticles[2]){ // Photons
327 h_phPtCone->Fill( ptcone20Acc(*p)*0.001 );
328 h_phEtCone->Fill( etcone20Acc(*p)*0.001 );
329 h_phType->Fill( classifierParticleTypeAcc(*p) );
330 h_phOrig->Fill( classifierParticleOriginAcc(*p) );
331 }
332 for (const auto * p : *truthParticles[3]){ // Taus
333 h_taDressedPt->Fill( pt_vis_dressedAcc(*p)*0.001 );
334 h_taType->Fill( classifierParticleTypeAcc(*p) );
335 h_taOrig->Fill( classifierParticleOriginAcc(*p) );
336 }
337 for (const auto * p : *truthParticles[4]){ // Neutrinos
338 h_nuType->Fill( classifierParticleTypeAcc(*p) );
339 h_nuOrig->Fill( classifierParticleOriginAcc(*p) );
340 }
341 for (const auto * j : *smallRJets){ // Small-R jets
342 h_jetPt->Fill( j->pt()*0.001 );
343 h_jetFTAG->Fill( HadronConeExclTruthLabelIDAcc(*j) );
344 h_jetJeMe->Fill( PartonTruthLabelIDAcc(*j) );
345 h_jetFull->Fill( TrueFlavorAcc(*j) );
346 }
347 for (const auto * j : *largeRJets){ // Large-R jets
348 h_jetLRPt->Fill( j->pt()*0.001 );
349 h_jetLRT2->Fill( Tau2_wtaAcc(*j) );
350 h_jetLRD2->Fill( D2Acc(*j) );
351 }
352
353 } // End of event loop
354 Info( APP_NAME , "Done with event loop" );
355
356 // Output file
357 TFile * oRoot = new TFile(outputName.c_str(),"RECREATE");
358 oRoot->cd();
359
360 // Write histograms
361 // MET histograms
362 h_metNonInt->Write();
363 h_metInt->Write();
364 h_metIntOut->Write();
365 h_metIntMuons->Write();
366 // Truth particle histograms
367 for (size_t n=0;n<nParticleContainers;++n) h_partPt[n]->Write();
368 for (size_t n=0;n<nParticleContainers;++n) h_partConn[n]->Write();
369 h_elPtCone->Write();
370 h_elEtCone->Write();
371 h_muPtCone->Write();
372 h_muEtCone->Write();
373 h_phPtCone->Write();
374 h_phEtCone->Write();
375 h_elDressedPt->Write();
376 h_muDressedPt->Write();
377 h_taDressedPt->Write();
378 h_elType->Write();
379 h_elOrig->Write();
380 h_muType->Write();
381 h_muOrig->Write();
382 h_phType->Write();
383 h_phOrig->Write();
384 h_taType->Write();
385 h_taOrig->Write();
386 h_nuType->Write();
387 h_nuOrig->Write();
388 // Truth jet histograms
389 h_jetPt->Write();
390 h_jetFTAG->Write();
391 h_jetJeMe->Write();
392 h_jetFull->Write();
393 h_jetLRPt->Write();
394 h_jetLRT2->Write();
395 h_jetLRD2->Write();
396 // Event histograms
397 h_x1->Write();
398 h_x2->Write();
399 h_xsec->Write();
400 h_HTFilt->Write();
401 for (auto * h : h_weights) h->Write();
402
403 // Close up -- all done!
404 oRoot->Close();
405
406 // trigger finalization of all services and tools created by the Gaudi Application
407#ifndef XAOD_STANDALONE
408 if (app->finalize().isFailure()){
409 Warning( APP_NAME , "Finalization failed?" );
410 }
411#endif
412
413 Info( APP_NAME , "All done -- goodbye." );
414
415 return 0;
416}
#define ANA_MSG_INFO(xmsg)
Macro printing info messages.
#define ANA_CHECK(EXP)
check whether the given expression was successful
#define ANA_CHECK_SET_TYPE(TYPE)
set the type for ANA_CHECK to report failures
#define CHECK_RETRIEVE(container, name)
Header file for AthHistogramAlgorithm.
Helper class to provide constant type-safe access to aux data.
a modified tool handle that allows its owner to configure new tools from the C++ side
Tool for accessing xAOD files outside of Athena.
@ kClassAccess
Access auxiliary data using the aux containers.
const int nEvents
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition Error.h:16
IAppMgrUI * Init(const char *options="POOLRootAccess/basic.opts")
Bootstraps (creates and configures) the Gaudi Application with the provided options file.
@ Info
Definition ZDCMsg.h:20
str outputName
Definition lumiFormat.py:65
Definition run.py:1
TruthEventContainer_v1 TruthEventContainer
Declare the latest version of the truth event container.
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition Init.cxx:31
EventInfo_v1 EventInfo
Definition of the latest event info version.
TruthMetaDataContainer_v1 TruthMetaDataContainer
Declare the latest version of the truth vertex container.
JetContainer_v1 JetContainer
Definition of the current "jet container version".
setEventNumber uint32_t
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.