ATLAS Offline Software
Loading...
Searching...
No Matches
SCTTracksMonAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "SCTTracksMonAlg.h"
7#include "SCT_NameFormatter.h"
8
11#include "Identifier/Identifier.h"
18
19#include "GaudiKernel/StatusCode.h"
20#include "GaudiKernel/ThreadLocalContext.h"
21
22#include <cmath>
23
26
27namespace {
28 // some possible parameter key values
29 enum ParameterKey {
30 ONE_D_LOCATION=1, TWO_D_LOCATION=3, TRACK_SEGMENT=11, OLD_PARAMETERS_VECTOR=31
31 };
32
33 // segregate the eta regions
34 float
35 etaRegion(const float eta) {
36 // eta cut when segregating the tracks per region histogram
37 static const float etaBoundary(1.0);
38
39 if (eta < -etaBoundary) {
40 return 0.0; // EC C
41 }
42 if (eta > etaBoundary) {
43 return 2.0; // EC A
44 }
45 return 1.0; // Barrel
46 }
47}
48
49SCTTracksMonAlg::SCTTracksMonAlg(const std::string& name, ISvcLocator* pSvcLocator) :AthMonitorAlgorithm(name, pSvcLocator) {
50
51}
52
54 ATH_CHECK( m_tracksName.initialize() );
55 ATH_CHECK(m_trackSummaryTool.retrieve());
57 if (m_doUnbiasedCalc) {
58 ATH_CHECK(m_updator.retrieve());
59 } else {
60 m_updator.disable();
61 }
62 ATH_CHECK(detStore()->retrieve(m_pSCTHelper, "SCT_ID"));
63
64
66}
67
68StatusCode SCTTracksMonAlg::fillHistograms(const EventContext& ctx) const{
69
70ATH_MSG_DEBUG("SCTTracksMonAlg::fillHistograms()");
71
72 const bool doThisSubsystem[N_REGIONS] = {
74 };
75
76 std::bitset<N_TRIGGER_TYPES> firedTriggers{0};
77 if (m_doTrigger and (not checkTriggers(firedTriggers).isSuccess())) {
78 ATH_MSG_WARNING("Triggers not found!");
79 }
81 if (not tracks.isValid()) {
82 ATH_MSG_WARNING("No collection named " << m_tracksName.key() << " in StoreGate");
83 return StatusCode::SUCCESS;
84 }
85
86
87 ATH_MSG_DEBUG("Begin loop over " << tracks->size() << " tracks");
88 int goodTrks_N{0};
89 for (const Trk::Track* track: *tracks) {
90 if (track==nullptr) {
91 ATH_MSG_ERROR("No pointer to track");
92 break;
93 }
94
95 int local_scthits{0};
96 int scthits_on_trk{0}; // Breaks out of loop if track has less than 3 sct hits
97 std::unique_ptr<const Trk::TrackSummary> trkSum = m_trackSummaryTool->summary (ctx, *track);
98 if (trkSum==nullptr) {
99 ATH_MSG_WARNING("Trk::TrackSummary is null and cannot be created by " << m_trackSummaryTool.name());
100 }
101
102 if (trkSum) {
103 scthits_on_trk = trkSum->get(Trk::numberOfSCTHits);
104 } else {
105 ATH_MSG_WARNING("TrackSummary not found not using track!");
106 }
107 if (scthits_on_trk < m_trackHitCut) {
108 ATH_MSG_DEBUG("track fails minimum SCT hit requirement");
109 break;
110 }
111 goodTrks_N++;
112 if (track->fitQuality()->numberDoF() > 0.) { // Fill Track Chi2/ndf histogram
113 auto trk_chi2Acc{Monitored::Scalar<float>("trk_chi2", track->fitQuality()->chiSquared() / track->fitQuality()->numberDoF())};
114 fill("SCTTracksMonitor", trk_chi2Acc);
115 }
116 if (track->perigeeParameters() == nullptr) {
117 continue;
118 }
119 double trackPerigeeTheta{track->perigeeParameters()->parameters()[Trk::theta]};
120 double trackPerigeeEta{-log(tan(0.5 * trackPerigeeTheta))};
121 auto tracksPerRegionAcc{Monitored::Scalar<float>("tracksPerRegion", etaRegion(trackPerigeeEta))};
122
123 fill("SCTTracksMonitor", tracksPerRegionAcc);
124
125 auto trk_etaAcc{Monitored::Scalar<float>("trk_eta", trackPerigeeEta)};
126 fill("SCTTracksMonitor", trk_etaAcc);
127
128 if (track->perigeeParameters()->parameters()[Trk::qOverP] != 0.) {
129 auto trk_ptAcc{Monitored::Scalar<float>("trk_pt", std::abs(1. / (track->perigeeParameters()->parameters()[Trk::qOverP] * 1000.)))};
130 fill("SCTTracksMonitor", trk_ptAcc);
131 }
132 auto trk_d0Acc{Monitored::Scalar<float>("trk_d0", track->perigeeParameters()->parameters()[Trk::d0])};
133 fill("SCTTracksMonitor", trk_d0Acc);
134 auto trk_z0Acc{Monitored::Scalar<float>("trk_z0", track->perigeeParameters()->parameters()[Trk::z0])};
135 fill("SCTTracksMonitor", trk_z0Acc);
136 auto trk_phiAcc{Monitored::Scalar<float>("trk_phi", track->perigeeParameters()->parameters()[Trk::phi])};
137 fill("SCTTracksMonitor", trk_phiAcc);
138
139 if (m_doTrigger) {
140 for (int trig{0}; trig < N_TRIGGER_TYPES; ++trig) {
141 if (hasTriggerFired(trig, firedTriggers)) {
142 auto trackTriggerAcc{Monitored::Scalar<int>("trackTriggers", trig)};
143 fill("SCTTracksMonitor", trackTriggerAcc);
144 }
145 }
146 }
147 bool hasHits[N_REGIONS] = {
148 false, false, false
149 }; // Define bools to check whether the track has barrel, EA/C hits
150 // Get pointer to track state on surfaces
151 const Trk::TrackStates* trackStates{track->trackStateOnSurfaces()};
152 if (not trackStates) {
153 ATH_MSG_ERROR("for current track, TrackStateOnSurfaces == Null, no data will be written for this track");
154 break;
155 }
156 for (const Trk::TrackStateOnSurface* tsos: *trackStates) {
158 const InDet::SiClusterOnTrack* clus{dynamic_cast<const InDet::SiClusterOnTrack*>(tsos->measurementOnTrack())};
159 if (clus) { // Is it a SiCluster? If yes...
160 const InDet::SiCluster* RawDataClus{dynamic_cast<const InDet::SiCluster*>(clus->prepRawData())};
161 if (RawDataClus==nullptr) {
162 continue; // Continue if dynamic_cast returns null
163 }
164 if (RawDataClus->detectorElement()->isSCT()) {
165 const Identifier sct_id{clus->identify()};
166 const int bec{m_pSCTHelper->barrel_ec(sct_id)};
167 const unsigned int subsystemIndex{bec2Index(bec)};
168 const bool doThisDetector{doThisSubsystem[subsystemIndex]};
169 hasHits[subsystemIndex] = true;
170 std::unique_ptr<const Trk::TrackParameters> trkParameters(nullptr);
171 const Trk::TrackParameters* trkParam{tsos->trackParameters()};
172 const Trk::RIO_OnTrack* rio{dynamic_cast<const Trk::RIO_OnTrack*>(tsos->measurementOnTrack())};
173 if (rio) {
174#ifndef NDEBUG
175 ATH_MSG_DEBUG("if rio");
176#endif
177 if (m_doUnbiasedCalc) {
178 if (trkParam) {
179 trkParameters =m_updator->removeFromState(*trkParam,
180 rio->localParameters(),
181 rio->localCovariance());
182 // need to take ownership of the returned
183 // pointer
184 if (trkParameters) {
185 trkParam = trkParameters.get();
186 }
187 }
188 }
189 } else {
190 ATH_MSG_DEBUG("not rio");
191 }
192 if (trkParam) {
193 const AmgVector(5) LocalTrackParameters{trkParam->parameters()};
194#ifndef NDEBUG
195 ATH_MSG_DEBUG("Track Position Phi= " << LocalTrackParameters[Trk::locX]);
196 ATH_MSG_DEBUG("Cluster Position Phi= " << clus->localParameters()[Trk::locX]);
197#endif
198 if (not m_residualPullCalculator.empty()) {
199 std::optional<Trk::ResidualPull> residualPull{
200 m_residualPullCalculator->residualPull(
201 rio, trkParam,
204 if (not residualPull) {
205 ATH_MSG_WARNING("Residual Pull Calculator did not succeed!");
206 return StatusCode::SUCCESS;
207 } else {
208 double local_residual{residualPull->residual()[Trk::locX]};
209 double local_pull{residualPull->pull()[Trk::locX]};
210 if (doThisDetector) {
211 auto residualAcc{Monitored::Scalar<float>("total"+m_regionNames[bec2Index(bec)]+"Residual", local_residual)};
212 fill("SCTTracksMonitor", residualAcc);
213
214 auto pullAcc{Monitored::Scalar<float>("total"+m_regionNames[bec2Index(bec)]+"Pull", local_pull)};
215 fill("SCTTracksMonitor", pullAcc);
216
217 }
218 }
219 }
220 } else { // no measured local parameters, pull won't be calculated
221 ATH_MSG_WARNING("No measured local parameters, pull won't be calculated");
222 }
223 ++local_scthits; // TODO This is not correct, change it
224 } // end if SCT..
225 } // end if (clus)
226 } // if (tsos->type(Trk::TrackStateOnSurface::Measurement))
227 }// end of loop on TrackStatesonSurface (they can be SiClusters, TRTHits,..)
228 auto local_hitsAcc{Monitored::Scalar<float>("trk_sct_hits", static_cast<float>(local_scthits))};
229 fill("SCTTracksMonitor", local_hitsAcc);
230
231 // We now know whether this particular track had hits in the barrel or endcaps- update the profile histogram
232 for (unsigned int region{0}; region < N_REGIONS; ++region) {
233 auto regionAcc{Monitored::Scalar<int>("region", static_cast<int>(region))};
234 auto hitsAcc{Monitored::Scalar<float>("hitsRegion", static_cast<float>(hasHits[region]))};
235 fill("SCTTracksMonitor", regionAcc,hitsAcc);
236 // barrel, Eca, Ecb)
237 }
238 } // end of loop on tracks
239 auto goodTrks_NAcc{Monitored::Scalar<int>("trk_N", goodTrks_N)};
240 fill("SCTTracksMonitor", goodTrks_NAcc);
241 return StatusCode::SUCCESS;
242}
243
244
245// ====================================================================================================
246// SCTTracksMonTool :: calculatePull
247// ====================================================================================================
248float
249SCTTracksMonAlg::calculatePull(const float residual, const float trkErr, const float hitErr) const {
250 float ErrorSum{std::sqrt(trkErr * trkErr + hitErr * hitErr)};
251
252 if (ErrorSum > 1.0e-20) { // as floats are rarely exactly zero
253 return residual / ErrorSum;
254 } else {
255 ATH_MSG_DEBUG("Error on Track and Cluster are 0. Returning Pull value 0.");
256 return 0.;
257 }
258}
259
260StatusCode
261SCTTracksMonAlg::checkTriggers(std::bitset<N_TRIGGER_TYPES>& firedTriggers) const {
262
263 const EventContext& ctx = Gaudi::Hive::currentContext();
265 if (evtInfo.isValid()) {
266 firedTriggers = evtInfo->level1TriggerType();
267
268 return StatusCode::SUCCESS;
269 }
270 return StatusCode::FAILURE;
271}
272
273bool
274SCTTracksMonAlg::hasTriggerFired(const unsigned int trigger, const std::bitset<N_TRIGGER_TYPES>& firedTriggers) const {
275 return ((trigger < N_TRIGGER_TYPES) ? firedTriggers.test(trigger) : false);
276}
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
An STL vector of pointers that by default owns its pointed-to elements.
#define AmgVector(rows)
Header file to be included by clients of the Monitored infrastructure.
unsigned int bec2Index(const int becVal)
Conversion bec->index.
This is an Identifier helper class for the SCT subdetector.
Contains string formatting utility functions for use in SCT_Monitoring @ author shaun roe.
Handle class for reading from StoreGate.
const ServiceHandle< StoreGateSvc > & detStore() const
virtual StatusCode initialize() override
initialize
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
RIO_OnTrack base class for Silicon detector in the InnerDetector.
virtual const InDetDD::SiDetectorElement * detectorElement() const override final
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
Declare a monitored scalar variable.
SG::ReadHandleKey< TrackCollection > m_tracksName
Name of the Track collection to use.
const std::string m_regionNames[3]
ToolHandle< Trk::IUpdator > m_updator
BooleanProperty m_doTrigger
SCTTracksMonAlg(const std::string &name, ISvcLocator *pSvcLocator)
ToolHandle< Trk::ITrackSummaryTool > m_trackSummaryTool
bool hasTriggerFired(const unsigned int trigger, const std::bitset< N_TRIGGER_TYPES > &firedTriggers) const
Get the status of a particular trigger bit (trigger bit 0-7)
ToolHandle< Trk::IResidualPullCalculator > m_residualPullCalculator
Kalman Updator for SCT Unbiased states in Residual calculation.
IntegerProperty m_trackHitCut
Cut on number of SCT hits on track.
BooleanProperty m_doNegativeEndcap
BooleanProperty m_doUnbiasedCalc
StatusCode checkTriggers(std::bitset< N_TRIGGER_TYPES > &firedTriggers) const
Fill the m_firedTriggers bitset according to event information.
virtual StatusCode initialize() override final
initialize
BooleanProperty m_doPositiveEndcap
virtual StatusCode fillHistograms(const EventContext &ctx) const override final
adds event to the monitoring histograms
const SCT_ID * m_pSCTHelper
SCT Helper class.
float calculatePull(const float, const float, const float) const
Calculate Pull value for MeasuredAtPlane TrackStates.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
const Amg::MatrixX & localCovariance() const
Interface method to get the localError.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
virtual const Trk::PrepRawData * prepRawData() const =0
returns the PrepRawData (also known as RIO) object to which this RIO_OnTrack is associated.
Identifier identify() const
return the identifier -extends MeasurementBase
@ Biased
RP with track state including the hit.
@ Unbiased
RP with track state that has measurement not included.
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
unsigned int bec2Index(const int becVal)
Conversion bec->index.
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ locX
Definition ParamDefs.h:37
@ theta
Definition ParamDefs.h:66
@ qOverP
perigee
Definition ParamDefs.h:67
@ phi
Definition ParamDefs.h:75
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters
void fill(H5::Group &out_file, size_t iterations)