ATLAS Offline Software
Loading...
Searching...
No Matches
InDetTrackBiasingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
8
9#include <cmath>
10#include <TH2.h>
11#include <TFile.h>
12
13namespace {
15}
16
17namespace InDet {
18
19 InDetTrackBiasingTool::InDetTrackBiasingTool(const std::string& name) :
21 {
22
23#ifndef XAOD_STANDALONE
24 declareInterface<IInDetTrackBiasingTool>(this);
25#endif
26
27 }
28
30 {
31 if (m_biasD0 != 0.) {
32 ATH_MSG_INFO( "overall d0 bias added = " << m_biasD0
33 << " mm (not part of an official recommendation)" );
34 }
35 if (m_biasZ0 != 0.) {
36 ATH_MSG_INFO( "overall z0 bias added = " << m_biasZ0
37 << " mm (not part of an official recommendation)" );
38 }
39 if (m_biasQoverPsagitta != 0.) {
40 ATH_MSG_INFO( "overall QoverP sagitta bias added = " << m_biasQoverPsagitta
41 << " TeV^-1 (not part of an official recommendation)" );
42 }
43
44 if (m_runNumber > 0) {
45 ATH_MSG_WARNING( "Using manually-set run number (" << m_runNumber << ") to determine which calibration file to use." );
46 }
47
49
50 ATH_CHECK(m_evtInfoKey.initialize());
51
53
54 return StatusCode::SUCCESS;
55 }
56
60
62
63 if ( !m_isMC ) {
64 ATH_MSG_ERROR( "InDetTrackBiasingTool should only be run on MC." );
66 }
67
68 // determine which run number to use
70 static const SG::AuxElement::Accessor<unsigned int> randomRunNumber("RandomRunNumber");
71 auto runNumber = randomRunNumber(*eventInfo);
72
73 if (runNumber <= 0) {
74 ATH_MSG_WARNING( "Run number not set." );
75 }
76 // 5 TeV and heavy-ion runs have no biasing maps
77 if (runNumber >= 286282 && runNumber <= 287931) {
78 ATH_MSG_ERROR( "The 5 TeV and heavy ion runs do not have biasing maps for release 22. "
79 "Contact the tracking CP group to discuss the derivation of these maps." );
81 }
82
83 // find which configured period this run belongs to
84 size_t periodIdx = m_calibFiles.size(); // sentinel: no match
85 if (m_runNumberBounds.empty()) {
86 periodIdx = 0; // single period, accept all run numbers
87 } else {
88 for (size_t i = 0; i + 1 < m_runNumberBounds.size(); ++i) {
89 if (runNumber > m_runNumberBounds[i] && runNumber <= m_runNumberBounds[i+1]) {
90 periodIdx = i;
91 break;
92 }
93 }
94 }
95 if (periodIdx >= m_calibFiles.size()) {
96 ATH_MSG_ERROR( "Run number = " << runNumber << " does not fall within any configured calibration period." );
98 }
99
100 // select histograms for the matched period
101 TH2* biasD0Histogram = m_biasD0Histograms[periodIdx].get();
102 TH2* biasZ0Histogram = m_biasZ0Histograms[periodIdx].get();
103 TH2* biasQoverPsagittaHistogram = m_biasQoverPsagittaHistograms[periodIdx].get();
104
105 bool doD0Bias = m_applyD0Bias && biasD0Histogram != nullptr;
106 bool doZ0Bias = m_applyZ0Bias && biasZ0Histogram != nullptr;
107 bool doQoverPBias = m_applyQoverPBias && biasQoverPsagittaHistogram != nullptr;
108
109 if (m_applyD0Bias && !biasD0Histogram) ATH_MSG_WARNING( "d0 bias histogram is nullptr. Will not perform d0 bias." );
110 if (m_applyZ0Bias && !biasZ0Histogram) ATH_MSG_WARNING( "z0 bias histogram is nullptr. Will not perform z0 bias." );
111 if (m_applyQoverPBias && !biasQoverPsagittaHistogram) ATH_MSG_WARNING( "q/p bias histogram is nullptr. Will not perform q/p sagitta bias." );
112
113 // declare static accessors to avoid repeating string lookups
114 static const SG::AuxElement::Accessor< float > accD0( "d0" );
115 static const SG::AuxElement::Accessor< float > accZ0( "z0" );
116 static const SG::AuxElement::Accessor< float > accQOverP( "qOverP" );
117
118 const float phi = track.phi0();
119 const float eta = track.eta();
120
121 // do the biasing
122 // Always apply the correction to the nominal; undo it for systematic variations
123 if ( doD0Bias ) {
124 const float d0Corr = readHistogram(m_biasD0, biasD0Histogram, phi, eta);
125 accD0( track ) += d0Corr;
126 if ( isActive( TRK_BIAS_D0_WM ) ) {
127 accD0( track ) -= d0Corr;
128 }
129 }
130 if ( doZ0Bias ) {
131 const float z0Corr = readHistogram(m_biasZ0, biasZ0Histogram, phi, eta);
132 accZ0( track ) += z0Corr;
133 if ( isActive( TRK_BIAS_Z0_WM ) ) {
134 accZ0( track ) -= z0Corr;
135 }
136 }
137 if ( doQoverPBias ) {
138 auto sinTheta = 1.0 / std::cosh(eta);
139 const float qOverPCorr = 1.e-6*sinTheta*readHistogram(m_biasQoverPsagitta, biasQoverPsagittaHistogram, phi, eta);
140 accQOverP( track ) += qOverPCorr;
141 if ( isActive( TRK_BIAS_QOVERP_SAGITTA_WM ) ) {
142 accQOverP( track ) -= qOverPCorr;
143 }
144 }
145
147 }
148
150 {
151
152 if (m_calibFiles.empty()) {
153 ATH_MSG_ERROR( "No calibration files configured. Set 'calibFiles' and (for multiple periods) "
154 "'runNumberBounds' for the relevant MC campaign via the python configuration." );
155 return StatusCode::FAILURE;
156 }
157 if (!m_runNumberBounds.empty() && m_runNumberBounds.size() != m_calibFiles.size() + 1) {
158 ATH_MSG_ERROR( "'runNumberBounds' (size " << m_runNumberBounds.size() << ") must have "
159 "calibFiles.size() + 1 = " << (m_calibFiles.size() + 1) << " entries." );
160 return StatusCode::FAILURE;
161 }
162 if (m_runNumberBounds.empty() && m_calibFiles.size() > 1) {
163 ATH_MSG_ERROR( "'runNumberBounds' must be set when multiple calibration files are configured." );
164 return StatusCode::FAILURE;
165 }
166
167 for (size_t i = 0; i < m_calibFiles.size(); ++i) {
168 if (m_runNumberBounds.empty()) {
169 ATH_MSG_INFO( "Calibration period 0 (all run numbers): file: "
171 } else {
172 ATH_MSG_INFO( "Calibration period " << i << ": run range ["
173 << m_runNumberBounds[i] << ", " << m_runNumberBounds[i+1]
174 << "], file: " << PathResolverFindCalibFile(m_calibFiles[i]) );
175 }
176 m_biasD0Histograms.emplace_back(nullptr);
178 m_biasZ0Histograms.emplace_back(nullptr);
180 m_biasQoverPsagittaHistograms.emplace_back(nullptr);
182 }
183
184 return StatusCode::SUCCESS;
185 }
186
187 float InDetTrackBiasingTool::readHistogram(float fDefault, TH2* histogram, float phi, float eta) const {
188 if (histogram == nullptr) {
189 ATH_MSG_ERROR( "Configuration histogram is invalid. Check the run number and systematic configuration combination.");
190 throw std::runtime_error( "invalid configuration" );
191 }
192
193 // safety measure:
194 if( eta>2.499 ) eta= 2.499;
195 if( eta<-2.499 ) eta=-2.499;
196
197 float f = histogram->GetBinContent(histogram->FindBin(eta, phi));
198 f += fDefault; // should be zero unless a manual override is provided
199
200 return f;
201 }
202
204 xAOD::TrackParticle*& out )
205 {
206 return TrackCorrTool_t::correctedCopy(in, out);
207 }
208
210 {
211 return TrackCorrTool_t::applyContainerCorrection(cont);
212 }
213
218
220 {
221 CP::SystematicSet result;
222 if (m_applyD0Bias) result.insert(InDet::TrackSystematicMap.at(TRK_BIAS_D0_WM));
223 if (m_applyZ0Bias) result.insert(InDet::TrackSystematicMap.at(TRK_BIAS_Z0_WM));
224 if (m_applyQoverPBias) result.insert(InDet::TrackSystematicMap.at(TRK_BIAS_QOVERP_SAGITTA_WM));
225 return result;
226 }
227
232
237
238
239}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
Handle class for reading from StoreGate.
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
std::string histogram
Definition chains.cxx:52
Return value from object correction CP tools.
@ Error
Some error happened during the object correction.
@ Ok
The correction was done successfully.
Class to wrap a set of SystematicVariations.
virtual StatusCode applySystematicVariation(const CP::SystematicSet &) override
configure the tool to apply a given list of systematic variations
virtual CP::CorrectionCode applyCorrection(xAOD::TrackParticle &track) override
Computes the tracks origin.
float readHistogram(float fDefault, TH2 *histogram, float phi, float eta) const
virtual CP::SystematicSet recommendedSystematics() const override
returns: list of recommended systematics to use with this tool
virtual bool isAffectedBySystematic(const CP::SystematicVariation &) const override
returns: whether the tool is affected by the systematic
Gaudi::Property< uint32_t > m_runNumber
Gaudi::Property< float > m_biasQoverPsagitta
SG::ReadHandleKey< xAOD::EventInfo > m_evtInfoKey
std::vector< std::unique_ptr< TH2 > > m_biasD0Histograms
Gaudi::Property< bool > m_applyQoverPBias
Gaudi::Property< std::vector< std::string > > m_calibFiles
Gaudi::Property< float > m_biasZ0
virtual ASG_TOOL_CLASS(InDetTrackBiasingTool, InDet::IInDetTrackBiasingTool) public ~InDetTrackBiasingTool()
virtual CP::CorrectionCode correctedCopy(const xAOD::TrackParticle &in, xAOD::TrackParticle *&out) override
Gaudi::Property< float > m_biasD0
Gaudi::Property< std::vector< unsigned int > > m_runNumberBounds
virtual CP::CorrectionCode applyContainerCorrection(xAOD::TrackParticleContainer &cont) override
virtual CP::SystematicSet affectingSystematics() const override
returns: list of systematics this tool can be affected by
std::vector< std::unique_ptr< TH2 > > m_biasQoverPsagittaHistograms
Gaudi::Property< bool > m_applyZ0Bias
std::vector< std::unique_ptr< TH2 > > m_biasZ0Histograms
Gaudi::Property< bool > m_applyD0Bias
virtual StatusCode initialize() override
virtual bool isAffectedBySystematic(const CP::SystematicVariation &) const override
returns: whether the tool is affected by the systematic
virtual CP::SystematicSet recommendedSystematics() const override
returns: list of recommended systematics to use with this tool
StatusCode initObject(std::unique_ptr< T > &obj, const std::string &rootFileName, const std::string &objName) const
a function to initialize an object from a root file
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
virtual StatusCode applySystematicVariation(const CP::SystematicSet &) override
configure the tool to apply a given list of systematic variations
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:573
Primary Vertex Finder.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".