ATLAS Offline Software
Loading...
Searching...
No Matches
InDetPhysValMonitoringTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
9
10#include "GaudiKernel/SystemOfUnits.h"
11
14#include "InDetRttPlots.h"
17#include "CachedGetAssocTruth.h"
18
19#include "safeDecorator.h"
20//
31
33//
34#include <algorithm>
35#include <limits>
36#include <cmath> // to get std::isnan(), std::abs etc.
37// #include <functional> // to get std::plus
38#include <utility>
39#include <cstdlib> // to getenv
40#include <vector>
41
43
44namespace { // utility functions used here
45
46 // get truth/track matching probability
47 float
48 getMatchingProbability(const xAOD::TrackParticle& trackParticle) {
49 float result(std::numeric_limits<float>::quiet_NaN());
50
51 static const SG::ConstAccessor<float> truthMatchProbabilityAcc("truthMatchProbability");
52 if (truthMatchProbabilityAcc.isAvailable(trackParticle)) {
53 result = truthMatchProbabilityAcc(trackParticle);
54 }
55 return result;
56 }
57
58 template <class T>
59 inline float
60 safelyGetEta(const T& pTrk, const float safePtThreshold = 0.1) {
61 return (pTrk->pt() > safePtThreshold) ? (pTrk->eta()) : std::nan("");
62 }
63
64 // general utility function to check value is in range
65 template <class T>
66 inline bool
67 inRange(const T& value, const T& minVal, const T& maxVal) {
68 return not ((value < minVal)or(value > maxVal));
69 }
70
71 template<class T>
72 inline bool
73 inRange(const T& value, const T& absoluteMax) {
74 return not (std::abs(value) > absoluteMax);
75 }
76
77 // Cuts on various objects
78
79 // general utility function to return bin index given a value and the upper endpoints of each bin
80 template <class T>
81 unsigned int
82 binIndex(const T& val, const std::vector<T>& partitions) {// signature should allow other containers
83 unsigned int i(0);
84 bool nf = true;
85
86 while (nf and i != partitions.size()) {
87 nf = (val > partitions[i++]);
88 }
89 return nf ? i : i - 1;
90 }
91
92 bool
93 acceptTruthVertex(const xAOD::TruthVertex* vtx) {
94 const float x(vtx->x()), y(vtx->y()), z(vtx->z());
95 const float vrtR2 = (x * x + y * y); // radial distance squared
96
97 return inRange(z, 500.f) and not (vrtR2 > 1); // units?
98 }
99
100 const std::vector<float> ETA_PARTITIONS = {
101 2.7, 3.5, std::numeric_limits<float>::infinity()
102 };
103
104}// namespace
105
107InDetPhysValMonitoringTool::InDetPhysValMonitoringTool(const std::string& type, const std::string& name,
108 const IInterface* parent) :
109 ManagedMonitorToolBase(type, name, parent){
110}
111
113
114StatusCode
117 // Get the track selector tool only if m_useTrackSelection is true;
118 // first check for consistency i.e. that there is a trackSelectionTool if you ask
119 // for trackSelection
120 ATH_CHECK(m_trackSelectionTool.retrieve(EnableTool {m_useTrackSelection} ));
121 ATH_CHECK(m_truthSelectionTool.retrieve(EnableTool {not m_truthParticleName.key().empty()} ));
122 ATH_CHECK(m_vtxValidTool.retrieve(EnableTool {m_useVertexTruthMatchTool}));
123 ATH_CHECK(m_trackTruthOriginTool.retrieve( EnableTool {m_doTruthOriginPlots} ));
124
125 ATH_CHECK(m_hardScatterSelectionTool.retrieve(EnableTool
126 {not m_vertexContainerName.key().empty() &&
127 not m_hardScatterSelectionTool.empty()}));
128
129 ATH_CHECK(m_grlTool.retrieve(EnableTool{m_useGRL}));
130
131 ATH_MSG_DEBUG("m_useVertexTruthMatchTool ====== " <<m_useVertexTruthMatchTool);
132 if (m_truthSelectionTool.get() ) {
133 m_truthCutFlow = CutFlow(m_truthSelectionTool->nCuts());
134 }
135
136 m_monPlots = std::make_unique<InDetRttPlots>
137 (nullptr, static_cast<std::string>(m_dirName) + static_cast<std::string>(m_folder),
138 getFilledPlotConfig()); // m_detailLevel := DEBUG, enable expert histograms
139
140 ATH_CHECK( m_trkParticleName.initialize() );
141 ATH_CHECK( m_truthParticleName.initialize( (m_pileupSwitch == "HardScatter" or m_pileupSwitch == "All") and not m_truthParticleName.key().empty() ) );
142 if (not m_truthParticleName.key().empty()) {
143 // create decor handle keys for truth particle decorations which are needed by CachedGetAssocTruth
144 // The existence of the handles is good enough to ensure that data dependencies are propagated
145 // and that the decorations exist when this tool is being called. Albeit not very elegant
146 // there is no need to create decor handles for the keys and use those instead of static
147 // accessors. To keep changes minimal the original static accessors are not replaced.
148 std::vector<std::string> trk_decorations;
152 "" /* no configurable prefix*/,
153 trk_decorations,
155 }
156 ATH_CHECK( m_vertexContainerName.initialize( not m_vertexContainerName.empty() ) );
157 ATH_CHECK( m_truthVertexContainerName.initialize( not m_truthVertexContainerName.key().empty() ) );
158 ATH_CHECK( m_eventInfoContainerName.initialize() );
159
160 ATH_CHECK( m_truthEventName.initialize( (m_pileupSwitch == "HardScatter" or m_pileupSwitch == "All") and not m_truthEventName.key().empty() ) );
161 ATH_CHECK( m_truthPileUpEventName.initialize( (m_pileupSwitch == "PileUp" or m_pileupSwitch == "All") and not m_truthPileUpEventName.key().empty() ) );
162 ATH_CHECK( m_jetContainerName.initialize( m_doTrackInJetPlots and not m_jetContainerName.key().empty()) );
163
164 std::vector<std::string> required_float_track_decorations {"d0","hitResiduals_residualLocX","d0err"};
165 std::vector<std::string> required_int_track_decorations {};
166 std::vector<std::string> required_float_truth_decorations {"d0"};
167 std::vector<std::string> required_int_truth_decorations {};
168 std::vector<std::string> required_int_jet_decorations {"HadronConeExclTruthLabelID"};
169 // The CSV file is for storing event data related to track overlay ML training purposes.
170 if (!m_setCSVName.empty()) {
172 ATH_MSG_INFO("Accessing csv file with name " <<m_setCSVName<< "...");
173 m_datfile <<"EvtNumber,PdgID,Px,Py,Pz,E,Pt,Eta,Phi,Mass,numPU,numvtx,MatchProb"<<std::endl;
174 }
175 std::string empty_prefix;
176 IDPVM::addReadDecoratorHandleKeys(*this, m_trkParticleName, empty_prefix, required_float_track_decorations, m_floatTrkDecor);
177 IDPVM::addReadDecoratorHandleKeys(*this, m_trkParticleName, empty_prefix, required_int_truth_decorations, m_intTrkDecor);
178 if (!m_truthParticleName.key().empty()) {
179 IDPVM::addReadDecoratorHandleKeys(*this, m_truthParticleName, empty_prefix, required_float_truth_decorations, m_floatTruthDecor);
180 IDPVM::addReadDecoratorHandleKeys(*this, m_truthParticleName, empty_prefix, required_int_truth_decorations, m_intTruthDecor);
181 }
183 IDPVM::addReadDecoratorHandleKeys(*this, m_jetContainerName, empty_prefix, required_int_jet_decorations, m_intJetDecor);
184 }
185
187
189 return StatusCode::SUCCESS;
190}
191
192
194
195
196 InDetRttPlotConfig rttConfig;
197 rttConfig.detailLevel = m_detailLevel;
198
199 rttConfig.isITk = m_isITk;
200 rttConfig.hasHGTDReco = m_hasHGTDReco;
201
205
207 rttConfig.doHitEffPlot = m_doHitLevelPlots;
208
212
215
217
223
225
228
230 if (m_truthParticleName.key().empty()){
231 rttConfig.doFakePlots = false;
232 rttConfig.doHitsFakeTracksPlots = false;
233 rttConfig.doEffPlots = false;
234 rttConfig.doResolutionPlotPrim = false;
235 rttConfig.doResolutionPlotPrim_truthFromB = false;
236 rttConfig.doResolutionPlotSecd = false;
237 rttConfig.doHitsMatchedTracksPlots = false;
238 rttConfig.doVertexTruthMatchingPlots = false;
239 rttConfig.doHardScatterVertexTruthMatchingPlots = false;
240 rttConfig.doEfficienciesPerAuthor = false;
241 rttConfig.doFakesPerAuthor = false;
242 rttConfig.doResolutionsPerAuthor = false;
243 rttConfig.doNtupleTruthToReco = false;
244 rttConfig.doTrkInJetPlots_fake_bjets = false;
245 rttConfig.doTrkInJetPlots_matched_bjets = false;
246 rttConfig.doTrkInJetPlots_truthFromB = false;
247 rttConfig.doResolutionPlotPrim_truthFromB = false;
248 }
249
251 if (m_onlyFillMatched){
252 rttConfig.doTrackParameters = false;
253 rttConfig.doNTracks = false;
254 rttConfig.doHitResidualPlot = false;
255 rttConfig.doHitEffPlot = false;
256 rttConfig.doHitsRecoTracksPlots = false;
257 rttConfig.doTrtExtensionPlots = false;
258 rttConfig.doFakePlots = false;
259 rttConfig.doHitsFakeTracksPlots = false;
260 rttConfig.doVertexPlots = false;
261 rttConfig.doVerticesVsMuPlots = false;
262 rttConfig.doHardScatterVertexPlots = false;
263 rttConfig.doVertexTruthMatchingPlots = false;
265 rttConfig.doTrkInJetPlots = false;
266 rttConfig.doTrkInJetPlots_bjets = false;
267 rttConfig.doTrkInJetPlots_matched = false;
268 rttConfig.doTrkInJetPlots_matched_bjets = false;
269 rttConfig.doTrkInJetPlots_fake = false;
270 rttConfig.doTrkInJetPlots_fake_bjets = false;
271 rttConfig.doTrkInJetPlots_truthFromB = false;
272 }
273
274 // For IDTIDE derivation
275 // disable the vertex plots since no covariance from IDTIDE
276 if (m_doIDTIDEPlots){
277 rttConfig.doVertexPlots = false;
278 rttConfig.doVerticesVsMuPlots = false;
279 rttConfig.doHardScatterVertexPlots = false;
280 rttConfig.doVertexTruthMatchingPlots = false;
282 rttConfig.doTrkInJetPlots = true;
283 rttConfig.doTrkInJetPlots_bjets = true;
284 rttConfig.doTrkInJetPlots_matched = true;
285 rttConfig.doTrkInJetPlots_matched_bjets = true;
286 rttConfig.doTrkInJetPlots_fake = true;
287 rttConfig.doTrkInJetPlots_fake_bjets = true;
288 rttConfig.doTrkInJetPlots_truthFromB = true;
289 }
290
292 if (m_detailLevel < 200){
293 rttConfig.doResolutionPlotSecd = false;
294 rttConfig.doHitsMatchedTracksPlots = false;
295 rttConfig.doHitsFakeTracksPlots = false;
296 rttConfig.doVertexTruthMatchingPlots = false;
297 rttConfig.doFakesPerAuthor = false;
298 rttConfig.doTrackParametersPerAuthor = false;
299 rttConfig.doEfficienciesPerAuthor = false;
300 rttConfig.doResolutionsPerAuthor = false;
301 rttConfig.doTrkInJetPlots_matched = false;
302 rttConfig.doTrkInJetPlots_fake = false;
303 rttConfig.doTrkInJetPlots_matched_bjets = false;
304 rttConfig.doTrkInJetPlots_fake_bjets = false;
305 }
306
307 return rttConfig;
308}
309
310StatusCode
312 ATH_MSG_DEBUG("Filling hists " << name() << "...");
313 // function object could be used to retrieve truth: IDPVM::CachedGetAssocTruth getTruth;
314
315 // retrieve trackParticle container
317 if (not trackHandle.isValid()) {
318 ATH_MSG_ERROR("Invalid trackname = " << m_trkParticleName << "!");
319 return StatusCode::FAILURE;
320 }
321 const xAOD::TrackParticleContainer* tracks = trackHandle.cptr();
322
323 SG::ReadHandle<xAOD::TruthPileupEventContainer> truthPileupEventContainer;
324 if( not m_truthPileUpEventName.key().empty()) {
326 }
327
329 if (not pie.isValid()){
330 ATH_MSG_WARNING("Shouldn't happen - EventInfo is buggy, setting mu to 0");
331 }
332
333 // FIX-ME: I'm not sure if we should stop execution if EventInfo is not valid ...
334 // it is used after as if they assume it is valid
335 if (m_useGRL and pie.isValid() and !pie->eventType(xAOD::EventInfo::IS_SIMULATION)) {
336 if (!m_grlTool->passRunLB(*pie)) {
337 ATH_MSG_VERBOSE("GRL veto");
338 return StatusCode::SUCCESS;
339 }
340 }
341
342 std::vector<const xAOD::TruthParticle*> truthParticlesVec = getTruthParticles(ctx);
343
344 // Mark the truth particles in our vector as "selected".
345 // This is needed because we later access the truth matching via xAOD decorations, where we do not 'know' about membership to this vector.
347 const xAOD::EventInfo *eventInfo = nullptr;
348 ATH_CHECK (evtStore()->retrieve (eventInfo, "EventInfo"));
349 IDPVM::CachedGetAssocTruth getAsTruth; // only cache one way, track->truth, not truth->tracks
350
351 unsigned int truthMu = 0;
352 float actualMu = 0.;
353 if(not m_truthPileUpEventName.key().empty() and truthPileupEventContainer.isValid()){
354 truthMu = static_cast<int>( truthPileupEventContainer->size() );
355 }
356 if(pie.isValid()) actualMu = pie->actualInteractionsPerCrossing();
357
358 // This is questionable but kept for backward compatibility for now
359 float puEvents = truthMu>0 ? truthMu : actualMu;
360
361 const xAOD::Vertex* primaryvertex = nullptr;
362 unsigned int nVertices = 0;
363 float beamSpotWeight = 1;
364
365 if(not m_vertexContainerName.key().empty()){
366 ATH_MSG_DEBUG("Getting number of pu interactings per event");
367
368 ATH_MSG_DEBUG("Filling vertex plots");
370 ATH_CHECK(vertices.isValid());
371
372 nVertices = not vertices->empty() ? vertices->size() : 0;
373 beamSpotWeight = pie->beamSpotWeight();
374 ATH_MSG_DEBUG("beamSpotWeight is equal to " << beamSpotWeight);
375 if(m_doPRW){
376 float prwWeight = 1;
378 if(readDecorHandle.isAvailable()) prwWeight = readDecorHandle(*pie);
379 ATH_MSG_DEBUG("Applying pileup weight equal to " << prwWeight);
380 beamSpotWeight *= prwWeight;
381 }
382
383 if (vertices.isValid() and not vertices->empty()) {
384 ATH_MSG_DEBUG("Number of vertices retrieved for this event " << vertices->size());
385 //Find the HS vertex following the user-configured strategy
386 if (m_hardScatterSelectionTool.empty()) {
387 for (const auto& vertex : *vertices){
388 if(vertex->vertexType()==xAOD::VxType::PriVtx){
389 primaryvertex = vertex;
390 break;
391 }
392 }
393 } else {
394 primaryvertex = m_hardScatterSelectionTool->getHardScatter(vertices.get());
395 }
396
397 if (!primaryvertex){
400 ATH_MSG_DEBUG("Failed to find a hard scatter vertex in this event.");
401 }
402 //Filling plots for all reconstructed vertices and the hard-scatter
403 ATH_MSG_DEBUG("Filling vertices info monitoring plots");
404
405 // Fill vectors of truth HS and PU vertices
406 std::pair<std::vector<const xAOD::TruthVertex*>, std::vector<const xAOD::TruthVertex*>> truthVertices = getTruthVertices(ctx);
407 std::vector<const xAOD::TruthVertex*> truthHSVertices = truthVertices.first;
408 std::vector<const xAOD::TruthVertex*> truthPUVertices = truthVertices.second;
409
410 // Decorate vertices
412 ATH_CHECK(m_vtxValidTool->matchVertices(*vertices));
413 ATH_MSG_DEBUG("Hard scatter classification type: " << InDetVertexTruthMatchUtils::classifyHardScatter(*vertices) << ", vertex container size = " << vertices->size());
414 }
415 m_monPlots->fill(*vertices, primaryvertex, truthHSVertices, truthPUVertices, actualMu, beamSpotWeight);
416
417 ATH_MSG_DEBUG("Filling vertex/event info monitoring plots");
418 //Filling vertexing plots for the reconstructed hard-scatter as a function of mu
419 m_monPlots->fill(*vertices, truthMu, actualMu, beamSpotWeight);
420 } else {
421 //FIXME: Does this happen for single particles?
422 ATH_MSG_WARNING("Skipping vertexing plots.");
423 }
424 }
425
426 if( not m_truthVertexContainerName.key().empty()){
427 // get truth vertex container name - m_truthVertexContainerName
429
430 //
431 //Get the HS vertex position from the truthVertexContainer
432 //FIXME: Add plots w.r.t truth HS positions (vertexing plots)
433 //
434 const xAOD::TruthVertex* truthVertex = nullptr;
435 if (truthVrt.isValid()) {
436 const auto& stdVertexContainer = truthVrt->stdcont();
437 //First truth particle vertex?
438 auto findVtx = std::find_if(stdVertexContainer.rbegin(), stdVertexContainer.rend(), acceptTruthVertex);
439 truthVertex = (findVtx == stdVertexContainer.rend()) ? nullptr : *findVtx;
440 } else {
441 ATH_MSG_WARNING("Cannot open " << m_truthVertexContainerName.key() << " truth vertex container");
442 }
443 if (not truthVertex) ATH_MSG_INFO ("Truth vertex did not pass cuts");
444 }
445 //
446 //Counters for cutflow
447 //
448 unsigned int nSelectedTruthTracks(0), nSelectedRecoTracks(0), nSelectedMatchedTracks(0), nAssociatedTruth(0), nMissingAssociatedTruth(0), nTruths(0);
449
450 CutFlow tmp_truth_cutflow( m_truthSelectionTool.get() ? m_truthSelectionTool->nCuts() : 0 );
451
452 //
453 //Loop over all reconstructed tracks
454 //
455 // If writing ntuples, use a truth-to-track(s) cache to handle truth matching.
456 // Based on the assumption that multiple tracks can (albeit rarely) share the same truth association.
457 std::map<const xAOD::TruthParticle*, std::vector<const xAOD::TrackParticle*>> cacheTruthMatching {};
458 //
459 std::vector<const xAOD::TrackParticle*> selectedTracks {};
460 selectedTracks.reserve(tracks->size());
461 unsigned int nTrackTOT = 0;
462 unsigned int nTrackCentral = 0;
463 unsigned int nTrackPt1GeV = 0;
464 for (const auto *const thisTrack: *tracks) {
465 //FIXME: Why is this w.r.t the primary vertex?
466 const asg::AcceptData& accept = m_trackSelectionTool->accept(*thisTrack, primaryvertex);
467 if (m_useTrackSelection and not accept) continue;
468 fillTrackCutFlow(accept); //?? Is this equal???
469
470 selectedTracks.push_back(thisTrack);
471 //Number of selected reco tracks
472 nSelectedRecoTracks++;
473
474 //Fill plots for selected reco tracks, hits / perigee / ???
475 nTrackTOT++;
476 if (thisTrack->pt() >= (1 * Gaudi::Units::GeV))
477 nTrackPt1GeV++;
478 if (std::abs(thisTrack->eta()) < 2.5)
479 nTrackCentral++;
480 m_monPlots->fill(*thisTrack, beamSpotWeight);
481 m_monPlots->fill(*thisTrack, puEvents, nVertices, beamSpotWeight); //fill mu dependent plots
482 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
483 float prob = getMatchingProbability(*thisTrack);
484
485 // This is where the Fake, and Really Fake fillers need to go. Where would the really really fakes go?
486 if (associatedTruth) {
487 nAssociatedTruth++;
488
489 // if there is associated truth also a truth selection tool was retrieved.
492 //FIXME: What is this for???
493 tmp_truth_cutflow.update( passed.missingCuts() );
494 }
495
496 if ((not std::isnan(prob)) and (prob > m_lowProb) and passed and (not m_usingSpecialPileupSwitch or isSelectedByPileupSwitch(*associatedTruth)) ) {
497 nSelectedMatchedTracks++;
498 bool truthIsFromB = false;
499 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(associatedTruth, 5) ) {
500 truthIsFromB = true;
501 }
502 m_monPlots->fill(*thisTrack, *associatedTruth, truthIsFromB, puEvents, beamSpotWeight); // Make plots requiring matched truth
503 }
504 }
505
506 const bool isAssociatedTruth = associatedTruth != nullptr;
507 const bool isFake = not std::isnan(prob) ? (prob < m_lowProb) : true;
508
509 if(!isAssociatedTruth) nMissingAssociatedTruth++;
510 m_monPlots->fillFakeRate(*thisTrack, isFake, puEvents, beamSpotWeight);
511
513 // Decorate track particle with extra flags
514 decorateTrackParticle(*thisTrack, accept);
515
516 if (isAssociatedTruth) {
517 // Decorate truth particle with extra flags
518 decorateTruthParticle(*associatedTruth, m_truthSelectionTool->accept(associatedTruth));
519
520 // Cache truth-to-track associations
521 auto cachedAssoc = cacheTruthMatching.find(associatedTruth);
522 // Check if truth particle already present in cache
523 if (cachedAssoc == cacheTruthMatching.end()) {
524 // If not yet present, add truth-to-track association in cache
525 cacheTruthMatching[associatedTruth] = {thisTrack};
526 }
527 else {
528 // If already present, cache additional track associations (here multiple track particle can be linked to the same truth particle)
529 cachedAssoc->second.push_back(thisTrack);
530 }
531 }
533 // Fill track only entries with dummy truth values
534 m_monPlots->fillNtuple(*thisTrack, primaryvertex);
535 }
536 }
537 }
539 // Now fill all truth-to-track associations
540 // Involves some double-filling of truth particles in cases where multiple tracks share the same truth association,
541 // these duplicates can be filtered in the ntuple by selecting only the 'best matched' truth-associated track particles.
542 for (auto& cachedAssoc: cacheTruthMatching) {
543 const xAOD::TruthParticle* thisTruth = cachedAssoc.first;
544
545 // Decorate that this truth particle is being filled to prevent double counting in truth particle loop
546 m_dec_hasTruthFilled(*thisTruth) = true;
547
548 // Sort all associated tracks by truth match probability
549 std::sort(cachedAssoc.second.begin(), cachedAssoc.second.end(),
550 [](const xAOD::TrackParticle* t1, const xAOD::TrackParticle* t2) { return getMatchingProbability(*t1) > getMatchingProbability(*t2); }
551 );
552
554 // Fill all tracks associated to to this truth particle, also recording 'truth match ranking' as index in probability-sorted vector of matched tracks
555 for (int itrack = 0; itrack < (int) cachedAssoc.second.size(); itrack++) {
556 const xAOD::TrackParticle* thisTrack = cachedAssoc.second[itrack];
557
558 // Fill track entries with truth association
559 m_monPlots->fillNtuple(*thisTrack, *thisTruth, primaryvertex, itrack);
560 }
561 }
562 }
563 }
564
565 m_monPlots->fill(nTrackTOT, nTrackCentral, nTrackPt1GeV, truthMu, actualMu, nVertices, beamSpotWeight);
566
567 //FIXME: I don't get why... this is here
568 if (m_truthSelectionTool.get()) {
569 ATH_MSG_DEBUG( CutFlow(tmp_truth_cutflow).report(m_truthSelectionTool->names()) );
570 std::lock_guard<std::mutex> lock(m_mutex);
571 m_truthCutFlow.merge(std::move(tmp_truth_cutflow));
572 }
573
574 //
575 //TruthParticle loop to fill efficiencies
576 //
577 for (int itruth = 0; itruth < (int) truthParticlesVec.size(); itruth++) { // Outer loop over all truth particles
578 nTruths++;
579 const xAOD::TruthParticle* thisTruth = truthParticlesVec[itruth];
580
581 // if the vector of truth particles is not empty also a truthSelectionTool was retrieved
582 const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(thisTruth);
583 if (accept) {
584 ++nSelectedTruthTracks; // total number of truth which pass cuts per event
585 bool isEfficient(false); // weight for the trackeff histos
586 float matchingProbability{};
587 m_monPlots->fill(*thisTruth, beamSpotWeight); // This is filling truth-only plots
588
590 auto cachedAssoc = cacheTruthMatching.find(thisTruth);
591 // Check if truth particle already present in cache
592 if (cachedAssoc == cacheTruthMatching.end()) {
593 // If not yet present, then no track associated
594 cacheTruthMatching[thisTruth] = {};
595 }
596 m_monPlots->fillDuplicate(*thisTruth, cacheTruthMatching[thisTruth], beamSpotWeight);
597 }
598
599 //
600 //Loop over reco tracks to find the match
601 //
602 const xAOD::TrackParticle* matchedTrack = nullptr;
603 for (const auto& thisTrack: selectedTracks) { // Inner loop over selected track particleis
604 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
605 if (associatedTruth && associatedTruth == thisTruth) {
606 float prob = getMatchingProbability(*thisTrack);
607 if (not std::isnan(prob) && prob > m_lowProb) {
608 matchingProbability = prob;
609 isEfficient = true;
610 matchedTrack = thisTrack;
611 break;
612 }
613 }
614 }
615 if (!m_setCSVName.empty()) {
616 m_datfile <<eventInfo->eventNumber()<<","<<thisTruth->pdgId()<<","<<thisTruth->px()/ Gaudi::Units::GeV<<","
617 <<thisTruth->py()/ Gaudi::Units::GeV<<","<<thisTruth->pz()/ Gaudi::Units::GeV<<","
618 <<thisTruth->e()/ Gaudi::Units::GeV<<","<<thisTruth->pt()/ Gaudi::Units::GeV<<","
619 <<thisTruth->eta()<<","<<thisTruth->phi()<<","<<thisTruth->m()/ Gaudi::Units::GeV<<","
620 <<puEvents<<","<<nVertices<<","<<matchingProbability<<std::endl;
621 }
622 if (!thisTruth){
623 ATH_MSG_ERROR("An error occurred: Truth particle for tracking efficiency calculation is a nullptr");
624 }
625 else if (isEfficient && !matchedTrack){
626 ATH_MSG_ERROR("Something went wrong - we log a truth particle as reconstructed, but the reco track is a nullptr! Bailing out... ");
627 }
628 else{
629 ATH_MSG_DEBUG("Filling efficiency plots info monitoring plots");
630 m_monPlots->fillEfficiency(*thisTruth, matchedTrack, isEfficient, truthMu, actualMu, beamSpotWeight);
632 ATH_MSG_DEBUG("Filling technical efficiency plots info monitoring plots");
633 static const SG::ConstAccessor< float > nSilHitsAcc("nSilHits");
634 if (nSilHitsAcc.isAvailable(*thisTruth)) {
635 if (nSilHitsAcc(*thisTruth) >= m_minHits.value().at(getIndexByEta(*thisTruth))){
636 m_monPlots->fillTechnicalEfficiency(*thisTruth, isEfficient,
637 truthMu, actualMu, beamSpotWeight);
638 }
639 } else {
640 ATH_MSG_DEBUG("Cannot fill technical efficiency. Missing si hit information for truth particle.");
641 }
642 }
643 }
644 }
645
646 if (m_fillTruthToRecoNtuple && thisTruth) {
647 // Skip if already filled in track loop
648 if (hasTruthFilled(*thisTruth)) continue;
649
650 // Decorate truth particle with extra flags
651 decorateTruthParticle(*thisTruth, accept);
652
653 // Fill truth only entries with dummy track values
654 m_monPlots->fillNtuple(*thisTruth);
655 }
656 }
657
658 if (nSelectedRecoTracks == nMissingAssociatedTruth) {
659 if (not m_truthParticleName.key().empty()) {
660 ATH_MSG_DEBUG("NO TRACKS had associated truth.");
661 }
662 } else {
663 ATH_MSG_DEBUG(nAssociatedTruth << " tracks out of " << tracks->size() << " had associated truth.");
664 }
665
666 m_monPlots->fillCounter(nSelectedRecoTracks, InDetPerfPlot_nTracks::SELECTEDRECO, beamSpotWeight);
667 m_monPlots->fillCounter(tracks->size(), InDetPerfPlot_nTracks::ALLRECO, beamSpotWeight);
668 m_monPlots->fillCounter(nSelectedTruthTracks, InDetPerfPlot_nTracks::SELECTEDTRUTH, beamSpotWeight);
669 m_monPlots->fillCounter(nTruths, InDetPerfPlot_nTracks::ALLTRUTH, beamSpotWeight);
670 m_monPlots->fillCounter(nAssociatedTruth, InDetPerfPlot_nTracks::ALLASSOCIATEDTRUTH, beamSpotWeight);
671 m_monPlots->fillCounter(nSelectedMatchedTracks, InDetPerfPlot_nTracks::MATCHEDRECO, beamSpotWeight);
672
673 // Tracking In Dense Environment
676 getAsTruth,
677 truthParticlesVec,
678 *tracks,
679 primaryvertex,
680 beamSpotWeight) );
681 }
682 return StatusCode::SUCCESS;
683}
684
686 // Decorate outcome of track selection
687 m_dec_passedTrackSelection(track) = (bool)(passed);
688}
689
691 // Decorate outcome of truth selection
692 m_dec_passedTruthSelection(truth) = (bool)(passed);
693
694 // Decorate if selected by pileup switch
696}
697
699 if (!m_acc_hasTruthFilled.isAvailable(truth)) {
700 ATH_MSG_DEBUG("Truth particle not yet filled in ntuple");
701 return false;
702 }
703 return m_acc_hasTruthFilled(truth);
704}
705
707 if (!m_acc_selectedByPileupSwitch.isAvailable(truth)) {
708 ATH_MSG_DEBUG("Selected by pileup switch decoration requested from a truth particle but not available");
709 return false;
710 }
711 return m_acc_selectedByPileupSwitch(truth);
712}
713
714void InDetPhysValMonitoringTool::markSelectedByPileupSwitch(const std::vector<const xAOD::TruthParticle*> & truthParticles) const{
715 for (const auto& thisTruth: truthParticles) {
716 m_dec_selectedByPileupSwitch(*thisTruth) = true;
717 }
718}
719
720StatusCode
722 ATH_MSG_INFO("Booking hists " << name() << "with detailed level: " << m_detailLevel);
723 m_monPlots->initialize();
724 std::vector<HistData> hists = m_monPlots->retrieveBookedHistograms();
725 for (const auto& hist : hists) {
726 ATH_CHECK(regHist(hist.first, hist.second, all)); // ??
727 }
728 // do the same for Efficiencies, but there's a twist:
729 std::vector<EfficiencyData> effs = m_monPlots->retrieveBookedEfficiencies();
730 for (auto& eff : effs) {
731 // reg**** in the monitoring baseclass doesnt have a TEff version, but TGraph *
732 // pointers just get passed through, so we use that method after an ugly cast
733 ATH_CHECK(regGraph(reinterpret_cast<TGraph*>(eff.first), eff.second, all)); // ??
734 }
735 // register trees for ntuple writing
737 std::vector<TreeData> trees = m_monPlots->retrieveBookedTrees();
738 for (auto& t : trees) {
739 ATH_CHECK(regTree(t.first, t.second, all));
740 }
741 }
742
743 return StatusCode::SUCCESS;
744}
745
746StatusCode
748 ATH_MSG_INFO("Finalising hists " << name() << "...");
749 //TODO: ADD Printouts for Truth??
751 ATH_MSG_INFO("");
752 ATH_MSG_INFO("Now Cutflow for track cuts:");
753 ATH_MSG_INFO("");
754 for (int i = 0; i < (int) m_trackCutflow.size(); ++i) {
755 ATH_MSG_INFO("number after " << m_trackCutflowNames[i] << ": " << m_trackCutflow[i]);
756 }
757 }
758
759 ATH_MSG_INFO("");
760 ATH_MSG_INFO("Cutflow for truth tracks:");
761 if (m_truthSelectionTool.get()) {
762 ATH_MSG_INFO("Truth selection report: " << m_truthCutFlow.report( m_truthSelectionTool->names()) );
763 }
764 if (endOfRunFlag()) {
765 m_monPlots->finalize();
766 }
767 ATH_MSG_INFO("Successfully finalized hists");
768 return StatusCode::SUCCESS;
769}
770
771const std::vector<const xAOD::TruthParticle*>
772InDetPhysValMonitoringTool::getTruthParticles(const EventContext& ctx) const {
773
774 std::vector<const xAOD::TruthParticle*> tempVec {};
775
776 if (m_pileupSwitch == "All") {
777 if (m_truthParticleName.key().empty()) {
778 return tempVec;
779 }
781 if (not truthParticleContainer.isValid()) {
782 return tempVec;
783 }
784 tempVec.insert(tempVec.begin(), truthParticleContainer->begin(), truthParticleContainer->end());
785 } else {
786 if (m_pileupSwitch == "HardScatter") {
787 // get truthevent container to separate out pileup and hardscatter truth particles
788 if (not m_truthEventName.key().empty()) {
790 const xAOD::TruthEvent* event = (truthEventContainer.isValid()) ? truthEventContainer->at(0) : nullptr;
791 if (not event) {
792 return tempVec;
793 }
794 const auto& links = event->truthParticleLinks();
795 tempVec.reserve(event->nTruthParticles());
796 for (const auto& link : links) {
797 if (link.isValid()){
798 tempVec.push_back(*link);
799 }
800 }
801 }
802 } else if (m_pileupSwitch == "PileUp") {
803 if (not m_truthPileUpEventName.key().empty()) {
804 ATH_MSG_VERBOSE("getting TruthPileupEvents container");
805 // get truth particles from all pileup events
807 if (truthPileupEventContainer.isValid()) {
808 const unsigned int nPileup = truthPileupEventContainer->size();
809 tempVec.reserve(nPileup * 200); // quick initial guess, will still save some time
810 for (unsigned int i(0); i != nPileup; ++i) {
811 const auto *eventPileup = truthPileupEventContainer->at(i);
812 // get truth particles from each pileup event
813 int ntruth = eventPileup->nTruthParticles();
814 ATH_MSG_VERBOSE("Adding " << ntruth << " truth particles from TruthPileupEvents container");
815 const auto& links = eventPileup->truthParticleLinks();
816 for (const auto& link : links) {
817 if (link.isValid()){
818 tempVec.push_back(*link);
819 }
820 }
821 }
822 } else {
823 ATH_MSG_ERROR("no entries in TruthPileupEvents container!");
824 }
825 }
826 } else {
827 ATH_MSG_ERROR("bad value for PileUpSwitch");
828 }
829 }
830 return tempVec;
831}
832
833std::pair<std::vector<const xAOD::TruthVertex*>, std::vector<const xAOD::TruthVertex*>>
834InDetPhysValMonitoringTool::getTruthVertices(const EventContext& ctx) const {
835
836 std::vector<const xAOD::TruthVertex*> truthHSVertices = {};
837 truthHSVertices.reserve(5);
838 std::vector<const xAOD::TruthVertex*> truthPUVertices = {};
839 truthPUVertices.reserve(100);
840 const xAOD::TruthVertex* truthVtx = nullptr;
841
842 bool doHS = false;
843 bool doPU = false;
844 if (m_pileupSwitch == "All") {
845 doHS = true;
846 doPU = true;
847 }
848 else if (m_pileupSwitch == "HardScatter") {
849 doHS = true;
850 }
851 else if (m_pileupSwitch == "PileUp") {
852 doPU = true;
853 }
854 else {
855 ATH_MSG_ERROR("Bad value for PileUpSwitch: " << m_pileupSwitch);
856 }
857
858 if (doHS) {
859 if (not m_truthEventName.key().empty()) {
860 ATH_MSG_VERBOSE("Getting HS TruthEvents container.");
862 if (truthEventContainer.isValid()) {
863 for (const auto *const evt : *truthEventContainer) {
864 truthVtx = evt->signalProcessVertex();
865 if (truthVtx) {
866 truthHSVertices.push_back(truthVtx);
867 }
868 }
869 }
870 else {
871 ATH_MSG_ERROR("No entries in TruthEvents container!");
872 }
873 }
874 }
875
876 if (doPU) {
877 if (not m_truthPileUpEventName.key().empty()) {
878 ATH_MSG_VERBOSE("Getting PU TruthEvents container.");
880 if (truthPileupEventContainer.isValid()) {
881 for (const auto *const evt : *truthPileupEventContainer) {
882 // Get the PU vertex
883 // In all cases tested i_vtx=2 for PU
884 // but better to keep something generic
885 truthVtx = nullptr;
886 size_t i_vtx = 0; size_t n_vtx = evt->nTruthVertices();
887 while(!truthVtx && i_vtx<n_vtx){
888 truthVtx = evt->truthVertex(i_vtx);
889 i_vtx++;
890 }
891
892 if (truthVtx) {
893 truthPUVertices.push_back(truthVtx);
894 }
895 }
896 }
897 else {
898 ATH_MSG_DEBUG("No entries in TruthPileupEvents container");
899 }
900 }
901 }
902
903 return {std::move(truthHSVertices), std::move(truthPUVertices)};
904}
905
906void
910
911void
912InDetPhysValMonitoringTool::fillCutFlow(const asg::AcceptData& accept, std::vector<std::string>& names,
913 std::vector<int>& cutFlow) {
914 // initialise cutflows
915 if (cutFlow.empty()) {
916 names.emplace_back("preCut");
917 cutFlow.push_back(0);
918 for (unsigned int i = 0; i != accept.getNCuts(); ++i) {
919 cutFlow.push_back(0);
920 names.push_back((std::string) accept.getCutName(i));
921 }
922 }
923 // get cutflow
924 cutFlow[0] += 1;
925 bool cutPositive = true;
926 for (unsigned int i = 0; i != (accept.getNCuts() + 1); ++i) {
927 if (!cutPositive) {
928 continue;
929 }
930 if (accept.getCutResult(i)) {
931 cutFlow[i + 1] += 1;
932 } else {
933 cutPositive = false;
934 }
935 }
936 }
937
939 double absEta = std::abs(truth.eta());
940 if (absEta > m_etaBins.value().back() || absEta < m_etaBins.value().front()) {
941 absEta = std::clamp(absEta, m_etaBins.value().front(), m_etaBins.value().back());
942 ATH_MSG_INFO("Requesting cut value outside of configured eta range: clamping eta = "
943 << std::abs(truth.eta()) << " to eta= " << absEta);
944 } else
945 absEta = std::clamp(absEta, m_etaBins.value().front(), m_etaBins.value().back());
946 const auto pVal = std::lower_bound(m_etaBins.value().begin(), m_etaBins.value().end(), absEta);
947 const int bin = std::distance(m_etaBins.value().begin(), pVal) - 1;
948 ATH_MSG_DEBUG("Checking (abs(eta)/bin) = (" << absEta << "," << bin << ")");
949 return bin;
950}
951
953 IDPVM::CachedGetAssocTruth& getAsTruth,
954 const std::vector<const xAOD::TruthParticle*>& truthParticles,
955 const xAOD::TrackParticleContainer& tracks,
956 const xAOD::Vertex* primaryvertex,
957 float beamSpotWeight) {
958 // Define accessors
959 static const SG::ConstAccessor<std::vector<ElementLink<xAOD::IParticleContainer> > > ghosttruth("GhostTruth");
960 static const SG::ConstAccessor<int> btagLabel("HadronConeExclTruthLabelID");
961
962 if (truthParticles.empty()) {
963 ATH_MSG_WARNING("No entries in TruthParticles truth particle container. Skipping jet plots.");
964 return StatusCode::SUCCESS;
965 }
966
968 if (not jetHandle.isValid()) {
969 ATH_MSG_WARNING("Cannot open jet container " << m_jetContainerName.key() << ". Skipping jet plots.");
970 return StatusCode::SUCCESS;
971 }
972 const xAOD::JetContainer* jets = jetHandle.cptr();
973
974 // loop on jets
975 for (const xAOD::Jet *const thisJet: *jets) {
976 // pass jet cuts
977 if (not passJetCuts(*thisJet)) continue;
978 // check if b-jet
979 bool isBjet = false;
980 if (not btagLabel.isAvailable(*thisJet)){
981 ATH_MSG_WARNING("Failed to extract b-tag truth label from jet");
982 } else {
983 isBjet = (btagLabel(*thisJet) == 5);
984 }
985
986 // Retrieve associated ghost truth particles
987 if(not ghosttruth.isAvailable(*thisJet)) {
988 ATH_MSG_WARNING("Failed to extract ghost truth particles from jet");
989 } else {
990 for(const ElementLink<xAOD::IParticleContainer>& el : ghosttruth(*thisJet)) {
991 if (not el.isValid()) continue;
992
993 const xAOD::TruthParticle *truth = static_cast<const xAOD::TruthParticle*>(*el);
994 // Check delta R between track and jet axis
995 if (thisJet->p4().DeltaR(truth->p4()) > m_maxTrkJetDR) {
996 continue;
997 }
998 // Apply truth selection cuts
999 const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(truth);
1000 if(!accept) continue;
1001
1002 bool isEfficient(false);
1003
1004 for (const auto *thisTrack: tracks) {
1005 if (m_useTrackSelection and not (m_trackSelectionTool->accept(*thisTrack, primaryvertex))) {
1006 continue;
1007 }
1008
1009 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
1010 if (associatedTruth and associatedTruth == truth) {
1011 float prob = getMatchingProbability(*thisTrack);
1012 if (not std::isnan(prob) && prob > m_lowProb) {
1013 isEfficient = true;
1014 break;
1015 }
1016 }
1017 }
1018
1019 bool truthIsFromB = false;
1020 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(truth, 5) ) {
1021 truthIsFromB = true;
1022 }
1023 m_monPlots->fillEfficiency(*truth, *thisJet, isEfficient, isBjet, truthIsFromB, beamSpotWeight);
1024 }
1025 } // ghost truth
1026
1027 // loop on tracks
1028 for (const xAOD::TrackParticle *thisTrack: tracks) {
1029 if (m_useTrackSelection and not (m_trackSelectionTool->accept(*thisTrack, primaryvertex))) {
1030 continue;
1031 }
1032
1033 if (thisJet->p4().DeltaR(thisTrack->p4()) > m_maxTrkJetDR) {
1034 continue;
1035 }
1036
1037 float prob = getMatchingProbability(*thisTrack);
1038 if(std::isnan(prob)) prob = 0.0;
1039
1040 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
1041 const bool isFake = (associatedTruth && prob < m_lowProb);
1042 bool truthIsFromB = false;
1043 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(associatedTruth, 5) ) {
1044 truthIsFromB = true;
1045 }
1046 m_monPlots->fill(*thisTrack, *thisJet, isBjet, isFake, truthIsFromB, beamSpotWeight);
1047 if (associatedTruth){
1048 m_monPlots->fillFakeRate(*thisTrack, *thisJet, isFake, isBjet, truthIsFromB, beamSpotWeight);
1049 }
1050 }
1051
1052 } // loop on jets
1053
1054 return StatusCode::SUCCESS;
1055}
1056
1057bool
1059 const float jetPt = jet.pt();
1060 const float jetEta = std::abs(jet.eta());
1061
1062 if (jetEta < m_jetAbsEtaMin) return false;
1063 if (jetEta > m_jetAbsEtaMax) return false;
1064 if (jetPt < m_jetPtMin) return false;
1065 if (jetPt > m_jetPtMax) return false;
1066 return true;
1067}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
header file for truth selection in this package
Helper class to provide constant type-safe access to aux data.
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
header file for class of same name
header file for class of same name
bool passed(DecisionID id, const DecisionIDContainer &)
checks if required decision ID is in the set of IDs in the container
bool inRange(const double *boundaries, const double value, const double tolerance=0.02)
#define y
#define x
#define z
ServiceHandle< StoreGateSvc > & evtStore()
void update(bool)
Definition CutFlow.h:192
size_type size() const noexcept
Returns the number of elements in the collection.
static void neededTrackParticleDecorations(std::vector< std::string > &decorations)
const xAOD::TruthParticle * getTruth(const xAOD::TrackParticle *const trackParticle)
bool passJetCuts(const xAOD::Jet &jet) const
ToolHandle< InDet::IInDetHardScatterSelectionTool > m_hardScatterSelectionTool
SG::AuxElement::Decorator< bool > m_dec_passedTrackSelection
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainerName
Primary vertex container's name.
const std::vector< const xAOD::TruthParticle * > getTruthParticles(const EventContext &ctx) const
SG::AuxElement::Accessor< bool > m_acc_hasTruthFilled
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleName
TruthParticle container's name.
std::unique_ptr< InDetRttPlots > m_monPlots
histograms
virtual StatusCode procHistograms()
An inheriting class should either override this function or finalHists().
SG::ReadDecorHandleKey< xAOD::EventInfo > m_weight_pileup_key
bool isSelectedByPileupSwitch(const xAOD::TruthParticle &truth) const
SG::ReadHandleKey< xAOD::TruthPileupEventContainer > m_truthPileUpEventName
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_trkParticleName
TrackParticle container's name.
static void fillCutFlow(const asg::AcceptData &accept, std::vector< std::string > &names, std::vector< int > &cutFlow)
InDetPhysValMonitoringTool()
prevent default construction
SG::AuxElement::Accessor< bool > m_acc_selectedByPileupSwitch
SG::AuxElement::Decorator< bool > m_dec_selectedByPileupSwitch
std::vector< SG::ReadDecorHandleKey< xAOD::JetContainer > > m_intJetDecor
int getIndexByEta(const xAOD::TruthParticle &truth) const
Utility function for evaluation of technical efficiency.
ToolHandle< InDet::IInDetTrackSelectionTool > m_trackSelectionTool
SG::AuxElement::Decorator< bool > m_dec_hasTruthFilled
ToolHandle< InDet::IInDetTrackTruthOriginTool > m_trackTruthOriginTool
BooleanProperty m_useTrackSelection
Properties to fine-tune the tool behaviour.
void fillTrackCutFlow(const asg::AcceptData &accept)
SG::ReadHandleKey< xAOD::TruthVertexContainer > m_truthVertexContainerName
Truth vertex container's name.
std::vector< SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > > m_floatTrkDecor
ToolHandle< IInDetVertexTruthMatchTool > m_vtxValidTool
void decorateTrackParticle(const xAOD::TrackParticle &track, const asg::AcceptData &passed) const
void decorateTruthParticle(const xAOD::TruthParticle &truth, const IAthSelectionTool::CutResult &passed) const
std::pair< std::vector< const xAOD::TruthVertex * >, std::vector< const xAOD::TruthVertex * > > getTruthVertices(const EventContext &ctx) const
std::vector< SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > > m_floatTruthDecor
std::vector< SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > > m_intTruthDecor
InDetRttPlotConfig getFilledPlotConfig() const
Generate an Rtt config struct based on the user-passed properties.
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoContainerName
EventInfo container name.
virtual StatusCode fillHistograms(const EventContext &ctx)
An inheriting class should either override this function or fillHists().
SG::ReadHandleKey< xAOD::TruthEventContainer > m_truthEventName
ToolHandle< IGoodRunsListSelectionTool > m_grlTool
SG::ReadHandleKey< xAOD::JetContainer > m_jetContainerName
bool hasTruthFilled(const xAOD::TruthParticle &truth) const
void markSelectedByPileupSwitch(const std::vector< const xAOD::TruthParticle * > &truthParticles) const
virtual ~InDetPhysValMonitoringTool()
Destructor.
std::vector< SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > > m_linkTrkDecor
ToolHandle< IAthSelectionTool > m_truthSelectionTool
StatusCode fillHistogramsTrackingInDenseEnvironment(const EventContext &ctx, IDPVM::CachedGetAssocTruth &getAsTruth, const std::vector< const xAOD::TruthParticle * > &truthParticles, const xAOD::TrackParticleContainer &tracks, const xAOD::Vertex *primaryvertex, float beamSpotWeight)
std::vector< SG::ReadDecorHandleKey< xAOD::TrackParticleContainer > > m_intTrkDecor
virtual StatusCode bookHistograms()
An inheriting class should either override this function or bookHists().
std::vector< std::string > m_trackCutflowNames
SG::AuxElement::Decorator< bool > m_dec_passedTruthSelection
virtual StatusCode regHist(TH1 *h, const std::string &system, Interval_t interval, MgmtAttr_t histo_mgmt=ATTRIB_MANAGED, const std::string &chain="", const std::string &merge="")
Registers a TH1 (including TH2, TH3, and TProfile) to be included in the output stream using logical ...
virtual StatusCode regTree(TTree *t, const std::string &system, Interval_t interval, MgmtAttr_t histo_mgmt=ATTRIB_MANAGED, const std::string &chain="", const std::string &merge="")
Registers a TTree to be included in the output stream using logical parameters that describe it.
ManagedMonitorToolBase(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode regGraph(TGraph *g, const std::string &system, Interval_t interval, MgmtAttr_t histo_mgmt=ATTRIB_MANAGED, const std::string &chain="", const std::string &merge="")
Registers a TGraph to be included in the output stream using logical parameters that describe the gra...
Helper class to provide constant type-safe access to aux data.
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Handle class for reading a decoration on an object.
bool isAvailable()
Test to see if this variable exists in the store, for the referenced object.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
const_pointer_type get() const
Dereference the pointer, but don't cache anything.
@ IS_SIMULATION
true: simulation, false: data
uint64_t eventNumber() const
The current event's event number.
virtual double m() const override final
The mass of the particle.
int pdgId() const
PDG ID code.
float px() const
The x component of the particle's momentum.
virtual double e() const override final
The total energy of the particle.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
float py() const
The y component of the particle's momentum.
virtual double eta() const override final
The pseudorapidity ( ) of the particle.
virtual double phi() const override final
The azimuthal angle ( ) of the particle.
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
float pz() const
The z component of the particle's momentum.
float z() const
Vertex longitudinal distance along the beam line form the origin.
float y() const
Vertex y displacement.
float x() const
Vertex x displacement.
dict partitions
Definition DeMoScan.py:65
void addReadDecoratorHandleKeys(T_Parent &parent, const SG::ReadHandleKey< T_Cont > &container_key, const std::string &prefix, const std::vector< std::string > &decor_names, std::vector< SG::ReadDecorHandleKey< T_Cont > > &decor_out)
float safelyGetEta(const T &pTrk, const float safePtThreshold=0.1)
Safely get eta.
unsigned int binIndex(const T &val, const std::vector< T > &partitions)
general utility function to return bin index given a value and the upper endpoints of each bin
HardScatterType classifyHardScatter(const xAOD::VertexContainer &vxContainer)
STL namespace.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ PriVtx
Primary vertex.
Jet_v1 Jet
Definition of the current "jet version".
EventInfo_v1 EventInfo
Definition of the latest event info version.
TruthVertex_v1 TruthVertex
Typedef to implementation.
Definition TruthVertex.h:15
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Vertex_v1 Vertex
Define the latest version of the vertex class.
TruthEvent_v1 TruthEvent
Typedef to implementation.
Definition TruthEvent.h:17
TruthParticle_v1 TruthParticle
Typedef to implementation.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
JetContainer_v1 JetContainer
Definition of the current "jet container version".
implementation file for function of same name
helper struct - steer the configuration from the parent tool's side
bool doTrkInJetPlots_matched_bjets
int detailLevel
detail level (kept for compatibility)
bool doNtupleTruthToReco
Ntuple functionality.
bool doEfficienciesPerAuthor
per author plots
bool doHitsRecoTracksPlotsPerAuthor
bool doEffPlots
Efficiency and duplicate plots - require truth, optionally matching reco.
bool doFakePlots
Fake plots.
bool doResolutionPlotPrim
Resolution and "matched track" plots - filled if both reco and truth exist.
bool doVertexTruthMatchingPlots
Vertexing plots - truth requirement.
bool doVertexPlots
Vertexing plots - no truth requirement.
bool doHardScatterVertexTruthMatchingPlots
bool doTrackParameters
Plots for (selected) tracks, not necessarily truth matched.
bool doTrkInJetPlots
Plots for tracks in jets.
bool doResolutionPlotPrim_truthFromB