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} ));
125 ATH_CHECK(m_grlTool.retrieve(EnableTool{m_useGRL}));
126
127 ATH_MSG_DEBUG("m_useVertexTruthMatchTool ====== " <<m_useVertexTruthMatchTool);
128 if (m_truthSelectionTool.get() ) {
129 m_truthCutFlow = CutFlow(m_truthSelectionTool->nCuts());
130 }
131
132 m_monPlots = std::make_unique<InDetRttPlots>
133 (nullptr, static_cast<std::string>(m_dirName) + static_cast<std::string>(m_folder),
134 getFilledPlotConfig()); // m_detailLevel := DEBUG, enable expert histograms
135
136 ATH_CHECK( m_trkParticleName.initialize() );
137 ATH_CHECK( m_truthParticleName.initialize( (m_pileupSwitch == "HardScatter" or m_pileupSwitch == "All") and not m_truthParticleName.key().empty() ) );
138 if (not m_truthParticleName.key().empty()) {
139 // create decor handle keys for truth particle decorations which are needed by CachedGetAssocTruth
140 // The existence of the handles is good enough to ensure that data dependencies are propagated
141 // and that the decorations exist when this tool is being called. Albeit not very elegant
142 // there is no need to create decor handles for the keys and use those instead of static
143 // accessors. To keep changes minimal the original static accessors are not replaced.
144 std::vector<std::string> trk_decorations;
148 "" /* no configurable prefix*/,
149 trk_decorations,
151 }
152 ATH_CHECK( m_vertexContainerName.initialize( not m_vertexContainerName.empty() ) );
153 ATH_CHECK( m_truthVertexContainerName.initialize( not m_truthVertexContainerName.key().empty() ) );
154 ATH_CHECK( m_eventInfoContainerName.initialize() );
155
156 ATH_CHECK( m_truthEventName.initialize( (m_pileupSwitch == "HardScatter" or m_pileupSwitch == "All") and not m_truthEventName.key().empty() ) );
157 ATH_CHECK( m_truthPileUpEventName.initialize( (m_pileupSwitch == "PileUp" or m_pileupSwitch == "All") and not m_truthPileUpEventName.key().empty() ) );
158 ATH_CHECK( m_jetContainerName.initialize( m_doTrackInJetPlots and not m_jetContainerName.key().empty()) );
159
160 std::vector<std::string> required_float_track_decorations {"d0","hitResiduals_residualLocX","d0err"};
161 std::vector<std::string> required_int_track_decorations {};
162 std::vector<std::string> required_float_truth_decorations {"d0"};
163 std::vector<std::string> required_int_truth_decorations {};
164 std::vector<std::string> required_int_jet_decorations {"HadronConeExclTruthLabelID"};
165 // The CSV file is for storing event data related to track overlay ML training purposes.
166 if (!m_setCSVName.empty()) {
168 ATH_MSG_INFO("Accessing csv file with name " <<m_setCSVName<< "...");
169 m_datfile <<"EvtNumber,PdgID,Px,Py,Pz,E,Pt,Eta,Phi,Mass,numPU,numvtx,MatchProb"<<std::endl;
170 }
171 std::string empty_prefix;
172 IDPVM::addReadDecoratorHandleKeys(*this, m_trkParticleName, empty_prefix, required_float_track_decorations, m_floatTrkDecor);
173 IDPVM::addReadDecoratorHandleKeys(*this, m_trkParticleName, empty_prefix, required_int_truth_decorations, m_intTrkDecor);
174 if (!m_truthParticleName.key().empty()) {
175 IDPVM::addReadDecoratorHandleKeys(*this, m_truthParticleName, empty_prefix, required_float_truth_decorations, m_floatTruthDecor);
176 IDPVM::addReadDecoratorHandleKeys(*this, m_truthParticleName, empty_prefix, required_int_truth_decorations, m_intTruthDecor);
177 }
179 IDPVM::addReadDecoratorHandleKeys(*this, m_jetContainerName, empty_prefix, required_int_jet_decorations, m_intJetDecor);
180 }
181
183
185 return StatusCode::SUCCESS;
186}
187
188
190
191
192 InDetRttPlotConfig rttConfig;
193 rttConfig.detailLevel = m_detailLevel;
194
195 rttConfig.isITk = m_isITk;
196 rttConfig.hasHGTDReco = m_hasHGTDReco;
197
202
204 rttConfig.doHitEffPlot = m_doHitLevelPlots;
205
210
213
215
221
223
226
228 if (m_truthParticleName.key().empty()){
229 rttConfig.doFakePlots = false;
230 rttConfig.doMissingTruthFakePlots = false;
231 rttConfig.doHitsFakeTracksPlots = false;
232 rttConfig.doHitsUnlinkedTracksPlots = 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_unlinked_bjets = false;
247 rttConfig.doTrkInJetPlots_truthFromB = false;
248 rttConfig.doResolutionPlotPrim_truthFromB = false;
249 }
250
252 if (m_onlyFillMatched){
253 rttConfig.doTrackParameters = false;
254 rttConfig.doNTracks = false;
255 rttConfig.doHitResidualPlot = false;
256 rttConfig.doHitEffPlot = false;
257 rttConfig.doHitsRecoTracksPlots = false;
258 rttConfig.doTrtExtensionPlots = false;
259 rttConfig.doFakePlots = false;
260 rttConfig.doMissingTruthFakePlots = false;
261 rttConfig.doHitsFakeTracksPlots = false;
262 rttConfig.doHitsUnlinkedTracksPlots = false;
263 rttConfig.doVertexPlots = false;
264 rttConfig.doVerticesVsMuPlots = false;
265 rttConfig.doHardScatterVertexPlots = false;
266 rttConfig.doVertexTruthMatchingPlots = false;
268 rttConfig.doTrkInJetPlots = false;
269 rttConfig.doTrkInJetPlots_bjets = false;
270 rttConfig.doTrkInJetPlots_matched = false;
271 rttConfig.doTrkInJetPlots_matched_bjets = false;
272 rttConfig.doTrkInJetPlots_fake = false;
273 rttConfig.doTrkInJetPlots_fake_bjets = false;
274 rttConfig.doTrkInJetPlots_unlinked = false;
275 rttConfig.doTrkInJetPlots_unlinked_bjets = false;
276 rttConfig.doTrkInJetPlots_truthFromB = false;
277 }
278
279 // For IDTIDE derivation
280 // disable the vertex plots since no covariance from IDTIDE
281 if (m_doIDTIDEPlots){
282 rttConfig.doVertexPlots = false;
283 rttConfig.doVerticesVsMuPlots = false;
284 rttConfig.doHardScatterVertexPlots = false;
285 rttConfig.doVertexTruthMatchingPlots = false;
287 rttConfig.doTrkInJetPlots = true;
288 rttConfig.doTrkInJetPlots_bjets = true;
289 rttConfig.doTrkInJetPlots_matched = true;
290 rttConfig.doTrkInJetPlots_matched_bjets = true;
291 rttConfig.doTrkInJetPlots_fake = true;
292 rttConfig.doTrkInJetPlots_fake_bjets = true;
293 rttConfig.doTrkInJetPlots_unlinked = true;
294 rttConfig.doTrkInJetPlots_unlinked_bjets = true;
295 rttConfig.doTrkInJetPlots_truthFromB = true;
296 }
297
299 if (m_detailLevel < 200){
300 rttConfig.doResolutionPlotSecd = false;
301 rttConfig.doHitsMatchedTracksPlots = false;
302 rttConfig.doHitsFakeTracksPlots = false;
303 rttConfig.doHitsUnlinkedTracksPlots = false;
304 rttConfig.doVertexTruthMatchingPlots = false;
305 rttConfig.doFakesPerAuthor = false;
306 rttConfig.doTrackParametersPerAuthor = false;
307 rttConfig.doEfficienciesPerAuthor = false;
308 rttConfig.doResolutionsPerAuthor = false;
309 rttConfig.doTrkInJetPlots_matched = false;
310 rttConfig.doTrkInJetPlots_fake = false;
311 rttConfig.doTrkInJetPlots_unlinked = false;
312 rttConfig.doTrkInJetPlots_matched_bjets = false;
313 rttConfig.doTrkInJetPlots_fake_bjets = false;
314 rttConfig.doTrkInJetPlots_unlinked_bjets = false;
315 }
316
317 return rttConfig;
318}
319
320StatusCode
322 ATH_MSG_DEBUG("Filling hists " << name() << "...");
323 // function object could be used to retrieve truth: IDPVM::CachedGetAssocTruth getTruth;
324
325 // Get the Event Context
326 const EventContext& ctx = Gaudi::Hive::currentContext();
327
328 // retrieve trackParticle container
330 if (not trackHandle.isValid()) {
331 ATH_MSG_ERROR("Invalid trackname = " << m_trkParticleName << "!");
332 return StatusCode::FAILURE;
333 }
334 const xAOD::TrackParticleContainer* tracks = trackHandle.cptr();
335
336 SG::ReadHandle<xAOD::TruthPileupEventContainer> truthPileupEventContainer;
337 if( not m_truthPileUpEventName.key().empty()) {
339 }
340
342 if (not pie.isValid()){
343 ATH_MSG_WARNING("Shouldn't happen - EventInfo is buggy, setting mu to 0");
344 }
345
346 // FIX-ME: I'm not sure if we should stop execution if EventInfo is not valid ...
347 // it is used after as if they assume it is valid
348 if (m_useGRL and pie.isValid() and !pie->eventType(xAOD::EventInfo::IS_SIMULATION)) {
349 if (!m_grlTool->passRunLB(*pie)) {
350 ATH_MSG_VERBOSE("GRL veto");
351 return StatusCode::SUCCESS;
352 }
353 }
354
355 std::vector<const xAOD::TruthParticle*> truthParticlesVec = getTruthParticles(ctx);
356
357 // Mark the truth particles in our vector as "selected".
358 // This is needed because we later access the truth matching via xAOD decorations, where we do not 'know' about membership to this vector.
360 const xAOD::EventInfo *eventInfo = nullptr;
361 ATH_CHECK (evtStore()->retrieve (eventInfo, "EventInfo"));
362 IDPVM::CachedGetAssocTruth getAsTruth; // only cache one way, track->truth, not truth->tracks
363
364 unsigned int truthMu = 0;
365 float actualMu = 0.;
366 if(not m_truthPileUpEventName.key().empty() and truthPileupEventContainer.isValid()){
367 truthMu = static_cast<int>( truthPileupEventContainer->size() );
368 }
369 if(pie.isValid()) actualMu = pie->actualInteractionsPerCrossing();
370
371 // This is questionable but kept for backward compatibility for now
372 float puEvents = truthMu>0 ? truthMu : actualMu;
373
374 const xAOD::Vertex* primaryvertex = nullptr;
375 unsigned int nVertices = 0;
376 float beamSpotWeight = 1;
377
378 if(not m_vertexContainerName.key().empty()){
379 ATH_MSG_DEBUG("Getting number of pu interactings per event");
380
381 ATH_MSG_DEBUG("Filling vertex plots");
383 ATH_CHECK(vertices.isValid());
384
385 nVertices = not vertices->empty() ? vertices->size() : 0;
386 beamSpotWeight = pie->beamSpotWeight();
387 ATH_MSG_DEBUG("beamSpotWeight is equal to " << beamSpotWeight);
388 if(m_doPRW){
389 float prwWeight = 1;
391 if(readDecorHandle.isAvailable()) prwWeight = readDecorHandle(*pie);
392 ATH_MSG_DEBUG("Applying pileup weight equal to " << prwWeight);
393 beamSpotWeight *= prwWeight;
394 }
395
396 if (vertices.isValid() and not vertices->empty()) {
397 ATH_MSG_DEBUG("Number of vertices retrieved for this event " << vertices->size());
398 //Find the HS vertex following the user-configured strategy
399 primaryvertex = m_hardScatterSelectionTool->getHardScatter(vertices.get());
400 if (!primaryvertex){
403 ATH_MSG_DEBUG("Failed to find a hard scatter vertex in this event.");
404 }
405 //Filling plots for all reconstructed vertices and the hard-scatter
406 ATH_MSG_DEBUG("Filling vertices info monitoring plots");
407
408 // Fill vectors of truth HS and PU vertices
409 std::pair<std::vector<const xAOD::TruthVertex*>, std::vector<const xAOD::TruthVertex*>> truthVertices = getTruthVertices(ctx);
410 std::vector<const xAOD::TruthVertex*> truthHSVertices = truthVertices.first;
411 std::vector<const xAOD::TruthVertex*> truthPUVertices = truthVertices.second;
412
413 // Decorate vertices
415 ATH_CHECK(m_vtxValidTool->matchVertices(*vertices));
416 ATH_MSG_DEBUG("Hard scatter classification type: " << InDetVertexTruthMatchUtils::classifyHardScatter(*vertices) << ", vertex container size = " << vertices->size());
417 }
418 m_monPlots->fill(*vertices, primaryvertex, truthHSVertices, truthPUVertices, actualMu, beamSpotWeight);
419
420 ATH_MSG_DEBUG("Filling vertex/event info monitoring plots");
421 //Filling vertexing plots for the reconstructed hard-scatter as a function of mu
422 m_monPlots->fill(*vertices, truthMu, actualMu, beamSpotWeight);
423 } else {
424 //FIXME: Does this happen for single particles?
425 ATH_MSG_WARNING("Skipping vertexing plots.");
426 }
427 }
428
429 if( not m_truthVertexContainerName.key().empty()){
430 // get truth vertex container name - m_truthVertexContainerName
432
433 //
434 //Get the HS vertex position from the truthVertexContainer
435 //FIXME: Add plots w.r.t truth HS positions (vertexing plots)
436 //
437 const xAOD::TruthVertex* truthVertex = nullptr;
438 if (truthVrt.isValid()) {
439 const auto& stdVertexContainer = truthVrt->stdcont();
440 //First truth particle vertex?
441 auto findVtx = std::find_if(stdVertexContainer.rbegin(), stdVertexContainer.rend(), acceptTruthVertex);
442 truthVertex = (findVtx == stdVertexContainer.rend()) ? nullptr : *findVtx;
443 } else {
444 ATH_MSG_WARNING("Cannot open " << m_truthVertexContainerName.key() << " truth vertex container");
445 }
446 if (not truthVertex) ATH_MSG_INFO ("Truth vertex did not pass cuts");
447 }
448 //
449 //Counters for cutflow
450 //
451 unsigned int nSelectedTruthTracks(0), nSelectedRecoTracks(0), nSelectedMatchedTracks(0), nAssociatedTruth(0), nMissingAssociatedTruth(0), nTruths(0);
452
453 CutFlow tmp_truth_cutflow( m_truthSelectionTool.get() ? m_truthSelectionTool->nCuts() : 0 );
454
455 //
456 //Loop over all reconstructed tracks
457 //
458 // If writing ntuples, use a truth-to-track(s) cache to handle truth matching.
459 // Based on the assumption that multiple tracks can (albeit rarely) share the same truth association.
460 std::map<const xAOD::TruthParticle*, std::vector<const xAOD::TrackParticle*>> cacheTruthMatching {};
461 //
462 std::vector<const xAOD::TrackParticle*> selectedTracks {};
463 selectedTracks.reserve(tracks->size());
464 unsigned int nTrackTOT = 0;
465 unsigned int nTrackCentral = 0;
466 unsigned int nTrackPt1GeV = 0;
467 for (const auto *const thisTrack: *tracks) {
468 //FIXME: Why is this w.r.t the primary vertex?
469 const asg::AcceptData& accept = m_trackSelectionTool->accept(*thisTrack, primaryvertex);
470 if (m_useTrackSelection and not accept) continue;
471 fillTrackCutFlow(accept); //?? Is this equal???
472
473 selectedTracks.push_back(thisTrack);
474 //Number of selected reco tracks
475 nSelectedRecoTracks++;
476
477 //Fill plots for selected reco tracks, hits / perigee / ???
478 nTrackTOT++;
479 if (thisTrack->pt() >= (1 * Gaudi::Units::GeV))
480 nTrackPt1GeV++;
481 if (std::abs(thisTrack->eta()) < 2.5)
482 nTrackCentral++;
483 m_monPlots->fill(*thisTrack, beamSpotWeight);
484 m_monPlots->fill(*thisTrack, puEvents, nVertices, beamSpotWeight); //fill mu dependent plots
485 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
486 float prob = getMatchingProbability(*thisTrack);
487
488 // This is where the Fake, and Really Fake fillers need to go. Where would the really really fakes go?
489 if (associatedTruth) {
490 nAssociatedTruth++;
491
492 // if there is associated truth also a truth selection tool was retrieved.
495 //FIXME: What is this for???
496 tmp_truth_cutflow.update( passed.missingCuts() );
497 }
498
499 if ((not std::isnan(prob)) and (prob > m_lowProb) and passed and (not m_usingSpecialPileupSwitch or isSelectedByPileupSwitch(*associatedTruth)) ) {
500 nSelectedMatchedTracks++;
501 bool truthIsFromB = false;
502 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(associatedTruth, 5) ) {
503 truthIsFromB = true;
504 }
505 m_monPlots->fill(*thisTrack, *associatedTruth, truthIsFromB, puEvents, beamSpotWeight); // Make plots requiring matched truth
506 }
507 }
508
509 const bool isAssociatedTruth = associatedTruth != nullptr;
510 const bool isFake = not std::isnan(prob) ? (prob < m_lowProb) : true;
511
512 if(!isAssociatedTruth) nMissingAssociatedTruth++;
513 m_monPlots->fillFakeRate(*thisTrack, isFake, isAssociatedTruth, puEvents, beamSpotWeight);
514
516 // Decorate track particle with extra flags
517 decorateTrackParticle(*thisTrack, accept);
518
519 if (isAssociatedTruth) {
520 // Decorate truth particle with extra flags
521 decorateTruthParticle(*associatedTruth, m_truthSelectionTool->accept(associatedTruth));
522
523 // Cache truth-to-track associations
524 auto cachedAssoc = cacheTruthMatching.find(associatedTruth);
525 // Check if truth particle already present in cache
526 if (cachedAssoc == cacheTruthMatching.end()) {
527 // If not yet present, add truth-to-track association in cache
528 cacheTruthMatching[associatedTruth] = {thisTrack};
529 }
530 else {
531 // If already present, cache additional track associations (here multiple track particle can be linked to the same truth particle)
532 cachedAssoc->second.push_back(thisTrack);
533 }
534 }
536 // Fill track only entries with dummy truth values
537 m_monPlots->fillNtuple(*thisTrack, primaryvertex);
538 }
539 }
540 }
542 // Now fill all truth-to-track associations
543 // Involves some double-filling of truth particles in cases where multiple tracks share the same truth association,
544 // these duplicates can be filtered in the ntuple by selecting only the 'best matched' truth-associated track particles.
545 for (auto& cachedAssoc: cacheTruthMatching) {
546 const xAOD::TruthParticle* thisTruth = cachedAssoc.first;
547
548 // Decorate that this truth particle is being filled to prevent double counting in truth particle loop
549 m_dec_hasTruthFilled(*thisTruth) = true;
550
551 // Sort all associated tracks by truth match probability
552 std::sort(cachedAssoc.second.begin(), cachedAssoc.second.end(),
553 [](const xAOD::TrackParticle* t1, const xAOD::TrackParticle* t2) { return getMatchingProbability(*t1) > getMatchingProbability(*t2); }
554 );
555
557 // Fill all tracks associated to to this truth particle, also recording 'truth match ranking' as index in probability-sorted vector of matched tracks
558 for (int itrack = 0; itrack < (int) cachedAssoc.second.size(); itrack++) {
559 const xAOD::TrackParticle* thisTrack = cachedAssoc.second[itrack];
560
561 // Fill track entries with truth association
562 m_monPlots->fillNtuple(*thisTrack, *thisTruth, primaryvertex, itrack);
563 }
564 }
565 }
566 }
567
568 m_monPlots->fill(nTrackTOT, nTrackCentral, nTrackPt1GeV, truthMu, actualMu, nVertices, beamSpotWeight);
569
570 //FIXME: I don't get why... this is here
571 if (m_truthSelectionTool.get()) {
572 ATH_MSG_DEBUG( CutFlow(tmp_truth_cutflow).report(m_truthSelectionTool->names()) );
573 std::lock_guard<std::mutex> lock(m_mutex);
574 m_truthCutFlow.merge(std::move(tmp_truth_cutflow));
575 }
576
577 //
578 //TruthParticle loop to fill efficiencies
579 //
580 for (int itruth = 0; itruth < (int) truthParticlesVec.size(); itruth++) { // Outer loop over all truth particles
581 nTruths++;
582 const xAOD::TruthParticle* thisTruth = truthParticlesVec[itruth];
583
584 // if the vector of truth particles is not empty also a truthSelectionTool was retrieved
585 const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(thisTruth);
586 if (accept) {
587 ++nSelectedTruthTracks; // total number of truth which pass cuts per event
588 bool isEfficient(false); // weight for the trackeff histos
589 float matchingProbability{};
590 m_monPlots->fill(*thisTruth, beamSpotWeight); // This is filling truth-only plots
591
593 auto cachedAssoc = cacheTruthMatching.find(thisTruth);
594 // Check if truth particle already present in cache
595 if (cachedAssoc == cacheTruthMatching.end()) {
596 // If not yet present, then no track associated
597 cacheTruthMatching[thisTruth] = {};
598 }
599 m_monPlots->fillDuplicate(*thisTruth, cacheTruthMatching[thisTruth], beamSpotWeight);
600 }
601
602 //
603 //Loop over reco tracks to find the match
604 //
605 const xAOD::TrackParticle* matchedTrack = nullptr;
606 for (const auto& thisTrack: selectedTracks) { // Inner loop over selected track particleis
607 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
608 if (associatedTruth && associatedTruth == thisTruth) {
609 float prob = getMatchingProbability(*thisTrack);
610 if (not std::isnan(prob) && prob > m_lowProb) {
611 matchingProbability = prob;
612 isEfficient = true;
613 matchedTrack = thisTrack;
614 break;
615 }
616 }
617 }
618 if (!m_setCSVName.empty()) {
619 m_datfile <<eventInfo->eventNumber()<<","<<thisTruth->pdgId()<<","<<thisTruth->px()/ Gaudi::Units::GeV<<","
620 <<thisTruth->py()/ Gaudi::Units::GeV<<","<<thisTruth->pz()/ Gaudi::Units::GeV<<","
621 <<thisTruth->e()/ Gaudi::Units::GeV<<","<<thisTruth->pt()/ Gaudi::Units::GeV<<","
622 <<thisTruth->eta()<<","<<thisTruth->phi()<<","<<thisTruth->m()/ Gaudi::Units::GeV<<","
623 <<puEvents<<","<<nVertices<<","<<matchingProbability<<std::endl;
624 }
625 if (!thisTruth){
626 ATH_MSG_ERROR("An error occurred: Truth particle for tracking efficiency calculation is a nullptr");
627 }
628 else if (isEfficient && !matchedTrack){
629 ATH_MSG_ERROR("Something went wrong - we log a truth particle as reconstructed, but the reco track is a nullptr! Bailing out... ");
630 }
631 else{
632 ATH_MSG_DEBUG("Filling efficiency plots info monitoring plots");
633 m_monPlots->fillEfficiency(*thisTruth, matchedTrack, isEfficient, truthMu, actualMu, beamSpotWeight);
635 ATH_MSG_DEBUG("Filling technical efficiency plots info monitoring plots");
636 static const SG::ConstAccessor< float > nSilHitsAcc("nSilHits");
637 if (nSilHitsAcc.isAvailable(*thisTruth)) {
638 if (nSilHitsAcc(*thisTruth) >= m_minHits.value().at(getIndexByEta(*thisTruth))){
639 m_monPlots->fillTechnicalEfficiency(*thisTruth, isEfficient,
640 truthMu, actualMu, beamSpotWeight);
641 }
642 } else {
643 ATH_MSG_DEBUG("Cannot fill technical efficiency. Missing si hit information for truth particle.");
644 }
645 }
646 }
647 }
648
650 // Skip if already filled in track loop
651 if (hasTruthFilled(*thisTruth)) continue;
652
653 // Decorate truth particle with extra flags
654 decorateTruthParticle(*thisTruth, accept);
655
656 // Fill truth only entries with dummy track values
657 m_monPlots->fillNtuple(*thisTruth);
658 }
659 }
660
661 if (nSelectedRecoTracks == nMissingAssociatedTruth) {
662 if (not m_truthParticleName.key().empty()) {
663 ATH_MSG_DEBUG("NO TRACKS had associated truth.");
664 }
665 } else {
666 ATH_MSG_DEBUG(nAssociatedTruth << " tracks out of " << tracks->size() << " had associated truth.");
667 }
668
669 m_monPlots->fillCounter(nSelectedRecoTracks, InDetPerfPlot_nTracks::SELECTEDRECO, beamSpotWeight);
670 m_monPlots->fillCounter(tracks->size(), InDetPerfPlot_nTracks::ALLRECO, beamSpotWeight);
671 m_monPlots->fillCounter(nSelectedTruthTracks, InDetPerfPlot_nTracks::SELECTEDTRUTH, beamSpotWeight);
672 m_monPlots->fillCounter(nTruths, InDetPerfPlot_nTracks::ALLTRUTH, beamSpotWeight);
673 m_monPlots->fillCounter(nAssociatedTruth, InDetPerfPlot_nTracks::ALLASSOCIATEDTRUTH, beamSpotWeight);
674 m_monPlots->fillCounter(nSelectedMatchedTracks, InDetPerfPlot_nTracks::MATCHEDRECO, beamSpotWeight);
675
676 // Tracking In Dense Environment
679 getAsTruth,
680 truthParticlesVec,
681 *tracks,
682 primaryvertex,
683 beamSpotWeight) );
684 }
685 return StatusCode::SUCCESS;
686}
687
689 // Decorate outcome of track selection
690 m_dec_passedTrackSelection(track) = (bool)(passed);
691}
692
694 // Decorate outcome of truth selection
695 m_dec_passedTruthSelection(truth) = (bool)(passed);
696
697 // Decorate if selected by pileup switch
699}
700
702 if (!m_acc_hasTruthFilled.isAvailable(truth)) {
703 ATH_MSG_DEBUG("Truth particle not yet filled in ntuple");
704 return false;
705 }
706 return m_acc_hasTruthFilled(truth);
707}
708
710 if (!m_acc_selectedByPileupSwitch.isAvailable(truth)) {
711 ATH_MSG_DEBUG("Selected by pileup switch decoration requested from a truth particle but not available");
712 return false;
713 }
714 return m_acc_selectedByPileupSwitch(truth);
715}
716
717void InDetPhysValMonitoringTool::markSelectedByPileupSwitch(const std::vector<const xAOD::TruthParticle*> & truthParticles) const{
718 for (const auto& thisTruth: truthParticles) {
719 m_dec_selectedByPileupSwitch(*thisTruth) = true;
720 }
721}
722
723StatusCode
725 ATH_MSG_INFO("Booking hists " << name() << "with detailed level: " << m_detailLevel);
726 m_monPlots->initialize();
727 std::vector<HistData> hists = m_monPlots->retrieveBookedHistograms();
728 for (const auto& hist : hists) {
729 ATH_CHECK(regHist(hist.first, hist.second, all)); // ??
730 }
731 // do the same for Efficiencies, but there's a twist:
732 std::vector<EfficiencyData> effs = m_monPlots->retrieveBookedEfficiencies();
733 for (auto& eff : effs) {
734 // reg**** in the monitoring baseclass doesnt have a TEff version, but TGraph *
735 // pointers just get passed through, so we use that method after an ugly cast
736 ATH_CHECK(regGraph(reinterpret_cast<TGraph*>(eff.first), eff.second, all)); // ??
737 }
738 // register trees for ntuple writing
740 std::vector<TreeData> trees = m_monPlots->retrieveBookedTrees();
741 for (auto& t : trees) {
742 ATH_CHECK(regTree(t.first, t.second, all));
743 }
744 }
745
746 return StatusCode::SUCCESS;
747}
748
749StatusCode
751 ATH_MSG_INFO("Finalising hists " << name() << "...");
752 //TODO: ADD Printouts for Truth??
754 ATH_MSG_INFO("");
755 ATH_MSG_INFO("Now Cutflow for track cuts:");
756 ATH_MSG_INFO("");
757 for (int i = 0; i < (int) m_trackCutflow.size(); ++i) {
758 ATH_MSG_INFO("number after " << m_trackCutflowNames[i] << ": " << m_trackCutflow[i]);
759 }
760 }
761
762 ATH_MSG_INFO("");
763 ATH_MSG_INFO("Cutflow for truth tracks:");
764 if (m_truthSelectionTool.get()) {
765 ATH_MSG_INFO("Truth selection report: " << m_truthCutFlow.report( m_truthSelectionTool->names()) );
766 }
767 if (endOfRunFlag()) {
768 m_monPlots->finalize();
769 }
770 ATH_MSG_INFO("Successfully finalized hists");
771 return StatusCode::SUCCESS;
772}
773
774const std::vector<const xAOD::TruthParticle*>
775InDetPhysValMonitoringTool::getTruthParticles(const EventContext& ctx) const {
776
777 std::vector<const xAOD::TruthParticle*> tempVec {};
778
779 if (m_pileupSwitch == "All") {
780 if (m_truthParticleName.key().empty()) {
781 return tempVec;
782 }
784 if (not truthParticleContainer.isValid()) {
785 return tempVec;
786 }
787 tempVec.insert(tempVec.begin(), truthParticleContainer->begin(), truthParticleContainer->end());
788 } else {
789 if (m_pileupSwitch == "HardScatter") {
790 // get truthevent container to separate out pileup and hardscatter truth particles
791 if (not m_truthEventName.key().empty()) {
793 const xAOD::TruthEvent* event = (truthEventContainer.isValid()) ? truthEventContainer->at(0) : nullptr;
794 if (not event) {
795 return tempVec;
796 }
797 const auto& links = event->truthParticleLinks();
798 tempVec.reserve(event->nTruthParticles());
799 for (const auto& link : links) {
800 if (link.isValid()){
801 tempVec.push_back(*link);
802 }
803 }
804 }
805 } else if (m_pileupSwitch == "PileUp") {
806 if (not m_truthPileUpEventName.key().empty()) {
807 ATH_MSG_VERBOSE("getting TruthPileupEvents container");
808 // get truth particles from all pileup events
810 if (truthPileupEventContainer.isValid()) {
811 const unsigned int nPileup = truthPileupEventContainer->size();
812 tempVec.reserve(nPileup * 200); // quick initial guess, will still save some time
813 for (unsigned int i(0); i != nPileup; ++i) {
814 const auto *eventPileup = truthPileupEventContainer->at(i);
815 // get truth particles from each pileup event
816 int ntruth = eventPileup->nTruthParticles();
817 ATH_MSG_VERBOSE("Adding " << ntruth << " truth particles from TruthPileupEvents container");
818 const auto& links = eventPileup->truthParticleLinks();
819 for (const auto& link : links) {
820 if (link.isValid()){
821 tempVec.push_back(*link);
822 }
823 }
824 }
825 } else {
826 ATH_MSG_ERROR("no entries in TruthPileupEvents container!");
827 }
828 }
829 } else {
830 ATH_MSG_ERROR("bad value for PileUpSwitch");
831 }
832 }
833 return tempVec;
834}
835
836std::pair<const std::vector<const xAOD::TruthVertex*>, const std::vector<const xAOD::TruthVertex*>>
837InDetPhysValMonitoringTool::getTruthVertices(const EventContext& ctx) const {
838
839 std::vector<const xAOD::TruthVertex*> truthHSVertices = {};
840 truthHSVertices.reserve(5);
841 std::vector<const xAOD::TruthVertex*> truthPUVertices = {};
842 truthPUVertices.reserve(100);
843 const xAOD::TruthVertex* truthVtx = nullptr;
844
845 bool doHS = false;
846 bool doPU = false;
847 if (m_pileupSwitch == "All") {
848 doHS = true;
849 doPU = true;
850 }
851 else if (m_pileupSwitch == "HardScatter") {
852 doHS = true;
853 }
854 else if (m_pileupSwitch == "PileUp") {
855 doPU = true;
856 }
857 else {
858 ATH_MSG_ERROR("Bad value for PileUpSwitch: " << m_pileupSwitch);
859 }
860
861 if (doHS) {
862 if (not m_truthEventName.key().empty()) {
863 ATH_MSG_VERBOSE("Getting HS TruthEvents container.");
865 if (truthEventContainer.isValid()) {
866 for (const auto *const evt : *truthEventContainer) {
867 truthVtx = evt->signalProcessVertex();
868 if (truthVtx) {
869 truthHSVertices.push_back(truthVtx);
870 }
871 }
872 }
873 else {
874 ATH_MSG_ERROR("No entries in TruthEvents container!");
875 }
876 }
877 }
878
879 if (doPU) {
880 if (not m_truthPileUpEventName.key().empty()) {
881 ATH_MSG_VERBOSE("Getting PU TruthEvents container.");
883 if (truthPileupEventContainer.isValid()) {
884 for (const auto *const evt : *truthPileupEventContainer) {
885 // Get the PU vertex
886 // In all cases tested i_vtx=2 for PU
887 // but better to keep something generic
888 truthVtx = nullptr;
889 size_t i_vtx = 0; size_t n_vtx = evt->nTruthVertices();
890 while(!truthVtx && i_vtx<n_vtx){
891 truthVtx = evt->truthVertex(i_vtx);
892 i_vtx++;
893 }
894
895 if (truthVtx) {
896 truthPUVertices.push_back(truthVtx);
897 }
898 }
899 }
900 else {
901 ATH_MSG_DEBUG("No entries in TruthPileupEvents container");
902 }
903 }
904 }
905
906 return std::make_pair<const std::vector<const xAOD::TruthVertex*>, const std::vector<const xAOD::TruthVertex*>>((const std::vector<const xAOD::TruthVertex*>)truthHSVertices, (const std::vector<const xAOD::TruthVertex*>)truthPUVertices);
907
908}
909
910void
914
915void
916InDetPhysValMonitoringTool::fillCutFlow(const asg::AcceptData& accept, std::vector<std::string>& names,
917 std::vector<int>& cutFlow) {
918 // initialise cutflows
919 if (cutFlow.empty()) {
920 names.emplace_back("preCut");
921 cutFlow.push_back(0);
922 for (unsigned int i = 0; i != accept.getNCuts(); ++i) {
923 cutFlow.push_back(0);
924 names.push_back((std::string) accept.getCutName(i));
925 }
926 }
927 // get cutflow
928 cutFlow[0] += 1;
929 bool cutPositive = true;
930 for (unsigned int i = 0; i != (accept.getNCuts() + 1); ++i) {
931 if (!cutPositive) {
932 continue;
933 }
934 if (accept.getCutResult(i)) {
935 cutFlow[i + 1] += 1;
936 } else {
937 cutPositive = false;
938 }
939 }
940 }
941
943 double absEta = std::abs(truth.eta());
944 if (absEta > m_etaBins.value().back() || absEta < m_etaBins.value().front()) {
945 absEta = std::clamp(absEta, m_etaBins.value().front(), m_etaBins.value().back());
946 ATH_MSG_INFO("Requesting cut value outside of configured eta range: clamping eta = "
947 << std::abs(truth.eta()) << " to eta= " << absEta);
948 } else
949 absEta = std::clamp(absEta, m_etaBins.value().front(), m_etaBins.value().back());
950 const auto pVal = std::lower_bound(m_etaBins.value().begin(), m_etaBins.value().end(), absEta);
951 const int bin = std::distance(m_etaBins.value().begin(), pVal) - 1;
952 ATH_MSG_DEBUG("Checking (abs(eta)/bin) = (" << absEta << "," << bin << ")");
953 return bin;
954}
955
957 IDPVM::CachedGetAssocTruth& getAsTruth,
958 const std::vector<const xAOD::TruthParticle*>& truthParticles,
959 const xAOD::TrackParticleContainer& tracks,
960 const xAOD::Vertex* primaryvertex,
961 float beamSpotWeight) {
962 // Define accessors
963 static const SG::ConstAccessor<std::vector<ElementLink<xAOD::IParticleContainer> > > ghosttruth("GhostTruth");
964 static const SG::ConstAccessor<int> btagLabel("HadronConeExclTruthLabelID");
965
966 if (truthParticles.empty()) {
967 ATH_MSG_WARNING("No entries in TruthParticles truth particle container. Skipping jet plots.");
968 return StatusCode::SUCCESS;
969 }
970
972 if (not jetHandle.isValid()) {
973 ATH_MSG_WARNING("Cannot open jet container " << m_jetContainerName.key() << ". Skipping jet plots.");
974 return StatusCode::SUCCESS;
975 }
976 const xAOD::JetContainer* jets = jetHandle.cptr();
977
978 // loop on jets
979 for (const xAOD::Jet *const thisJet: *jets) {
980 // pass jet cuts
981 if (not passJetCuts(*thisJet)) continue;
982 // check if b-jet
983 bool isBjet = false;
984 if (not btagLabel.isAvailable(*thisJet)){
985 ATH_MSG_WARNING("Failed to extract b-tag truth label from jet");
986 } else {
987 isBjet = (btagLabel(*thisJet) == 5);
988 }
989
990 // Retrieve associated ghost truth particles
991 if(not ghosttruth.isAvailable(*thisJet)) {
992 ATH_MSG_WARNING("Failed to extract ghost truth particles from jet");
993 } else {
994 for(const ElementLink<xAOD::IParticleContainer>& el : ghosttruth(*thisJet)) {
995 if (not el.isValid()) continue;
996
997 const xAOD::TruthParticle *truth = static_cast<const xAOD::TruthParticle*>(*el);
998 // Check delta R between track and jet axis
999 if (thisJet->p4().DeltaR(truth->p4()) > m_maxTrkJetDR) {
1000 continue;
1001 }
1002 // Apply truth selection cuts
1003 const IAthSelectionTool::CutResult accept = m_truthSelectionTool->accept(truth);
1004 if(!accept) continue;
1005
1006 bool isEfficient(false);
1007
1008 for (const auto *thisTrack: tracks) {
1009 if (m_useTrackSelection and not (m_trackSelectionTool->accept(*thisTrack, primaryvertex))) {
1010 continue;
1011 }
1012
1013 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
1014 if (associatedTruth and associatedTruth == truth) {
1015 float prob = getMatchingProbability(*thisTrack);
1016 if (not std::isnan(prob) && prob > m_lowProb) {
1017 isEfficient = true;
1018 break;
1019 }
1020 }
1021 }
1022
1023 bool truthIsFromB = false;
1024 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(truth, 5) ) {
1025 truthIsFromB = true;
1026 }
1027 m_monPlots->fillEfficiency(*truth, *thisJet, isEfficient, isBjet, truthIsFromB, beamSpotWeight);
1028 }
1029 } // ghost truth
1030
1031 // loop on tracks
1032 for (const xAOD::TrackParticle *thisTrack: tracks) {
1033 if (m_useTrackSelection and not (m_trackSelectionTool->accept(*thisTrack, primaryvertex))) {
1034 continue;
1035 }
1036
1037 if (thisJet->p4().DeltaR(thisTrack->p4()) > m_maxTrkJetDR) {
1038 continue;
1039 }
1040
1041 float prob = getMatchingProbability(*thisTrack);
1042 if(std::isnan(prob)) prob = 0.0;
1043
1044 const xAOD::TruthParticle* associatedTruth = getAsTruth.getTruth(thisTrack);
1045 const bool unlinked = (associatedTruth==nullptr);
1046 const bool isFake = (associatedTruth && prob < m_lowProb);
1047 bool truthIsFromB = false;
1048 if ( m_doTruthOriginPlots and m_trackTruthOriginTool->isFrom(associatedTruth, 5) ) {
1049 truthIsFromB = true;
1050 }
1051 m_monPlots->fill(*thisTrack, *thisJet, isBjet, isFake, unlinked, truthIsFromB, beamSpotWeight);
1052 if (associatedTruth){
1053 m_monPlots->fillFakeRate(*thisTrack, *thisJet, isFake, isBjet, truthIsFromB, beamSpotWeight);
1054 }
1055 }
1056
1057 } // loop on jets
1058
1059 return StatusCode::SUCCESS;
1060}
1061
1062bool
1064 const float jetPt = jet.pt();
1065 const float jetEta = std::abs(jet.eta());
1066
1067 if (jetEta < m_jetAbsEtaMin) return false;
1068 if (jetEta > m_jetAbsEtaMax) return false;
1069 if (jetPt < m_jetPtMin) return false;
1070 if (jetPt > m_jetPtMax) return false;
1071 return true;
1072}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
header file for truth selection in this package
Helper class to provide constant type-safe access to aux data.
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.
std::pair< const std::vector< const xAOD::TruthVertex * >, const std::vector< const xAOD::TruthVertex * > > getTruthVertices(const EventContext &ctx) const
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.
virtual StatusCode fillHistograms()
An inheriting class should either override this function or fillHists().
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::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.
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.
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
bool doTrkInJetPlots_unlinked_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 (and unlinked)
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