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.doFakesPerAuthor = false;
297 rttConfig.doTrackParametersPerAuthor = false;
298 rttConfig.doEfficienciesPerAuthor = false;
299 rttConfig.doResolutionsPerAuthor = false;
300 rttConfig.doTrkInJetPlots_matched = false;
301 rttConfig.doTrkInJetPlots_fake = false;
302 rttConfig.doTrkInJetPlots_matched_bjets = false;
303 rttConfig.doTrkInJetPlots_fake_bjets = false;
304 }
305
306 return rttConfig;
307}
308
309StatusCode
311 ATH_MSG_DEBUG("Filling hists " << name() << "...");
312 // function object could be used to retrieve truth: IDPVM::CachedGetAssocTruth getTruth;
313
314 // retrieve trackParticle container
316 if (not trackHandle.isValid()) {
317 ATH_MSG_ERROR("Invalid trackname = " << m_trkParticleName << "!");
318 return StatusCode::FAILURE;
319 }
320 const xAOD::TrackParticleContainer* tracks = trackHandle.cptr();
321
322 SG::ReadHandle<xAOD::TruthPileupEventContainer> truthPileupEventContainer;
323 if( not m_truthPileUpEventName.key().empty()) {
325 }
326
328 if (not pie.isValid()){
329 ATH_MSG_WARNING("Shouldn't happen - EventInfo is buggy, setting mu to 0");
330 }
331
332 // FIX-ME: I'm not sure if we should stop execution if EventInfo is not valid ...
333 // it is used after as if they assume it is valid
334 if (m_useGRL and pie.isValid() and !pie->eventType(xAOD::EventInfo::IS_SIMULATION)) {
335 if (!m_grlTool->passRunLB(*pie)) {
336 ATH_MSG_VERBOSE("GRL veto");
337 return StatusCode::SUCCESS;
338 }
339 }
340
341 std::vector<const xAOD::TruthParticle*> truthParticlesVec = getTruthParticles(ctx);
342
343 // Mark the truth particles in our vector as "selected".
344 // This is needed because we later access the truth matching via xAOD decorations, where we do not 'know' about membership to this vector.
346 const xAOD::EventInfo *eventInfo = nullptr;
347 ATH_CHECK (evtStore()->retrieve (eventInfo, "EventInfo"));
348 IDPVM::CachedGetAssocTruth getAsTruth; // only cache one way, track->truth, not truth->tracks
349
350 unsigned int truthMu = 0;
351 float actualMu = 0.;
352 if(not m_truthPileUpEventName.key().empty() and truthPileupEventContainer.isValid()){
353 truthMu = static_cast<int>( truthPileupEventContainer->size() );
354 }
355 if(pie.isValid()) actualMu = pie->actualInteractionsPerCrossing();
356
357 // This is questionable but kept for backward compatibility for now
358 float puEvents = truthMu>0 ? truthMu : actualMu;
359
360 const xAOD::Vertex* primaryvertex = nullptr;
361 unsigned int nVertices = 0;
362 float beamSpotWeight = 1;
363
364 if(not m_vertexContainerName.key().empty()){
365 ATH_MSG_DEBUG("Getting number of pu interactings per event");
366
367 ATH_MSG_DEBUG("Filling vertex plots");
369 ATH_CHECK(vertices.isValid());
370
371 nVertices = not vertices->empty() ? vertices->size() : 0;
372 beamSpotWeight = pie->beamSpotWeight();
373 ATH_MSG_DEBUG("beamSpotWeight is equal to " << beamSpotWeight);
374 if(m_doPRW){
375 float prwWeight = 1;
377 if(readDecorHandle.isAvailable()) prwWeight = readDecorHandle(*pie);
378 ATH_MSG_DEBUG("Applying pileup weight equal to " << prwWeight);
379 beamSpotWeight *= prwWeight;
380 }
381
382 if (vertices.isValid() and not vertices->empty()) {
383 ATH_MSG_DEBUG("Number of vertices retrieved for this event " << vertices->size());
384 //Find the HS vertex following the user-configured strategy
385 if (m_hardScatterSelectionTool.empty()) {
386 for (const auto& vertex : *vertices){
387 if(vertex->vertexType()==xAOD::VxType::PriVtx){
388 primaryvertex = vertex;
389 break;
390 }
391 }
392 } else {
393 primaryvertex = m_hardScatterSelectionTool->getHardScatter(vertices.get());
394 }
395
396 if (!primaryvertex){
399 ATH_MSG_DEBUG("Failed to find a hard scatter vertex in this event.");
400 }
401 //Filling plots for all reconstructed vertices and the hard-scatter
402 ATH_MSG_DEBUG("Filling vertices info monitoring plots");
403
404 // Fill vectors of truth HS and PU vertices
405 std::pair<std::vector<const xAOD::TruthVertex*>, std::vector<const xAOD::TruthVertex*>> truthVertices = getTruthVertices(ctx);
406 std::vector<const xAOD::TruthVertex*> truthHSVertices = truthVertices.first;
407 std::vector<const xAOD::TruthVertex*> truthPUVertices = truthVertices.second;
408
409 // Decorate vertices
411 ATH_CHECK(m_vtxValidTool->matchVertices(*vertices));
412 ATH_MSG_DEBUG("Hard scatter classification type: " << InDetVertexTruthMatchUtils::classifyHardScatter(*vertices) << ", vertex container size = " << vertices->size());
413 }
414 m_monPlots->fill(*vertices, primaryvertex, truthHSVertices, truthPUVertices, actualMu, beamSpotWeight);
415
416 ATH_MSG_DEBUG("Filling vertex/event info monitoring plots");
417 //Filling vertexing plots for the reconstructed hard-scatter as a function of mu
418 m_monPlots->fill(*vertices, truthMu, actualMu, beamSpotWeight);
419 } else {
420 //FIXME: Does this happen for single particles?
421 ATH_MSG_WARNING("Skipping vertexing plots.");
422 }
423 }
424
425 if( not m_truthVertexContainerName.key().empty()){
426 // get truth vertex container name - m_truthVertexContainerName
428
429 //
430 //Get the HS vertex position from the truthVertexContainer
431 //FIXME: Add plots w.r.t truth HS positions (vertexing plots)
432 //
433 const xAOD::TruthVertex* truthVertex = nullptr;
434 if (truthVrt.isValid()) {
435 const auto& stdVertexContainer = truthVrt->stdcont();
436 //First truth particle vertex?
437 auto findVtx = std::find_if(stdVertexContainer.rbegin(), stdVertexContainer.rend(), acceptTruthVertex);
438 truthVertex = (findVtx == stdVertexContainer.rend()) ? nullptr : *findVtx;
439 } else {
440 ATH_MSG_WARNING("Cannot open " << m_truthVertexContainerName.key() << " truth vertex container");
441 }
442 if (not truthVertex) ATH_MSG_INFO ("Truth vertex did not pass cuts");
443 }
444 //
445 //Counters for cutflow
446 //
447 unsigned int nSelectedTruthTracks(0), nSelectedRecoTracks(0), nSelectedMatchedTracks(0), nAssociatedTruth(0), nMissingAssociatedTruth(0), nTruths(0);
448
449 CutFlow tmp_truth_cutflow( m_truthSelectionTool.get() ? m_truthSelectionTool->nCuts() : 0 );
450
451 //
452 //Loop over all reconstructed tracks
453 //
454 // If writing ntuples, use a truth-to-track(s) cache to handle truth matching.
455 // Based on the assumption that multiple tracks can (albeit rarely) share the same truth association.
456 std::map<const xAOD::TruthParticle*, std::vector<const xAOD::TrackParticle*>> cacheTruthMatching {};
457 //
458 std::vector<const xAOD::TrackParticle*> selectedTracks {};
459 selectedTracks.reserve(tracks->size());
460 unsigned int nTrackTOT = 0;
461 unsigned int nTrackCentral = 0;
462 unsigned int nTrackPt1GeV = 0;
463 for (const auto *const thisTrack: *tracks) {
464 //FIXME: Why is this w.r.t the primary vertex?
465 const asg::AcceptData& accept = m_trackSelectionTool->accept(*thisTrack, primaryvertex);
466 if (m_useTrackSelection and not accept) continue;
467 fillTrackCutFlow(accept); //?? Is this equal???
468
469 selectedTracks.push_back(thisTrack);
470 //Number of selected reco tracks
471 nSelectedRecoTracks++;
472
473 //Fill plots for selected reco tracks, hits / perigee / ???
474 nTrackTOT++;
475 if (thisTrack->pt() >= (1 * Gaudi::Units::GeV))
476 nTrackPt1GeV++;
477 if (std::abs(thisTrack->eta()) < 2.5)
478 nTrackCentral++;
479 m_monPlots->fill(*thisTrack, beamSpotWeight);
480 m_monPlots->fill(*thisTrack, puEvents, nVertices, beamSpotWeight); //fill mu dependent plots
481 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
482 float prob = getMatchingProbability(*thisTrack);
483
484 // This is where the Fake, and Really Fake fillers need to go. Where would the really really fakes go?
485 if (associatedTruth) {
486 nAssociatedTruth++;
487
488 // if there is associated truth also a truth selection tool was retrieved.
491 //FIXME: What is this for???
492 tmp_truth_cutflow.update( passed.missingCuts() );
493 }
494
495 if ((not std::isnan(prob)) and (prob > m_lowProb) and passed and (not m_usingSpecialPileupSwitch or isSelectedByPileupSwitch(*associatedTruth)) ) {
496 nSelectedMatchedTracks++;
497 bool truthIsFromB = false;
498 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(associatedTruth, 5) ) {
499 truthIsFromB = true;
500 }
501 m_monPlots->fill(*thisTrack, *associatedTruth, truthIsFromB, puEvents, beamSpotWeight); // Make plots requiring matched truth
502 }
503 }
504
505 const bool isAssociatedTruth = associatedTruth != nullptr;
506 const bool isFake = not std::isnan(prob) ? (prob < m_lowProb) : true;
507
508 if(!isAssociatedTruth) nMissingAssociatedTruth++;
509 m_monPlots->fillFakeRate(*thisTrack, isFake, puEvents, beamSpotWeight);
510
512 // Decorate track particle with extra flags
513 decorateTrackParticle(*thisTrack, accept);
514
515 if (isAssociatedTruth) {
516 // Decorate truth particle with extra flags
517 decorateTruthParticle(*associatedTruth, m_truthSelectionTool->accept(associatedTruth));
518
519 // Cache truth-to-track associations
520 auto cachedAssoc = cacheTruthMatching.find(associatedTruth);
521 // Check if truth particle already present in cache
522 if (cachedAssoc == cacheTruthMatching.end()) {
523 // If not yet present, add truth-to-track association in cache
524 cacheTruthMatching[associatedTruth] = {thisTrack};
525 }
526 else {
527 // If already present, cache additional track associations (here multiple track particle can be linked to the same truth particle)
528 cachedAssoc->second.push_back(thisTrack);
529 }
530 }
532 // Fill track only entries with dummy truth values
533 m_monPlots->fillNtuple(*thisTrack, primaryvertex);
534 }
535 }
536 }
538 // Now fill all truth-to-track associations
539 // Involves some double-filling of truth particles in cases where multiple tracks share the same truth association,
540 // these duplicates can be filtered in the ntuple by selecting only the 'best matched' truth-associated track particles.
541 for (auto& cachedAssoc: cacheTruthMatching) {
542 const xAOD::TruthParticle* thisTruth = cachedAssoc.first;
543
544 // Decorate that this truth particle is being filled to prevent double counting in truth particle loop
545 m_dec_hasTruthFilled(*thisTruth) = true;
546
547 // Sort all associated tracks by truth match probability
548 std::sort(cachedAssoc.second.begin(), cachedAssoc.second.end(),
549 [](const xAOD::TrackParticle* t1, const xAOD::TrackParticle* t2) { return getMatchingProbability(*t1) > getMatchingProbability(*t2); }
550 );
551
553 // Fill all tracks associated to to this truth particle, also recording 'truth match ranking' as index in probability-sorted vector of matched tracks
554 for (int itrack = 0; itrack < (int) cachedAssoc.second.size(); itrack++) {
555 const xAOD::TrackParticle* thisTrack = cachedAssoc.second[itrack];
556
557 // Fill track entries with truth association
558 m_monPlots->fillNtuple(*thisTrack, *thisTruth, primaryvertex, itrack);
559 }
560 }
561 }
562 }
563
564 m_monPlots->fill(nTrackTOT, nTrackCentral, nTrackPt1GeV, truthMu, actualMu, nVertices, beamSpotWeight);
565
566 //FIXME: I don't get why... this is here
567 if (m_truthSelectionTool.get()) {
568 ATH_MSG_DEBUG( CutFlow(tmp_truth_cutflow).report(m_truthSelectionTool->names()) );
569 std::lock_guard<std::mutex> lock(m_mutex);
570 m_truthCutFlow.merge(std::move(tmp_truth_cutflow));
571 }
572
573 //
574 //TruthParticle loop to fill efficiencies
575 //
576 for (int itruth = 0; itruth < (int) truthParticlesVec.size(); itruth++) { // Outer loop over all truth particles
577 nTruths++;
578 const xAOD::TruthParticle* thisTruth = truthParticlesVec[itruth];
579
580 // if the vector of truth particles is not empty also a truthSelectionTool was retrieved
581 const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(thisTruth);
582 if (accept) {
583 ++nSelectedTruthTracks; // total number of truth which pass cuts per event
584 bool isEfficient(false); // weight for the trackeff histos
585 float matchingProbability{};
586 m_monPlots->fill(*thisTruth, beamSpotWeight); // This is filling truth-only plots
587
589 auto cachedAssoc = cacheTruthMatching.find(thisTruth);
590 // Check if truth particle already present in cache
591 if (cachedAssoc == cacheTruthMatching.end()) {
592 // If not yet present, then no track associated
593 cacheTruthMatching[thisTruth] = {};
594 }
595 m_monPlots->fillDuplicate(*thisTruth, cacheTruthMatching[thisTruth], beamSpotWeight);
596 }
597
598 //
599 //Loop over reco tracks to find the match
600 //
601 const xAOD::TrackParticle* matchedTrack = nullptr;
602 for (const auto& thisTrack: selectedTracks) { // Inner loop over selected track particleis
603 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
604 if (associatedTruth && associatedTruth == thisTruth) {
605 float prob = getMatchingProbability(*thisTrack);
606 if (not std::isnan(prob) && prob > m_lowProb) {
607 matchingProbability = prob;
608 isEfficient = true;
609 matchedTrack = thisTrack;
610 break;
611 }
612 }
613 }
614 if (!m_setCSVName.empty()) {
615 m_datfile <<eventInfo->eventNumber()<<","<<thisTruth->pdgId()<<","<<thisTruth->px()/ Gaudi::Units::GeV<<","
616 <<thisTruth->py()/ Gaudi::Units::GeV<<","<<thisTruth->pz()/ Gaudi::Units::GeV<<","
617 <<thisTruth->e()/ Gaudi::Units::GeV<<","<<thisTruth->pt()/ Gaudi::Units::GeV<<","
618 <<thisTruth->eta()<<","<<thisTruth->phi()<<","<<thisTruth->m()/ Gaudi::Units::GeV<<","
619 <<puEvents<<","<<nVertices<<","<<matchingProbability<<std::endl;
620 }
621 if (!thisTruth){
622 ATH_MSG_ERROR("An error occurred: Truth particle for tracking efficiency calculation is a nullptr");
623 }
624 else if (isEfficient && !matchedTrack){
625 ATH_MSG_ERROR("Something went wrong - we log a truth particle as reconstructed, but the reco track is a nullptr! Bailing out... ");
626 }
627 else{
628 ATH_MSG_DEBUG("Filling efficiency plots info monitoring plots");
629 m_monPlots->fillEfficiency(*thisTruth, matchedTrack, isEfficient, truthMu, actualMu, beamSpotWeight);
631 ATH_MSG_DEBUG("Filling technical efficiency plots info monitoring plots");
632 static const SG::ConstAccessor< float > nSilHitsAcc("nSilHits");
633 if (nSilHitsAcc.isAvailable(*thisTruth)) {
634 if (nSilHitsAcc(*thisTruth) >= m_minHits.value().at(getIndexByEta(*thisTruth))){
635 m_monPlots->fillTechnicalEfficiency(*thisTruth, isEfficient,
636 truthMu, actualMu, beamSpotWeight);
637 }
638 } else {
639 ATH_MSG_DEBUG("Cannot fill technical efficiency. Missing si hit information for truth particle.");
640 }
641 }
642 }
643 }
644
645 if (m_fillTruthToRecoNtuple && thisTruth) {
646 // Skip if already filled in track loop
647 if (hasTruthFilled(*thisTruth)) continue;
648
649 // Decorate truth particle with extra flags
650 decorateTruthParticle(*thisTruth, accept);
651
652 // Fill truth only entries with dummy track values
653 m_monPlots->fillNtuple(*thisTruth);
654 }
655 }
656
657 if (nSelectedRecoTracks == nMissingAssociatedTruth) {
658 if (not m_truthParticleName.key().empty()) {
659 ATH_MSG_DEBUG("NO TRACKS had associated truth.");
660 }
661 } else {
662 ATH_MSG_DEBUG(nAssociatedTruth << " tracks out of " << tracks->size() << " had associated truth.");
663 }
664
665 m_monPlots->fillCounter(nSelectedRecoTracks, InDetPerfPlot_nTracks::SELECTEDRECO, beamSpotWeight);
666 m_monPlots->fillCounter(tracks->size(), InDetPerfPlot_nTracks::ALLRECO, beamSpotWeight);
667 m_monPlots->fillCounter(nSelectedTruthTracks, InDetPerfPlot_nTracks::SELECTEDTRUTH, beamSpotWeight);
668 m_monPlots->fillCounter(nTruths, InDetPerfPlot_nTracks::ALLTRUTH, beamSpotWeight);
669 m_monPlots->fillCounter(nAssociatedTruth, InDetPerfPlot_nTracks::ALLASSOCIATEDTRUTH, beamSpotWeight);
670 m_monPlots->fillCounter(nSelectedMatchedTracks, InDetPerfPlot_nTracks::MATCHEDRECO, beamSpotWeight);
671
672 // Tracking In Dense Environment
675 getAsTruth,
676 truthParticlesVec,
677 *tracks,
678 primaryvertex,
679 beamSpotWeight) );
680 }
681 return StatusCode::SUCCESS;
682}
683
685 // Decorate outcome of track selection
686 m_dec_passedTrackSelection(track) = (bool)(passed);
687}
688
690 // Decorate outcome of truth selection
691 m_dec_passedTruthSelection(truth) = (bool)(passed);
692
693 // Decorate if selected by pileup switch
695}
696
698 if (!m_acc_hasTruthFilled.isAvailable(truth)) {
699 ATH_MSG_DEBUG("Truth particle not yet filled in ntuple");
700 return false;
701 }
702 return m_acc_hasTruthFilled(truth);
703}
704
706 if (!m_acc_selectedByPileupSwitch.isAvailable(truth)) {
707 ATH_MSG_DEBUG("Selected by pileup switch decoration requested from a truth particle but not available");
708 return false;
709 }
710 return m_acc_selectedByPileupSwitch(truth);
711}
712
713void InDetPhysValMonitoringTool::markSelectedByPileupSwitch(const std::vector<const xAOD::TruthParticle*> & truthParticles) const{
714 for (const auto& thisTruth: truthParticles) {
715 m_dec_selectedByPileupSwitch(*thisTruth) = true;
716 }
717}
718
719StatusCode
721 ATH_MSG_INFO("Booking hists " << name() << "with detailed level: " << m_detailLevel);
722 m_monPlots->initialize();
723 std::vector<HistData> hists = m_monPlots->retrieveBookedHistograms();
724 for (const auto& hist : hists) {
725 ATH_CHECK(regHist(hist.first, hist.second, all)); // ??
726 }
727 // do the same for Efficiencies, but there's a twist:
728 std::vector<EfficiencyData> effs = m_monPlots->retrieveBookedEfficiencies();
729 for (auto& eff : effs) {
730 // reg**** in the monitoring baseclass doesnt have a TEff version, but TGraph *
731 // pointers just get passed through, so we use that method after an ugly cast
732 ATH_CHECK(regGraph(reinterpret_cast<TGraph*>(eff.first), eff.second, all)); // ??
733 }
734 // register trees for ntuple writing
736 std::vector<TreeData> trees = m_monPlots->retrieveBookedTrees();
737 for (auto& t : trees) {
738 ATH_CHECK(regTree(t.first, t.second, all));
739 }
740 }
741
742 return StatusCode::SUCCESS;
743}
744
745StatusCode
747 ATH_MSG_INFO("Finalising hists " << name() << "...");
748 //TODO: ADD Printouts for Truth??
750 ATH_MSG_INFO("");
751 ATH_MSG_INFO("Now Cutflow for track cuts:");
752 ATH_MSG_INFO("");
753 for (int i = 0; i < (int) m_trackCutflow.size(); ++i) {
754 ATH_MSG_INFO("number after " << m_trackCutflowNames[i] << ": " << m_trackCutflow[i]);
755 }
756 }
757
758 ATH_MSG_INFO("");
759 ATH_MSG_INFO("Cutflow for truth tracks:");
760 if (m_truthSelectionTool.get()) {
761 ATH_MSG_INFO("Truth selection report: " << m_truthCutFlow.report( m_truthSelectionTool->names()) );
762 }
763 if (endOfRunFlag()) {
764 m_monPlots->finalize();
765 }
766 ATH_MSG_INFO("Successfully finalized hists");
767 return StatusCode::SUCCESS;
768}
769
770const std::vector<const xAOD::TruthParticle*>
771InDetPhysValMonitoringTool::getTruthParticles(const EventContext& ctx) const {
772
773 std::vector<const xAOD::TruthParticle*> tempVec {};
774
775 if (m_pileupSwitch == "All") {
776 if (m_truthParticleName.key().empty()) {
777 return tempVec;
778 }
780 if (not truthParticleContainer.isValid()) {
781 return tempVec;
782 }
783 tempVec.insert(tempVec.begin(), truthParticleContainer->begin(), truthParticleContainer->end());
784 } else {
785 if (m_pileupSwitch == "HardScatter") {
786 // get truthevent container to separate out pileup and hardscatter truth particles
787 if (not m_truthEventName.key().empty()) {
789 const xAOD::TruthEvent* event = (truthEventContainer.isValid()) ? truthEventContainer->at(0) : nullptr;
790 if (not event) {
791 return tempVec;
792 }
793 const auto& links = event->truthParticleLinks();
794 tempVec.reserve(event->nTruthParticles());
795 for (const auto& link : links) {
796 if (link.isValid()){
797 tempVec.push_back(*link);
798 }
799 }
800 }
801 } else if (m_pileupSwitch == "PileUp") {
802 if (not m_truthPileUpEventName.key().empty()) {
803 ATH_MSG_VERBOSE("getting TruthPileupEvents container");
804 // get truth particles from all pileup events
806 if (truthPileupEventContainer.isValid()) {
807 const unsigned int nPileup = truthPileupEventContainer->size();
808 tempVec.reserve(nPileup * 200); // quick initial guess, will still save some time
809 for (unsigned int i(0); i != nPileup; ++i) {
810 const auto *eventPileup = truthPileupEventContainer->at(i);
811 // get truth particles from each pileup event
812 int ntruth = eventPileup->nTruthParticles();
813 ATH_MSG_VERBOSE("Adding " << ntruth << " truth particles from TruthPileupEvents container");
814 const auto& links = eventPileup->truthParticleLinks();
815 for (const auto& link : links) {
816 if (link.isValid()){
817 tempVec.push_back(*link);
818 }
819 }
820 }
821 } else {
822 ATH_MSG_ERROR("no entries in TruthPileupEvents container!");
823 }
824 }
825 } else {
826 ATH_MSG_ERROR("bad value for PileUpSwitch");
827 }
828 }
829 return tempVec;
830}
831
832std::pair<std::vector<const xAOD::TruthVertex*>, std::vector<const xAOD::TruthVertex*>>
833InDetPhysValMonitoringTool::getTruthVertices(const EventContext& ctx) const {
834
835 std::vector<const xAOD::TruthVertex*> truthHSVertices = {};
836 truthHSVertices.reserve(5);
837 std::vector<const xAOD::TruthVertex*> truthPUVertices = {};
838 truthPUVertices.reserve(100);
839 const xAOD::TruthVertex* truthVtx = nullptr;
840
841 bool doHS = false;
842 bool doPU = false;
843 if (m_pileupSwitch == "All") {
844 doHS = true;
845 doPU = true;
846 }
847 else if (m_pileupSwitch == "HardScatter") {
848 doHS = true;
849 }
850 else if (m_pileupSwitch == "PileUp") {
851 doPU = true;
852 }
853 else {
854 ATH_MSG_ERROR("Bad value for PileUpSwitch: " << m_pileupSwitch);
855 }
856
857 if (doHS) {
858 if (not m_truthEventName.key().empty()) {
859 ATH_MSG_VERBOSE("Getting HS TruthEvents container.");
861 if (truthEventContainer.isValid()) {
862 for (const auto *const evt : *truthEventContainer) {
863 truthVtx = evt->signalProcessVertex();
864 if (truthVtx) {
865 truthHSVertices.push_back(truthVtx);
866 }
867 }
868 }
869 else {
870 ATH_MSG_ERROR("No entries in TruthEvents container!");
871 }
872 }
873 }
874
875 if (doPU) {
876 if (not m_truthPileUpEventName.key().empty()) {
877 ATH_MSG_VERBOSE("Getting PU TruthEvents container.");
879 if (truthPileupEventContainer.isValid()) {
880 for (const auto *const evt : *truthPileupEventContainer) {
881 // Get the PU vertex
882 // In all cases tested i_vtx=2 for PU
883 // but better to keep something generic
884 truthVtx = nullptr;
885 size_t i_vtx = 0; size_t n_vtx = evt->nTruthVertices();
886 while(!truthVtx && i_vtx<n_vtx){
887 truthVtx = evt->truthVertex(i_vtx);
888 i_vtx++;
889 }
890
891 if (truthVtx) {
892 truthPUVertices.push_back(truthVtx);
893 }
894 }
895 }
896 else {
897 ATH_MSG_DEBUG("No entries in TruthPileupEvents container");
898 }
899 }
900 }
901
902 return {std::move(truthHSVertices), std::move(truthPUVertices)};
903}
904
905void
909
910void
911InDetPhysValMonitoringTool::fillCutFlow(const asg::AcceptData& accept, std::vector<std::string>& names,
912 std::vector<int>& cutFlow) {
913 // initialise cutflows
914 if (cutFlow.empty()) {
915 names.emplace_back("preCut");
916 cutFlow.push_back(0);
917 for (unsigned int i = 0; i != accept.getNCuts(); ++i) {
918 cutFlow.push_back(0);
919 names.push_back((std::string) accept.getCutName(i));
920 }
921 }
922 // get cutflow
923 cutFlow[0] += 1;
924 bool cutPositive = true;
925 for (unsigned int i = 0; i != (accept.getNCuts() + 1); ++i) {
926 if (!cutPositive) {
927 continue;
928 }
929 if (accept.getCutResult(i)) {
930 cutFlow[i + 1] += 1;
931 } else {
932 cutPositive = false;
933 }
934 }
935 }
936
938 double absEta = std::abs(truth.eta());
939 if (absEta > m_etaBins.value().back() || absEta < m_etaBins.value().front()) {
940 absEta = std::clamp(absEta, m_etaBins.value().front(), m_etaBins.value().back());
941 ATH_MSG_INFO("Requesting cut value outside of configured eta range: clamping eta = "
942 << std::abs(truth.eta()) << " to eta= " << absEta);
943 } else
944 absEta = std::clamp(absEta, m_etaBins.value().front(), m_etaBins.value().back());
945 const auto pVal = std::lower_bound(m_etaBins.value().begin(), m_etaBins.value().end(), absEta);
946 const int bin = std::distance(m_etaBins.value().begin(), pVal) - 1;
947 ATH_MSG_DEBUG("Checking (abs(eta)/bin) = (" << absEta << "," << bin << ")");
948 return bin;
949}
950
952 IDPVM::CachedGetAssocTruth& getAsTruth,
953 const std::vector<const xAOD::TruthParticle*>& truthParticles,
954 const xAOD::TrackParticleContainer& tracks,
955 const xAOD::Vertex* primaryvertex,
956 float beamSpotWeight) {
957 // Define accessors
958 static const SG::ConstAccessor<std::vector<ElementLink<xAOD::IParticleContainer> > > ghosttruth("GhostTruth");
959 static const SG::ConstAccessor<int> btagLabel("HadronConeExclTruthLabelID");
960
961 if (truthParticles.empty()) {
962 ATH_MSG_WARNING("No entries in TruthParticles truth particle container. Skipping jet plots.");
963 return StatusCode::SUCCESS;
964 }
965
967 if (not jetHandle.isValid()) {
968 ATH_MSG_WARNING("Cannot open jet container " << m_jetContainerName.key() << ". Skipping jet plots.");
969 return StatusCode::SUCCESS;
970 }
971 const xAOD::JetContainer* jets = jetHandle.cptr();
972
973 // loop on jets
974 for (const xAOD::Jet *const thisJet: *jets) {
975 // pass jet cuts
976 if (not passJetCuts(*thisJet)) continue;
977 // check if b-jet
978 bool isBjet = false;
979 if (not btagLabel.isAvailable(*thisJet)){
980 ATH_MSG_WARNING("Failed to extract b-tag truth label from jet");
981 } else {
982 isBjet = (btagLabel(*thisJet) == 5);
983 }
984
985 // Retrieve associated ghost truth particles
986 if(not ghosttruth.isAvailable(*thisJet)) {
987 ATH_MSG_WARNING("Failed to extract ghost truth particles from jet");
988 } else {
989 for(const ElementLink<xAOD::IParticleContainer>& el : ghosttruth(*thisJet)) {
990 if (not el.isValid()) continue;
991
992 const xAOD::TruthParticle *truth = static_cast<const xAOD::TruthParticle*>(*el);
993
994 // Check if ghost truth is in event TruthParticle vector
995 if (m_pileupSwitch != "All") {
996 if (std::find(truthParticles.begin(), truthParticles.end(), truth) == truthParticles.end()) {
997 continue;
998 }
999 }
1000
1001 // Check delta R between track and jet axis
1002 if (thisJet->p4().DeltaR(truth->p4()) > m_maxTrkJetDR) {
1003 continue;
1004 }
1005 // Apply truth selection cuts
1006 const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(truth);
1007 if(!accept) continue;
1008
1009 bool isEfficient(false);
1010
1011 for (const auto *thisTrack: tracks) {
1012 if (m_useTrackSelection and not (m_trackSelectionTool->accept(*thisTrack, primaryvertex))) {
1013 continue;
1014 }
1015
1016 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
1017 if (associatedTruth and associatedTruth == truth) {
1018 float prob = getMatchingProbability(*thisTrack);
1019 if (not std::isnan(prob) && prob > m_lowProb) {
1020 isEfficient = true;
1021 break;
1022 }
1023 }
1024 }
1025
1026 bool truthIsFromB = false;
1027 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(truth, 5) ) {
1028 truthIsFromB = true;
1029 }
1030 m_monPlots->fillEfficiency(*truth, *thisJet, isEfficient, isBjet, truthIsFromB, beamSpotWeight);
1031 }
1032 } // ghost truth
1033
1034 // loop on tracks
1035 for (const xAOD::TrackParticle *thisTrack: tracks) {
1036 if (m_useTrackSelection and not (m_trackSelectionTool->accept(*thisTrack, primaryvertex))) {
1037 continue;
1038 }
1039
1040 if (thisJet->p4().DeltaR(thisTrack->p4()) > m_maxTrkJetDR) {
1041 continue;
1042 }
1043
1044 float prob = getMatchingProbability(*thisTrack);
1045 if(std::isnan(prob)) prob = 0.0;
1046
1047 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
1048 const bool isFake = (associatedTruth && prob < m_lowProb);
1049 bool truthIsFromB = false;
1050 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(associatedTruth, 5) ) {
1051 truthIsFromB = true;
1052 }
1053 m_monPlots->fill(*thisTrack, *thisJet, isBjet, isFake, truthIsFromB, beamSpotWeight);
1054 if (associatedTruth){
1055 m_monPlots->fillFakeRate(*thisTrack, *thisJet, isFake, isBjet, truthIsFromB, beamSpotWeight);
1056 }
1057 }
1058
1059 } // loop on jets
1060
1061 return StatusCode::SUCCESS;
1062}
1063
1064bool
1066 const float jetPt = jet.pt();
1067 const float jetEta = std::abs(jet.eta());
1068
1069 if (jetEta < m_jetAbsEtaMin) return false;
1070 if (jetEta > m_jetAbsEtaMax) return false;
1071 if (jetPt < m_jetPtMin) return false;
1072 if (jetPt > m_jetPtMax) return false;
1073 return true;
1074}
#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::ReadHandleKey< xAOD::VertexContainer > m_vertexContainerName
Primary vertex container's name.
const std::vector< const xAOD::TruthParticle * > getTruthParticles(const EventContext &ctx) const
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::Decorator< bool > m_dec_passedTrackSelection
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::Decorator< bool > m_dec_selectedByPileupSwitch
ToolHandle< InDet::IInDetTrackTruthOriginTool > m_trackTruthOriginTool
SG::Accessor< bool > m_acc_selectedByPileupSwitch
BooleanProperty m_useTrackSelection
Properties to fine-tune the tool behaviour.
void fillTrackCutFlow(const asg::AcceptData &accept)
SG::Decorator< bool > m_dec_passedTruthSelection
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
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