ATLAS Offline Software
Loading...
Searching...
No Matches
TrackValidationNtupleWriter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TrackValidationNtupleWriter.cxx, (c) ATLAS Detector Software
8
10// Gaudi
11#include "GaudiKernel/ITHistSvc.h"
12
13#include "TTree.h"
14
15// Trk
16#include "TrkTrack/Track.h"
17
22
23//#include "TrkParameters/Perigee.h"
24
26
30
31// inventory of tools
41
42#include "CLHEP/Vector/LorentzVector.h"
43using CLHEP::HepLorentzVector;
44
45Trk::TrackValidationNtupleWriter::TrackValidationNtupleWriter(const std::string& name, ISvcLocator* pSvcLocator):
46 AthAlgorithm(name,pSvcLocator),
48 m_ValTrkParticleNtupleTool("Trk::BasicValTrkParticleNtupleTool/BasicValTrkParticleNtupleTool"),
49 m_truthNtupleTool("Trk::TruthNtupleTool/TruthNtupleTool"),
57 m_McEventCollectionName("TruthEvent"),
59 m_ntupleFileName("TRKVAL"),
60 m_ntupleDirName("Validation"),
61 m_truthToTrack("Trk::TruthToTrack/TruthToTrack"),
62 m_trackSelector("InDet::InDetTrackSelectorTool/InDetTrackSelectorTool"),
63 m_genPartSelector("Trk::InDetReconstructableSelector/InDetReconstructableSelector"),
64 m_genJetFinder("Trk::GenParticleJetFinder/GenParticleJetFinder"),
66 m_doTruth(true),
67 m_doTrackParticle(false),
70 m_trees(0),
71 m_eventLinkTree(nullptr)
72
73{
74 m_ValidationNtupleTools.push_back("Trk::TrackInformationNtupleTool/TrackInformationNtupleTool");
75 m_ValidationNtupleTools.push_back("Trk::PerigeeParametersNtupleTool/PerigeeParametersNtupleTool");
76 m_ValidationNtupleTools.push_back("Trk::MeasurementVectorNtupleTool/MeasurementVectorNtupleTool");
77 m_trackTruthClassifierHandles.push_back("Trk::PrimaryTruthClassifier/PrimaryTruthClassifier");
78
79 m_eventPropertyNtupleHandles.push_back("Trk::EventPropertyNtupleTool/EventPropertyNtupleTool");
80 m_eventPropertyNtupleHandles.push_back("Trk::EventToTrackLinkNtupleTool/EventToTrackLinkNtupleTool");
81
82 m_inputTrackCollection.emplace_back("Tracks");
83 m_trackTruthCollectionName.emplace_back("TrackTruthCollection");
84
85 declareProperty("TrackCollection", m_inputTrackCollection, "Names of the track collections");
86 declareProperty("TrackParticleCollection", m_inputTrackParticleCollection, "Names of the track particle collections");
87 declareProperty("TrackTruthCollection", m_trackTruthCollectionName, "Names of the truth track collections (if DoTruth=True)");
88 declareProperty("TruthCollection", m_McEventCollectionName, "Name of the truth (gen event) collection (if DoTruth=True)");
89 declareProperty("PrimaryVertexCollection", m_inputPrimaryVertexCollection, "SG key of input PrimaryVertex collection (needed for TrackSelector, if no vertex collection is given, the selector will not use the vertex position)");
90 declareProperty("NtupleFileName", m_ntupleFileName, "Ntuple file handle");
91 declareProperty("NtupleDirectoryName", m_ntupleDirName, "directory name for ntuple tree");
92 //declareProperty("NtupleTreeName", m_ntupleTreeNames, "Name of the ntuple trees (list corresponding to the list of input track collections)");
93 declareProperty("UseExternalEventLinkTree", m_useExternalEventLinkTree, "flag if event link tree is supplied externally, eg as part of CBNT");
94 declareProperty("DoTruth", m_doTruth, "Write truth data?");
95 declareProperty("ValidationNtupleTools", m_ValidationNtupleTools, "Tool to write the validation ntuple");
96 declareProperty("ValTrkParticleNtupleTool", m_ValTrkParticleNtupleTool, "Tool to write the validation ntuple for Track Particles");
97 declareProperty("TruthNtupleTool", m_truthNtupleTool, "Tool to write the truth ntuple");
98 declareProperty("JetNtupleTool", m_jetTruthNtupleTool, "Tool to add jet information to ntuple");
99 declareProperty("TruthToTrackTool", m_truthToTrack, "Tool for truth to track");
100 declareProperty("TrackSelectorTool", m_trackSelector, "Tool for the selection of tracks");
101 declareProperty("GenParticleSelectorTool", m_genPartSelector, "Tool for the selection of truth particles");
102 declareProperty("GenParticleJetFinder", m_genJetFinder, "Tool for jet clustering (MC)");
103 declareProperty("TruthClassifierTools", m_trackTruthClassifierHandles, "List of truth classifier tools");
104 declareProperty("EventPropertyNtupleTools", m_eventPropertyNtupleHandles,"List of event property ntuple tools");
105 declareProperty("doTrackParticle", m_doTrackParticle, "Swith to record Rec:TrackParticle Trees");
106}
107
109
111
112 msg(MSG::INFO) <<"TrackValidationNtupleWriter initialize()" << endmsg;
113
114 //check that m_inputTrackCollection and m_trackTruthCollectionName have the same size
116 msg(MSG::FATAL) << "joboptions TrackCollection and TrackTruthCollection have different sizes!" << endmsg;
117 msg(MSG::FATAL) << "If you like to get truth data (DoTruth=True)," << endmsg;
118 msg(MSG::FATAL) << " please make sure to set for each TrackCollection the corresponding TrackTruthCollection" << endmsg;
119 return StatusCode::FAILURE;
120 }
121
122 // Get Validation ntuple Tools
123 StatusCode sc = m_ValidationNtupleTools.retrieve();
124 if (sc.isFailure()) {
125 msg(MSG::FATAL) << "Could not retrieve "<< m_ValidationNtupleTools <<" (to write validation ntuple) "<< endmsg;
126 return sc;
127 }
129 // Get TrackParticle Validation ntuple Tool
130 sc = m_ValTrkParticleNtupleTool.retrieve();
131 if (sc.isFailure()) {
132 msg(MSG::FATAL) << "Could not retrieve "<< m_ValTrkParticleNtupleTool <<" (to write TrackParticle validation ntuple) "<< endmsg;
133 return sc;
134 }
135 }
136
137 // Get the Track Selector Tool
138 if ( !m_trackSelector.empty() ) {
139 sc = m_trackSelector.retrieve();
140 if (sc.isFailure()) {
141 msg(MSG::FATAL) << "Could not retrieve "<< m_trackSelector <<" (to select the tracks which are written to the ntuple) "<< endmsg;
142 msg(MSG::INFO) << "Set the ToolHandle to None if track selection is supposed to be disabled" << endmsg;
143 return sc;
144 }
145 }
146
147 msg(MSG::INFO) <<"Track Selector retrieved" << endmsg;
148 // -------------------------------
149 // get event property tools
150 ToolHandleArray< Trk::IEventPropertyNtupleTool >::iterator itTools;
151 if ( m_eventPropertyNtupleHandles.retrieve().isFailure() ) {
152 msg(MSG::ERROR) << "Failed to retreive " << m_eventPropertyNtupleHandles << endmsg;
153 } else {
154 msg(MSG::INFO) << "Retrieved " << m_eventPropertyNtupleHandles << endmsg;
155 }
156
157
158 //std::vector<std::string> classifierNames(0);
159 itTools = m_eventPropertyNtupleHandles.begin();
160 for ( ; itTools != m_eventPropertyNtupleHandles.end(); ++itTools ) {
161 // add tool to list
162 m_eventPropertyNtupleTools.push_back(&(*(*itTools)));
163 }
164
165 // Retrieve the TruthToTrack tool if truth is required
166 if ( m_doTruth ) {
167 sc = m_truthToTrack.retrieve();
168 if (sc.isFailure()) {
169 ATH_MSG_FATAL ("Could not retrieve "<< m_truthToTrack);
170 return sc;
171 }
172
173 // retrieve truth selector for efficiency denominator
174 sc = m_genPartSelector.retrieve();
175 if (sc.isFailure()) {
176 ATH_MSG_FATAL ("Could not retrieve "<< m_genPartSelector);
177 return sc;
178 }
179
180 // -------------------------------
181 // get given classifier tools
182 ToolHandleArray< ITrackTruthClassifier >::iterator itTools;
183 if ( m_trackTruthClassifierHandles.retrieve().isFailure() ) {
184 msg(MSG::ERROR) << "Failed to retreive " << m_trackTruthClassifierHandles << endmsg;
185 } else {
186 msg(MSG::INFO) << "Retrieved " << m_trackTruthClassifierHandles << endmsg;
187 }
188 //std::vector<std::string> classifierNames(0);
189 itTools = m_trackTruthClassifierHandles.begin();
190 for ( ; itTools != m_trackTruthClassifierHandles.end(); ++itTools ) {
191 // add tool to list
192 m_trackTruthClassifiers.push_back(&(*(*itTools)));
193 //classifierNames.push_back((*itTools)->nameOfClassifier());
194 }
195
196 // Get the Jet-Truth Ntuple Tool
197 if (! m_jetTruthNtupleTool.empty()) {
198 sc = m_jetTruthNtupleTool.retrieve();
199 if (sc.isFailure()) {
200 msg(MSG::ERROR) << "Could not retrieve "<< m_jetTruthNtupleTool
201 << " (to write jet data)."<< endmsg << "--> Instead configure "
202 << "to empty string if jet data not desired." << endmsg;
203 return sc;
204 }
205 sc = m_genJetFinder.retrieve();
206 if (sc.isFailure()) {
207 msg(MSG::ERROR) << "Could not retrieve "<< m_genJetFinder
208 << " (to find jets at truth level)."<< endmsg;
209 return sc;
210 }
211 }
212
213 // Get the Truth Ntuple Tool
214 sc = m_truthNtupleTool.retrieve();
215 if (sc.isFailure()) {
216 msg(MSG::FATAL) << "Could not retrieve "<< m_truthNtupleTool <<" (to write truth data) "<< endmsg;
217 return sc;
218 }
219 bool include_jets = (! m_jetTruthNtupleTool.empty());
221 if (sc.isFailure()) return sc;
222
224
225 } // if truth is activated
226
227 // ---------------------------
228 // retrieve pointer to THistSvc
229 SmartIF<ITHistSvc> tHistSvc{service("THistSvc")};
230 ATH_CHECK( tHistSvc.isValid() );
231
232 // ---------------------------
233 // create tree for each given track collection and register it to THistSvc
234 std::vector<std::string>::const_iterator trackColNameIter = m_inputTrackCollection.begin();
235 //for (unsigned int trackColIndex = 0; trackColIndex<m_inputTrackCollection.size(); trackColIndex++) {
236 for (; trackColNameIter != m_inputTrackCollection.end(); ++trackColNameIter) {
237 TTree* tree = new TTree((*trackColNameIter).c_str(), ((*trackColNameIter)+" Validation").c_str());
238 m_trees.push_back(tree);
239 std::string fullNtupleName = "/"+m_ntupleFileName+"/"+m_ntupleDirName+"/"+(*trackColNameIter);
240 sc = tHistSvc->regTree(fullNtupleName, tree);
241 if (sc.isFailure()) {
242 msg(MSG::ERROR) << "Unable to register TTree : " << fullNtupleName << endmsg;
243 return sc;
244 }
245 // add the ntuple branches to this tree
246 ToolHandleArray< Trk::ITrackValidationNtupleTool >::iterator itTools;
247 itTools = m_ValidationNtupleTools.begin();
248 for ( ; itTools != m_ValidationNtupleTools.end(); ++itTools ) {
249 if (((*itTools)->addNtupleItems(tree)).isFailure()) {
250 msg(MSG::ERROR) << "ValidationNtupleTool could not add its branches"
251 << " for tree " << fullNtupleName << endmsg;
252 return StatusCode::FAILURE;
253 }
254 }
255 // initialize tree offsets to 0:
256 m_nTrackTreeRecords.push_back( 0 );
257 }
258
259
260 // create tree for each given track particle collection and register it to THistSvc
261 std::vector<std::string>::const_iterator trackParticleColNameIter = m_inputTrackParticleCollection.begin();
262
263 for (; trackParticleColNameIter != m_inputTrackParticleCollection.end(); ++trackParticleColNameIter ) {
264 TTree* tree = new TTree((*trackParticleColNameIter).c_str(), ((*trackParticleColNameIter)+" Validation").c_str());
265 m_trees.push_back(tree);
266 std::string fullNtupleName = "/"+m_ntupleFileName+"/"+m_ntupleDirName+"/"+(*trackParticleColNameIter);
267 sc = tHistSvc->regTree(fullNtupleName, tree);
268 if (sc.isFailure()) {
269 msg(MSG::ERROR) << "Unable to register TTree : " << fullNtupleName << endmsg;
270 return sc;
271 }
272 // add the ntuple branches to this tree
273 sc = m_ValTrkParticleNtupleTool->addNtupleItems(tree);
274 if (sc.isFailure()) {
275 msg(MSG::ERROR) << "ValidationNtupleTool could not add its branches for tree " << fullNtupleName << endmsg;
276 return sc;
277 }
278
279 } //loop over m_inputTrackParticleCollection
280
281 for (unsigned int toolIndex = 0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex ) {
282 if( m_eventPropertyNtupleTools[toolIndex]->isTrackLinkTool( ) ) {
283 m_eventPropertyNtupleTools[toolIndex]->registerTrackCollections( m_inputTrackCollection,
284 m_doTruth );
285 } //if
286 else if(m_eventPropertyNtupleTools[toolIndex]->isTrkParticleLinkTool() ) // register just Trk::TrackParticleBase collection retrieved from SG
287 m_eventPropertyNtupleTools[toolIndex]->registerTrackCollections( m_inputTrackParticleCollection, m_doTruth );
288 } // for over m_eventPropertyNtupleTools
289
290 // ---------------------------
291 // add event-wise track tree with link to the information in the track-wise tree
293 m_eventLinkTree = new TTree("EventToTrackLink", "Event to track entry link");
294 std::string fullNtupleName = "/"+m_ntupleFileName+"/"+m_ntupleDirName+"/EventToTrackLink";
295 sc = tHistSvc->regTree(fullNtupleName, m_eventLinkTree);
296 if (sc.isFailure()) {
297 msg(MSG::ERROR) << "Unable to register TTree : " << fullNtupleName << endmsg;
298 return sc;
299 }
300
301 for (unsigned int toolIndex=0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex ) {
302 if( m_eventPropertyNtupleTools[toolIndex]->isTrkParticleLinkTool() ||
303 m_eventPropertyNtupleTools[toolIndex]->isTrackLinkTool( ) ||
304 m_eventPropertyNtupleTools[toolIndex]->isEvtPropertyTool( ) ) {
305 if( m_eventPropertyNtupleTools[toolIndex]->addNtupleItems( m_eventLinkTree ).isFailure() )
306 {
307 msg(MSG::ERROR) << "Unable to add items into the event tree: " << m_eventLinkTree->GetTitle() << endmsg;
308 return StatusCode::SUCCESS;
309 } // if addNtupleItems isFailure
310 } // if Track or TrackParticle
311 } //loop over m_eventPropertyNtupleTools
312 } // if not use external link tree
313 return StatusCode::SUCCESS;
314}
315
316
317
319
320// std::cout<< "TrackValidationNtupleWriter execute() start" <<std::endl;
321
322 ATH_MSG_DEBUG ("TrackValidationNtupleWriter execute() start");
323
324 StatusCode sc = StatusCode::SUCCESS; if (sc.isFailure()) { /* mute sc*/ }
325 for (unsigned int toolIndex = 0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex ) {
326 if (m_eventPropertyNtupleTools[toolIndex]->resetVariables( ).isFailure()){};
327 }
328
329 const McEventCollection* mcEventColl = nullptr;
330
331 unsigned int nTruthTreeRecordsAtCurrentEvent = 0;
332 std::vector<Trk::ValidationTrackTruthData> truthData;
333 std::vector<HepMC::ConstGenParticlePtr>* selecParticles = nullptr;
334 //std::vector<const Trk::TrackParameters*> extrapolatedTruthPerigees;
335 //std::vector<std::vector<unsigned int> > classifications;
336 std::vector< Trk::GenParticleJet >* genParticleJets = nullptr;
337 //std::map<HepMC::GenParticle*, unsigned int> particleToIndexMap;
338 if (m_doTruth)
339 {
340 // retrieve gen event collection
341 if (evtStore()->retrieve(mcEventColl, m_McEventCollectionName).isFailure())
342 {
343 std::string key = "G4Truth";
344 if (evtStore()->retrieve(mcEventColl, key).isFailure())
345 {
346 msg(MSG::WARNING) << "Could not find the McEventCollection" << endmsg;
347 return StatusCode::SUCCESS;
348 }
349 }
350
351// std::cout<<"collecton retrieved "<<std::endl;
352
353 // select stable, charged particles
354 selecParticles = m_genPartSelector->selectGenSignal(mcEventColl);
355 if (selecParticles)
356 {
357// std::cout<<"there are selected particles "<<std::endl;
358
359 // init the classification:
360 //classifications.resize(selecParticles->size());
361 //truthData.classifications.resize(selecParticles->size());
362 //truthData.truthPerigee.resize(selecParticles->size());
363 for (unsigned int toolIndex = 0 ; toolIndex < m_trackTruthClassifiers.size(); ++toolIndex )
364 {
365 m_trackTruthClassifiers[toolIndex]->initClassification(*mcEventColl, selecParticles);
366 }
367
368 for ( const auto& genParticle: *selecParticles)
369 {
370 //truthData.genParticle = (*selecParticles);
372 partData.genParticle = genParticle;
373 // Perform extrapolation to generate perigee parameters
374 const Trk::TrackParameters* generatedTrackPerigee(nullptr);
375 if ( genParticle->production_vertex() )
376 {
377 generatedTrackPerigee = m_truthToTrack->makePerigeeParameters( genParticle );
378 if (generatedTrackPerigee == nullptr && HepMC::generations(genParticle) > 0 ) {
379 ATH_MSG_DEBUG ("No perigee available for interacting truth particle."
380 <<" -> This is OK for particles from the TrackRecord, but probably"
381 <<" a bug for production vertex particles.");
382 }
383
384 }
385 partData.truthPerigee = generatedTrackPerigee;
386 // get classification
387 partData.classifications.reserve(m_trackTruthClassifiers.size());
388 for (unsigned int toolIndex = 0 ; toolIndex < m_trackTruthClassifiers.size(); ++toolIndex )
389 {
390 partData.classifications.push_back(m_trackTruthClassifiers[toolIndex]->classify(genParticle));
391 }
392 // resize the truth to track vectors to the number of input track collections:
393 partData.truthToTrackIndices.resize(m_inputTrackCollection.size());
395 truthData.push_back(partData);
396 //partIndex++;
397 }
398
399// std::cout<<"Second loop done "<<std::endl;
400
401 if (! m_jetTruthNtupleTool.empty()) {
402
403// std::cout<<"Second loop done "<<std::endl;
404 genParticleJets = m_genJetFinder->jetMCFinder(*selecParticles);
405 if (!genParticleJets) ATH_MSG_DEBUG ("no jets found!");
406 else ATH_MSG_DEBUG ("jets found: " << genParticleJets->size());
407 }
408// std::cout<<" end of jet truth tool check"<<std::endl;
409
410 } // end if (selecParticles)
411 nTruthTreeRecordsAtCurrentEvent = m_truthNtupleTool->getNumberOfTreeRecords();
412 } // end if(m_doTruth)
413
414// std::cout<<"Finished working with truth part"<<std::endl;
415
416 // get vertex collection so that the track selector is able to make a correct d0, z0 cut
417 const VxContainer* primaryVertexContainer = nullptr;
418 if (!m_trackSelector.empty() && !m_inputPrimaryVertexCollection.empty()) {
419 sc = evtStore()->retrieve(primaryVertexContainer, m_inputPrimaryVertexCollection);
420 if ( !primaryVertexContainer || sc.isFailure() ) {
421 ATH_MSG_ERROR( " Primary Vertex container (" << m_inputPrimaryVertexCollection << ") not found in StoreGate" );
422 delete genParticleJets;
423 return StatusCode::FAILURE;
424 }
425 }
426 const Trk::Vertex* vertex = nullptr;
427 if (primaryVertexContainer) {
428 if (!primaryVertexContainer->empty()) vertex = &((*primaryVertexContainer)[0]->recVertex());
429 }
430
431 // fill the track trees for each track collection
432 for (unsigned int trackColIndex = 0; trackColIndex<m_inputTrackCollection.size(); trackColIndex++)
433 {
434 sc = writeTrackData(trackColIndex, truthData, vertex);
435 if (sc.isFailure()) {
436 ATH_MSG_ERROR ("Failure when writing track data for collection " << m_inputTrackCollection[trackColIndex]);
437 delete genParticleJets;
438 return sc;
439 }
440 }
441
442 // fill track particle data
444 for (unsigned int trackParticleColIndex = 0; trackParticleColIndex<m_inputTrackParticleCollection.size(); trackParticleColIndex++)
445 {
446 sc = writeTrackParticleData(trackParticleColIndex);
447 if (sc.isFailure()) {
448 msg(MSG::ERROR) <<"Failure when writing TrackParticle data for collection " << m_inputTrackParticleCollection[trackParticleColIndex] << endmsg;
449 delete genParticleJets;
450 return sc;
451 }
452 }
453}
454 if (m_doTruth) {
455 for (unsigned int toolIndex = 0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex )
456 if( m_eventPropertyNtupleTools[toolIndex]->isTrackLinkTool() ) {
457 m_eventPropertyNtupleTools[toolIndex]->setGenParticleTreeIndices
458 (nTruthTreeRecordsAtCurrentEvent,
459 selecParticles ? (int)selecParticles->size() : 0);
460 }
461 }
462
463 // fill info about whole event
464 for (unsigned int toolIndex = 0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex ) {
465 sc = m_eventPropertyNtupleTools[toolIndex]->fillEventData( );
466 if (sc.isFailure()) {
467 msg(MSG::ERROR) <<"Failure when filling event data." << endmsg;
468 delete genParticleJets;
469 return sc;
470 }
471 }
472
474
475 // fill info about jets
476 std::vector<unsigned int> truthToJetIndices(selecParticles ? selecParticles->size() : 0);
477 if (m_doTruth && selecParticles && genParticleJets && !m_jetTruthNtupleTool.empty() ) {
478
479 const unsigned int nJetTruthTreeRecordsAtCurrentEvent
480 = m_jetTruthNtupleTool->getNumberOfTreeRecords();
481
482 for( std::vector<Trk::GenParticleJet>::iterator itrMcJet = genParticleJets->begin();
483 itrMcJet < genParticleJets->end() ; ++itrMcJet) {
484
485 std::vector<int> indices = (*itrMcJet).getIndicesInEvent();
486 if (!indices.empty())
487 for (std::vector<int>::const_iterator k =indices.begin(); k != indices.end(); ++k) {
488 if (*k >= 0 && *k <= (int)selecParticles->size() ) {
489 truthData[*k].truthToJetIndex = nJetTruthTreeRecordsAtCurrentEvent
490 + int(itrMcJet - genParticleJets->begin()) + 1;
491 } else {
492 msg(MSG::WARNING) <<" mistake with jet::indexInEvent !! " << *k << endmsg;
493 }
494 }
495 }
496 sc = m_jetTruthNtupleTool->writeJetTruthData(*genParticleJets,
497 nTruthTreeRecordsAtCurrentEvent);
498 if ( sc.isFailure() ){
499 msg(MSG::ERROR) << "Jet Truth Ntuple Tool could not fill data" << endmsg;
500 delete genParticleJets;
501 return StatusCode::FAILURE;
502 }
503 }
504
505
506 if (m_doTruth && selecParticles){
507 sc = m_truthNtupleTool->writeTruthData( truthData );
508 if ( sc.isFailure() ){
509 msg(MSG::ERROR) << "Truth Ntuple Tool could not fill data" << endmsg;
510 delete genParticleJets;
511 return StatusCode::FAILURE;
512 }
513 } // end if (m_doTruth && selecParticles)
514
515 delete selecParticles;
516 delete genParticleJets;
517 std::vector<Trk::ValidationTrackTruthData>::iterator truthDataIter = truthData.begin();
518 for (; truthDataIter != truthData.end(); ++truthDataIter) {
519 delete (*truthDataIter).truthPerigee;
520 (*truthDataIter).truthPerigee = nullptr;
521 }
522 return StatusCode::SUCCESS;
523}
524
525StatusCode Trk::TrackValidationNtupleWriter::writeTrackData(unsigned int trackColIndex,
526 std::vector<Trk::ValidationTrackTruthData>& truthData,
527 const Trk::Vertex* primaryVertex ) {
528 StatusCode sc = StatusCode::SUCCESS; if (sc.isFailure()) { /* mute sc*/ }
529 // retrieve reconstructed tracks
530 const TrackCollection* tracks = nullptr;
531 if (!m_inputTrackCollection[trackColIndex].empty() && evtStore()->contains<TrackCollection>(m_inputTrackCollection[trackColIndex])) {
532 sc = evtStore()->retrieve(tracks, m_inputTrackCollection[trackColIndex]);
533 if (sc.isFailure()) {
534 msg(MSG::WARNING) <<"Tracks not found: " << m_inputTrackCollection[trackColIndex] << endmsg;
535 return StatusCode::SUCCESS;
536 } else {
537 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) <<"Tracks found: " << m_inputTrackCollection[trackColIndex] <<endmsg;
538 }
539 } else {
540 msg(MSG::WARNING) <<"TrackCollection " << m_inputTrackCollection[trackColIndex] << " not found in StoreGate." << endmsg;
541 return StatusCode::SUCCESS;
542 }
543
544 const TrackTruthCollection* trackTruthCollection = nullptr;
545 if (m_doTruth) {
546 // retrieve track truth collection
548 sc = evtStore()->retrieve(trackTruthCollection, m_trackTruthCollectionName[trackColIndex]);
549 if (sc.isFailure()) {
550 msg(MSG::WARNING) <<"TrackTruthCollection not found: " << m_trackTruthCollectionName[trackColIndex] << endmsg;
551 // FIXME: return is not good here...
552 return StatusCode::SUCCESS;
553 } else {
554 ATH_MSG_DEBUG ("TrackTruthColl found: " << m_trackTruthCollectionName[trackColIndex]);
555 // TODO: use trackTruthCollection.trackCollectionLink() to check whether consistent track collection was used
556 }
557 } else {
558 msg(MSG::WARNING) <<"TrackTruthCollection " << m_trackTruthCollectionName[trackColIndex] << " not found in StoreGate." << endmsg;
559 // FIXME: return is not good here...
560 return StatusCode::SUCCESS;
561 }
562 } // end if m_doTruth
563
564 const unsigned int nTruthTreeRecordsAtCurrentEvent =
565 (m_doTruth ? m_truthNtupleTool->getNumberOfTreeRecords() : 0 );
566
567 int trackTreeIndexBegin = m_trees[trackColIndex]->GetEntries();
568 int nTracksPerEvent = 0;
569
570 // loop over tracks
571 TrackCollection::const_iterator trackIterator = (*tracks).begin();
572 for ( ; trackIterator < (*tracks).end(); ++trackIterator) {
573 if (!((*trackIterator))) {
574 msg(MSG::WARNING) <<"TrackCollection " << m_inputTrackCollection[trackColIndex] << "contains empty entries" << endmsg;
575 continue;
576 }
577 if (m_trackSelector.empty() || m_trackSelector->decision(*(*trackIterator), primaryVertex)) {
578 ATH_MSG_VERBOSE ("track selected!");
579 ToolHandleArray< Trk::ITrackValidationNtupleTool >::iterator itTools;
580 itTools = m_ValidationNtupleTools.begin();
581 for ( ; itTools != m_ValidationNtupleTools.end(); ++itTools ) {
582 if (((*itTools)->fillTrackData( *(*trackIterator), 0 )).isFailure()) {
583 ATH_MSG_ERROR ("Validation Ntuple Tool could not fill track data.");
584 return StatusCode::FAILURE;
585 }
586 }
587 nTracksPerEvent += 1;
588
589 if (m_doTruth){
590 // find matching truth particle
591 const TrackTruth* trackTruth = nullptr;
592 HepMC::ConstGenParticlePtr genParticle{nullptr};
593 TrackTruthCollection::const_iterator truthIterator = trackTruthCollection->find( trackIterator - (*tracks).begin() );
594 if ( truthIterator == trackTruthCollection->end() ){
595 ATH_MSG_DEBUG ("No matching truth particle found for track");
596 } else {
597 trackTruth = &((*truthIterator).second);
598 if ( !(trackTruth->particleLink().isValid()) ) {
599 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Link to generated particle information is not there - assuming a lost G4 particle ('fake fake')." << endmsg;
600 genParticle = m_visibleParticleWithoutTruth; // with pdg_id 0
601 } else {
602#ifdef HEPMC3
603 genParticle = trackTruth->particleLink().scptr();
604#else
605 genParticle = trackTruth->particleLink().cptr();
606#endif
607 if ( genParticle!=nullptr && genParticle->pdg_id() == 0 ) {
608 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Associated Particle ID " << genParticle->pdg_id()
609 << " does not conform to PDG requirements... ignore it!" << endmsg;
610 genParticle = nullptr;
611 }
612 }
613 }
614 if (genParticle) {
615 ATH_MSG_VERBOSE("Associated Particle ID: " << genParticle->pdg_id());
616 // Perform extrapolation to generate perigee parameters
617 const Trk::TrackParameters* generatedTrackPerigee(nullptr);
618 const Trk::TrackParameters* newTrackPerigee(nullptr);
619 // fill the truth data in the track tree
620 int truthIndex = -1;
621 // TODO: do the search somehow better:
622 std::vector<Trk::ValidationTrackTruthData>::iterator matchedPartIter = truthData.begin();
623 for (; matchedPartIter != truthData.end(); ++matchedPartIter) {
624 truthIndex++;
625 if ((*matchedPartIter).genParticle == genParticle) break;
626 }
627 if (matchedPartIter == truthData.end()) {
628 // did not find particle in list of selected particles
629 truthIndex = -1;
630 if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Matched particle " << genParticle << " is not in list of selected particles" << endmsg;
631 if ( genParticle->production_vertex() ) {
632 newTrackPerigee = m_truthToTrack->makePerigeeParameters( genParticle );
633 generatedTrackPerigee = newTrackPerigee;
634 }
635 } else {
636 // store the index in the track tree of the current track (establish link from truth to track)
637 (*matchedPartIter).truthToTrackIndices[trackColIndex].push_back(m_nTrackTreeRecords[trackColIndex]);
638 (*matchedPartIter).truthToTrackMatchingProbabilities[trackColIndex].push_back(trackTruth->probability());
639 generatedTrackPerigee = (*matchedPartIter).truthPerigee;
640 // calculate entry index in tree:
641 truthIndex += nTruthTreeRecordsAtCurrentEvent;
642 }
643 ToolHandleArray< Trk::ITrackValidationNtupleTool >::iterator itTools;
644 itTools = m_ValidationNtupleTools.begin();
645 for ( ; itTools != m_ValidationNtupleTools.end(); ++itTools ) {
646 if (((*itTools)->fillTrackTruthData( generatedTrackPerigee, *trackTruth, truthIndex )).isFailure()) {
647 ATH_MSG_ERROR ("Validation Ntuple Tool could not fill track truth data.");
648 delete newTrackPerigee;
649 return StatusCode::FAILURE;
650 }
651 }
652 // New memory allocated for the true perigee - must be deleted
653 delete newTrackPerigee;
654
655 } // end if (genParticle)
656 } // end if (m_doTruth)
657
658 m_trees[trackColIndex]->Fill();
659 itTools = m_ValidationNtupleTools.begin();
660 for ( ; itTools != m_ValidationNtupleTools.end(); ++itTools )
661 (*itTools)->resetVariables();
662 // call getEntries - 1, push_back in index vektor
663
664 m_nTrackTreeRecords[trackColIndex]++;
665 } else {
666 if (msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) <<"track not selected!" <<endmsg;
667 }
668 } // end for (trackIterator)
669
670 for (unsigned int toolIndex = 0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex )
671 if( m_eventPropertyNtupleTools[toolIndex]->isTrackLinkTool() ) m_eventPropertyNtupleTools[toolIndex]->setTrackTreeIndices
672 (trackColIndex, trackTreeIndexBegin, nTracksPerEvent );
673
674 return StatusCode::SUCCESS;
675}
676
677StatusCode Trk::TrackValidationNtupleWriter::writeTrackParticleData(unsigned int trackParticleColIndex ) {
678
679 msg(MSG::DEBUG) << "writeTrackParticleData method started" << endmsg;
680
681 // retrieve Trk::TrackParticleBaseCollection from the SG
682 const Trk::TrackParticleBaseCollection* trackParticles = nullptr;
683
684 if (!m_inputTrackParticleCollection[trackParticleColIndex].empty() &&
686 if (evtStore()->retrieve(trackParticles, m_inputTrackParticleCollection[trackParticleColIndex]).isFailure()) {
687 msg(MSG::WARNING) <<"Trk::TrackParticleBasesContainer not found:" << m_inputTrackParticleCollection[trackParticleColIndex] << endmsg;
688 return StatusCode::SUCCESS;
689 } else {
690 if (msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) <<"Trk::TrackParticleBasesContainer found: "<< m_inputTrackParticleCollection[trackParticleColIndex] <<endmsg;
691 }
692 } else {
693 msg(MSG::WARNING) <<"Trk::TrackParticleBasesContainer " << m_inputTrackParticleCollection[trackParticleColIndex] << " not found in StoreGate." << endmsg;
694 return StatusCode::SUCCESS;
695 }
696
697 // indexes for eventPropertyNtupleTool
698 int trackTreeIndexBegin = m_trees[trackParticleColIndex + m_inputTrackCollection.size()]->GetEntries();
699 int nTrkParticlesPerEvent = 0;
700
701 // fill coresponding Rec:TrackParticle tree using BasicTrkParticleValidationNtuple
702 Trk::TrackParticleBaseCollection::const_iterator trackParticleIterator = (*trackParticles).begin();
703 for ( ; trackParticleIterator < (*trackParticles).end(); ++trackParticleIterator) {
704 if (!((*trackParticleIterator))) {
705 msg(MSG::WARNING) <<"TrackParticleCollection " << m_inputTrackParticleCollection[trackParticleColIndex] << "contains empty entries" << endmsg;
706 continue;
707 } // if emty entry
708
709 if ( m_ValTrkParticleNtupleTool->fillTrackParticleData( *(*trackParticleIterator) ).isFailure() ){
710 msg(MSG::ERROR) << "Validation Ntuple Tool could not fill track data." << endmsg;
711 return StatusCode::FAILURE;
712 } // if StatusCode is FAILURE
713 nTrkParticlesPerEvent += 1;
714
715 if ( m_ValTrkParticleNtupleTool->writeRecord(m_trees[trackParticleColIndex + m_inputTrackCollection.size()]).isFailure() ){
716 msg(MSG::ERROR) << "Validation Ntuple Tool could not write track data." << endmsg;
717 return StatusCode::FAILURE;
718 }
719 } // loop over Rec::TrackPartcielContainer
720
721 // Record link between Event Property and Trk::TrackParticleBase information
722 for (unsigned int toolIndex = 0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex ){
723 if( m_eventPropertyNtupleTools[toolIndex]->isTrkParticleLinkTool() )
724 m_eventPropertyNtupleTools[toolIndex]->setTrackTreeIndices(trackParticleColIndex, trackTreeIndexBegin, nTrkParticlesPerEvent );
725 }
726
727 msg(MSG::DEBUG) <<"writeTrackParticleData successfully finished " << endmsg;
728 return StatusCode::SUCCESS;
729}
730
731
733
734 msg(MSG::INFO) << "TrackValidationNtupleWriter finalize()" << endmsg;
735
736#ifdef HEPMC3
737 //This is smart pointer in HepMC3
738#else
740#endif
741 for (unsigned int toolIndex = 0 ; toolIndex < m_eventPropertyNtupleTools.size(); ++toolIndex ){
742 if (m_eventPropertyNtupleTools[toolIndex]->resetVariables( ).isFailure()){};
743 }
744
745 return StatusCode::SUCCESS;
746}
747
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
Extrapolation for HepMC particles.
static Double_t sc
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
static const Attributes_t empty
AthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
bool empty() const noexcept
Returns true if the collection is empty.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
MC particle associated with a reco track + the quality of match.
Definition TrackTruth.h:14
float probability() const
Definition TrackTruth.h:28
const HepMcParticleLink & particleLink() const
Definition TrackTruth.h:26
std::vector< std::string > m_inputTrackCollection
name of the TrackCollection
bool m_useExternalEventLinkTree
if TVNW should make event tree itself or assume CBNT does
StatusCode writeTrackParticleData(unsigned int trackParticleColIndex)
method to write track particle data to Ntuple.
std::string m_ntupleDirName
jobOption: Ntuple directory name
StatusCode initialize()
standard Athena-Algorithm method
std::vector< unsigned int > m_nTrackTreeRecords
ToolHandle< Trk::IGenParticleSelector > m_genPartSelector
Tool handle to the Trk::IGenParticleSelector.
StatusCode finalize()
standard Athena-Algorithm method
std::vector< TTree * > m_trees
Pointer to the NTuple trees (one for each input track collection)
ToolHandleArray< Trk::ITrackValidationNtupleTool > m_ValidationNtupleTools
set of tools for writing Trk::Track into the Ntuple
std::string m_inputPrimaryVertexCollection
SG key of the input primary vertex collection (used by the track selector)
StatusCode execute()
standard Athena-Algorithm method
TTree * m_eventLinkTree
pointer to event-wise ntuple trees (one for all input track collections + truth)
bool m_doTruth
Switch to turn on / off truth.
StatusCode writeTrackData(unsigned int trackColIndex, std::vector< Trk::ValidationTrackTruthData > &truthData, const Trk::Vertex *primaryVertex=NULL)
< following methods and atributes are used in derived class TrigTrackValidationNtupleWriter Private m...
ToolHandleArray< Trk::ITrackTruthClassifier > m_trackTruthClassifierHandles
jobO: list of truth classifiers
ToolHandle< Trk::ITrackSelectorTool > m_trackSelector
Tool handle to the Trk::ITrackSelectorTool.
ToolHandle< Trk::IValidationNtupleTool > m_ValTrkParticleNtupleTool
Tool for writting Rec::TrackParticle into the Ntuple – OBSOLETE.
std::string m_McEventCollectionName
name of the McEventCollection
std::vector< const Trk::ITrackTruthClassifier * > m_trackTruthClassifiers
the truth classifiers
ToolHandle< Trk::ITruthNtupleTool > m_truthNtupleTool
ToolHandle< Trk::IJetTruthNtupleTool > m_jetTruthNtupleTool
std::vector< Trk::IEventPropertyNtupleTool * > m_eventPropertyNtupleTools
list of event property tools
ToolHandleArray< Trk::IEventPropertyNtupleTool > m_eventPropertyNtupleHandles
jobO: list of event property tools
ToolHandle< Trk::ITruthToTrack > m_truthToTrack
Tool handle to the Trk::TruthToTrack tool.
std::string m_ntupleFileName
jobOption: Ntuple file name
std::vector< std::string > m_trackTruthCollectionName
name of the TrackTruthCollection
~TrackValidationNtupleWriter()
Default Destructor.
HepMC::GenParticlePtr m_visibleParticleWithoutTruth
Switch to turn on/pff recording track particle trees into Ntuple.
std::vector< std::string > m_inputTrackParticleCollection
name of the TrackParticleCollection
ToolHandle< Trk::IGenParticleJetFinder > m_genJetFinder
Tool to find jets.
TrackValidationNtupleWriter(const std::string &name, ISvcLocator *pSvcLocator)
Standard Athena-Algorithm Constructor.
const Trk::TrackParameters * truthPerigee
std::vector< std::vector< unsigned int > > truthToTrackIndices
std::vector< unsigned int > classifications
HepMC::ConstGenParticlePtr genParticle
std::vector< std::vector< float > > truthToTrackMatchingProbabilities
This class is a simplest representation of a vertex candidate.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
GenParticlePtr newGenParticlePtr(const HepMC::FourVector &mom=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), int pid=0, int status=0)
Definition GenParticle.h:39
int generations(const T &p)
Method to return how many interactions a particle has undergone during simulation (TODO migrate to be...
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
DataVector< TrackParticleBase > TrackParticleBaseCollection
std::pair< long int, long int > indices
ParametersBase< TrackParametersDim, Charged > TrackParameters
MsgStream & msg
Definition testRead.cxx:32
TChain * tree