ATLAS Offline Software
Loading...
Searching...
No Matches
InDetBoundaryCheckTool.cxx
Go to the documentation of this file.
1/*
2 * Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4
10
12
14 const std::string& t,
15 const std::string& n,
16 const IInterface* p
17):
18 AthAlgTool(t, n, p),
19 m_atlasId(nullptr)
20{
21 declareInterface<IBoundaryCheckTool>(this);
22}
23
25 StatusCode sc = AlgTool::initialize();
26
27 if (sc.isFailure()) return sc;
28
29 ATH_CHECK(detStore()->retrieve(m_atlasId, "AtlasID"));
30
31 ATH_CHECK(m_pixelLayerTool.retrieve(DisableTool{!m_usePixel.value()}));
32 ATH_CHECK(m_sctCondSummaryTool.retrieve(DisableTool{!m_useSCT.value() || (!m_sctDetElStatus.empty() && !VALIDATE_STATUS_ARRAY_ACTIVATED)}));
33 ATH_CHECK(m_sctDetElStatus.initialize(m_useSCT.value() && !m_sctDetElStatus.empty()) );
34 if (m_useSCT.value() && !m_sctDetElStatus.empty()) {
35 ATH_CHECK( detStore()->retrieve(m_sctID,"SCT_ID") );
36 }
37
38 if (m_checkBadSCT.value()) {
39 /*
40 * Check if ITk Strip is used because isBadSCTChipStrip method is
41 * valid only for SCT.
42 */
43 ATH_CHECK(m_geoModelSvc.retrieve());
44
45 if (m_geoModelSvc->geoConfig()==GeoModel::GEO_RUN4) {
46 m_checkBadSCT.set(false);
47 ATH_MSG_WARNING("Since ITk Strip is used, m_check_bad_sct is turned off.");
48 }
49 }
50 return StatusCode::SUCCESS;
51}
52
54 return AlgTool::finalize();
55}
56
58 [[maybe_unused]] const InDetDD::SiDetectorElement &element,
59 const Trk::TrackParameters &parameters
60) const {
61 return m_pixelLayerTool->expectHit(&parameters);
62}
63
65 const InDetDD::SiDetectorElement &element,
66 const Trk::TrackParameters &parameters
67) const {
68 const EventContext& ctx{Gaudi::Hive::currentContext()};
70 if (m_checkBadSCT.value() && isBadSCTChipStrip(!m_sctDetElStatus.empty() ? sctDetElStatus.cptr() : nullptr, element.identify(), parameters, element)) {
71 return false;
72 }
73 VALIDATE_STATUS_ARRAY(!m_sctDetElStatus.empty(),sctDetElStatus->isGood(element.identifyHash()), m_sctCondSummaryTool->isGood(element.identifyHash(), ctx));
74 return !m_sctDetElStatus.empty() ? sctDetElStatus->isGood(element.identifyHash()) : m_sctCondSummaryTool->isGood(element.identifyHash(), ctx);
75}
76
78 const InDetDD::SiDetectorElement &siElement,
79 const Trk::TrackParameters &parameters
80) const {
81 /*
82 * We're supporting SCT and Pixel elements. Some of the checking code can
83 * be shared, and some of it is different for these detector types. This
84 * method will perform all the shared checks that apply to both SCTs and
85 * pixels.
86 */
87 double phitol;
88 double etatol;
89
90 /*
91 * We set our \phi and \eta tolerances by scaling the configured value in
92 * the tool's parameters by the standard deviation of the relative
93 * positions. If we do not have a covariance matrix to gather these \sigma
94 * values from, we use default parameters of 2.5 for \phi and 5.0 for
95 * \eta.
96 */
97 if (parameters.covariance() != nullptr) {
98 /*
99 * From the covariance matrix, we grab the diagonal to get the
100 * variance vector. Then, if we take the component-wise square root
101 * of that, we get a vector of \sigma. Then all we need to do is use
102 * the right indexes to retrieve the values for \eta and \phi.
103 */
104 Eigen::Matrix<double, 5, 1> var = parameters.covariance()->diagonal().cwiseSqrt();
105 etatol = m_etaTol.value() * var(Trk::iEta);
106 phitol = m_phiTol.value() * var(Trk::iPhi);
107 } else {
108 /*
109 * If we don't have the covariance matrix, set our defaults. In the
110 * future, these two default values could be lifted into separate
111 * configuration parameters.
112 */
113 phitol = 2.5;
114 etatol = 5;
115 }
116
117
118 /*
119 * Next, we determine whether the hit is in the active region of the
120 * element using the SiDetectorElement::inDetector() method followed by
121 * the SiIntersect::in() method.
122 */
124 parameters.localPosition(), phitol, etatol
125 );
126
128 if (intersection.nearBoundary()){
129
130 /*
131 * If we are around the boundary, we return a special state which
132 * will not be counted as a hole or missing hit in the pattern,
133 * while still being recorded on the trajectory for later
134 * refinement.
135 */
137 }
138
139 if (intersection.out()) {
140 /*
141 * In this case, we are _not_ inside the active region of the element.
142 */
144 }
145
146 /* Now, to proceed further we need to confirm that the module is actually active
147 */
148
149 Identifier id = siElement.identify();
150
151 bool alive;
152
153 /*
154 * If we have not yet determined our hit to lie in any inactive region, we
155 * check whether the module hit is actually alive. For this, we deletage
156 * to two dedicated methods which essentially wrap external tools which
157 * know about element states.
158 */
159 if (m_usePixel.value() && m_atlasId->is_pixel(id)) {
160 alive = isAlivePixel(siElement, parameters);
161 } else if (m_useSCT.value() && m_atlasId->is_sct(id)) {
162 alive = isAliveSCT(siElement, parameters);
163 } else {
164 ATH_MSG_WARNING("Unsupported identifier type! "+m_atlasId->print_to_string(id));
166 }
167
168 /*
169 * We now have all the necessary information to make a judgement about the
170 * track parameters.
171 */
172 if (alive) {
173
174 /*
175 * now, we check whether the local position on the silicon element is
176 * near the bonding gap of the module, which is insensitive. For this, we
177 * can simply delegate to the SiDetectorElement::newBondGap() method.
178 *
179 * Keen-eyed readers may note that bond gaps are only relevant for SCT
180 * modules and that Pixels do not have them. Therefore, we can technically
181 * consider this a check relevant only to SCTs. However, as this logic is
182 * abstracted into the SiDetectorElement class, we will treat is as a
183 * shared property and a shared check.
184 */
185 if (siElement.nearBondGap(parameters.localPosition(), etatol )) {
187 }
188 /*
189 * If the module is alive and we hit the active region on it, we know
190 * we have a good hit. Note that this is the only way we can return a
191 * Candidate result! It's the only success state.
192 */
194
195 }
196 else {
197 /*
198 * Finally, if the module is not alive, we simply return a DeadElement
199 * result.
200 */
202 }
203}
204
206 const Trk::TrackParameters &parameters
207) const {
208 /*
209 * Retrieve the detector element associated with our track parameters. If
210 * such an element does not exist for whatever reason, return a negative
211 * result.
212 */
213 const Trk::TrkDetElementBase *element = parameters.associatedSurface().associatedDetectorElement();
214
215 if (element == nullptr) {
217 }
218
219 /*
220 * Try to see if detector element is a silicon element, otherwise return a
221 * negative result: this tool is not designed to work on non-silicon
222 * elements.
223 */
224 const InDetDD::SiDetectorElement *siElement =
226 ? static_cast<const InDetDD::SiDetectorElement *>(element)
227 : nullptr;
228
229 if (siElement != nullptr) {
230 return boundaryCheckSiElement(*siElement, parameters);
231 } else {
232 ATH_MSG_DEBUG("TrackParameters do not belong to a type of element we can process");
234 }
235}
236
238 const InDet::SiDetectorElementStatus *sctDetElStatus,
239 const Identifier &waferId,
240 const Trk::TrackParameters &parameters,
241 const InDetDD::SiDetectorElement &siElement
242) const {
243 // Check if the track passes through a bad SCT ABCD chip or a bad SCT strip.
244 // A chip and a strip are determined by the parameter position.
245 // Algorithm is based on InnerDetector/InDetMonitoring/SCT_Monitoring/src/SCTHitEffMonTool.cxx
246
247 // Check the input.
248 if (!m_atlasId->is_sct(waferId)) {
249 ATH_MSG_ERROR(waferId << " is not an SCT Identifier");
250 return true;
251 }
252
253 // Get strip id from local position.
254 // Due to the limited position resolution, we may pick up a neighboring strip...
255 const Amg::Vector2D localPos(parameters.localPosition());
256 const Identifier stripIdentifier(siElement.identifierOfPosition(localPos));
257
258 if (!m_atlasId->is_sct(stripIdentifier)) {
259 ATH_MSG_WARNING(stripIdentifier << " is not an SCT Identifier");
260 return true;
261 }
262
263 {
264 const EventContext& ctx{Gaudi::Hive::currentContext()};
265 if (sctDetElStatus) {
266 unsigned int chip_i=SCT::getGeometricalChipID(*m_sctID, stripIdentifier);
267 VALIDATE_STATUS_ARRAY(sctDetElStatus,sctDetElStatus->isChipGood(siElement.identifyHash(), chip_i) && sctDetElStatus->isCellGood(siElement.identifyHash(), m_sctID->strip(stripIdentifier) ),m_sctCondSummaryTool->isGood(stripIdentifier, InDetConditions::SCT_CHIP, ctx) && m_sctCondSummaryTool->isGood(stripIdentifier, InDetConditions::SCT_STRIP, ctx));
268 if (!sctDetElStatus->isChipGood(siElement.identifyHash(), chip_i)) return true;
269
270 return !sctDetElStatus->isCellGood(siElement.identifyHash(), m_sctID->strip(stripIdentifier) );
271 }
272 else {
273 if (!m_sctCondSummaryTool->isGood(stripIdentifier, InDetConditions::SCT_CHIP, ctx)) {
274 // The position is on a bad chip.
275 return true;
276 } else if (!m_sctCondSummaryTool->isGood(stripIdentifier, InDetConditions::SCT_STRIP, ctx)) {
277 // The position is on a bad strip. (We may need to check neighboring strips.)
278 return true;
279 }
280 }
281 }
282 return false;
283}
#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)
static Double_t sc
This is an Identifier helper class for the SCT subdetector.
#define VALIDATE_STATUS_ARRAY(use_info, info_val, summary_val)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
Class to hold geometrical description of a silicon detector element.
bool nearBondGap(const Amg::Vector2D &localPosition, double etaTol) const
Test if near bond gap within tolerances.
class to run intersection tests
Definition SiIntersect.h:23
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
SiIntersect inDetector(const Amg::Vector2D &localPosition, double phiTol, double etaTol) const
Test that it is in the active region.
virtual Identifier identify() const override final
identifier of this detector element (inline)
Identifier identifierOfPosition(const Amg::Vector2D &localPos) const
Full identifier of the cell for a given position: assumes a raw local position (no Lorentz shift)
ToolHandle< IInDetConditionsTool > m_sctCondSummaryTool
InDetBoundaryCheckTool(const std::string &, const std::string &, const IInterface *)
bool isAliveSCT(const InDetDD::SiDetectorElement &element, const Trk::TrackParameters &parameters) const
Gaudi::Property< double > m_phiTol
virtual StatusCode initialize() override
SG::ReadHandleKey< InDet::SiDetectorElementStatus > m_sctDetElStatus
Optional read handle to get status data to test whether a SCT detector element is good.
SG::ReadHandle< InDet::SiDetectorElementStatus > getSCTDetElStatus(const EventContext &ctx) const
ToolHandle< IInDetTestPixelLayerTool > m_pixelLayerTool
Gaudi::Property< bool > m_checkBadSCT
Control check of bad SCT chip (should be false for ITk Strip)
Gaudi::Property< bool > m_usePixel
Control usage of pixel and SCT info.
ServiceHandle< IGeoModelSvc > m_geoModelSvc
virtual StatusCode finalize() override
virtual Trk::BoundaryCheckResult boundaryCheck(const Trk::TrackParameters &) const override
Trk::BoundaryCheckResult boundaryCheckSiElement(const InDetDD::SiDetectorElement &, const Trk::TrackParameters &) const
bool isAlivePixel(const InDetDD::SiDetectorElement &element, const Trk::TrackParameters &parameters) const
Gaudi::Property< double > m_etaTol
eta and phi tolerances
bool isBadSCTChipStrip(const InDet::SiDetectorElementStatus *, const Identifier &, const Trk::TrackParameters &, const InDetDD::SiDetectorElement &) const
bool isChipGood(IdentifierHash hash, unsigned int chip) const
bool isCellGood(IdentifierHash hash, unsigned short cell_i) const
const_pointer_type cptr()
Dereference the pointer.
This is the base class for all tracking detector elements with read-out relevant information.
virtual DetectorElemType detectorType() const =0
Return the Detector element type.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Eigen::Matrix< double, 2, 1 > Vector2D
constexpr unsigned int getGeometricalChipID(unsigned int strip)
Get the geometrical chip ID for the given strip.
@ OnEdge
within the sensitive area of an active element
@ DeadElement
outside the element
@ Insensitive
close to the edge of an active element
@ Outside
with the insensitive area of an active element
@ Error
within the nominally active area of a dead element
@ iEta
(old readout) will be skipped
Definition ParamDefs.h:48
@ iPhi
Definition ParamDefs.h:47
ParametersBase< TrackParametersDim, Charged > TrackParameters