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