ATLAS Offline Software
Loading...
Searching...
No Matches
MuonTrackSummaryHelperTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <cassert>
8#include <cmath>
9#include <set>
10
25#include "TrkSurfaces/Surface.h"
26#include "TrkTrack/Track.h"
28
29Muon::MuonTrackSummaryHelperTool::MuonTrackSummaryHelperTool(const std::string& t, const std::string& n, const IInterface* p) :
30 base_class(t, n, p) {
31 declareInterface<ITrackSummaryHelperTool>(this);
32}
33
35 ATH_CHECK(m_DetectorManagerKey.initialize());
36 ATH_CHECK(m_extrapolator.retrieve(EnableTool{m_calculateCloseHits && !m_extrapolator.empty()}));
37 ATH_CHECK(m_slExtrapolator.retrieve(EnableTool{m_calculateCloseHits && !m_slExtrapolator.empty()}));
38 ATH_CHECK(m_idHelperSvc.retrieve());
39 ATH_CHECK(m_mdtKey.initialize());
40 return StatusCode::SUCCESS;
41}
42
43void Muon::MuonTrackSummaryHelperTool::analyse(const EventContext& , const Trk::Track& , const Trk::RIO_OnTrack* rot,
44 const Trk::TrackStateOnSurface* tsos, std::vector<int>& information,
45 std::bitset<Trk::numberOfDetectorTypes>& ) const {
46 using namespace Trk;
47 if (tsos->type(Trk::TrackStateOnSurface::Outlier)) return; // ignore outliers
48
49 Identifier id = rot->identify();
50 ATH_MSG_DEBUG("Processing rot: " << m_idHelperSvc->toString(id));
51 if (m_idHelperSvc->isRpc(id)) {
52 if (m_idHelperSvc->rpcIdHelper().measuresPhi(id))
53 increment(information[numberOfRpcPhiHits]);
54 else
55 increment(information[numberOfRpcEtaHits]);
56 } else if (m_idHelperSvc->isCsc(id)) {
57 if (m_idHelperSvc->cscIdHelper().measuresPhi(id))
58 increment(information[numberOfCscPhiHits]);
59 else {
60 increment(information[numberOfCscEtaHits]);
61 const CscClusterOnTrack* clus = dynamic_cast<const CscClusterOnTrack*>(rot);
62 if (clus && ((clus->status() == Muon::CscStatusUnspoiled) || (clus->status() == Muon::CscStatusSplitUnspoiled)))
64 }
65 } else if (m_idHelperSvc->isTgc(id)) {
66 if (m_idHelperSvc->tgcIdHelper().isStrip(id))
67 increment(information[numberOfTgcPhiHits]);
68 else
69 increment(information[numberOfTgcEtaHits]);
70 } else if (m_idHelperSvc->isMdt(id)) {
71 increment(information[numberOfMdtHits]);
72 } else if (m_idHelperSvc->issTgc(id)) {
73 if (m_idHelperSvc->stgcIdHelper().measuresPhi(id)) increment(information[numberOfStgcPhiHits]);
74 // we do not discriminate between pads or wires
75 else
76 increment(information[numberOfStgcEtaHits]);
77 } else if (m_idHelperSvc->isMM(id)) {
78 increment(information[numberOfMmHits]);
79 } else {
80 ATH_MSG_ERROR("Unknown muon detector type ");
81 ATH_MSG_ERROR("Dumping TrackStateOnSurface " << *tsos);
82 }
83 }
84
85void Muon::MuonTrackSummaryHelperTool::analyse(const EventContext& ctx, const Trk::Track& trk, const Trk::CompetingRIOsOnTrack* crot,
86 const Trk::TrackStateOnSurface* tsos, std::vector<int>& information,
87 std::bitset<Trk::numberOfDetectorTypes>& hitPattern) const {
88 // For competing ROTs we *only* count hits that are on different layers.
89 std::set<Identifier> layIds;
90 for (unsigned int i = 0; i < crot->numberOfContainedROTs(); i++) {
91 const Trk::RIO_OnTrack* rot = &crot->rioOnTrack(i);
92 Identifier layId = m_idHelperSvc->layerId(rot->identify());
93 ATH_MSG_DEBUG("ROT " << i << "\t LayerId=" << m_idHelperSvc->toString(layId));
94 std::pair<std::set<Identifier>::iterator, bool> pr = layIds.insert(layId);
95 if (pr.second) {
96 // layer not seen before
97 ATH_MSG_DEBUG("Have found hit on new layer. # of layers for this cROT currently=" << layIds.size());
98 analyse(ctx, trk, rot, tsos, information, hitPattern);
99 }
100 }
101}
102
104 if (type < 0)
105 type = 1; // they all start off at -1, so can't just increment
106 else
107 ++type;
108}
109
112 ATH_MSG_WARNING("searchForHoles is not implemented in MuonTrackSummaryHelperTool");
113}
114
115void Muon::MuonTrackSummaryHelperTool::addDetailedTrackSummary(const EventContext& ctx, const Trk::Track& track, Trk::TrackSummary& summary) const {
116 if (summary.m_muonTrackSummary) {
117 ATH_MSG_DEBUG("TrackSummary already has detailed muon track summary, not adding a new one");
118 return;
119 }
120
122 const MuonGM::MuonDetectorManager* MuonDetMgr{*DetectorManagerHandle};
123 if (MuonDetMgr == nullptr) {
124 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
125 return;
126 }
127
128 ATH_MSG_DEBUG("Adding detailed muon track summary");
129 ATH_MSG_DEBUG(track.info());
130 // loop over track and get chamber Identifiers
131 const Trk::TrackStates* states = track.trackStateOnSurfaces();
132 if (!states || states->empty()) { return; }
133
134 Trk::MuonTrackSummary* muonTrackSummary = new Trk::MuonTrackSummary();
135 Trk::MuonTrackSummary& trackSummary = *muonTrackSummary;
136
137 Trk::MuonTrackSummary::ChamberHitSummary* currentChamberSummary = nullptr;
138 const Trk::TrackParameters* currentChamberPars = nullptr;
139
140 // loop over TSOSs
141 Trk::TrackStates::const_iterator tsit = states->begin();
142 Trk::TrackStates::const_iterator tsit_end = states->end();
143 for (; tsit != tsit_end; ++tsit) {
144 const Trk::TrackParameters* pars = (*tsit)->trackParameters();
145
146 if ((*tsit)->type(Trk::TrackStateOnSurface::Scatterer)) {
147 ++trackSummary.m_nscatterers;
148 continue;
149 }
150
151 if ((*tsit)->type(Trk::TrackStateOnSurface::Hole)) {
152 if (!pars) {
153 ATH_MSG_WARNING(" Hole state without track parameters, cannot identify hole ");
154 continue;
155 }
156 if (pars->associatedSurface().associatedDetectorElement()) {
157 Identifier id = pars->associatedSurface().associatedDetectorElement()->identify();
158 bool issTgc = m_idHelperSvc->issTgc(id);
159 if (issTgc) {
160 // get the identifier for phi or eta holes
161 Identifier idh = pars->associatedSurface().associatedDetectorElementIdentifier();
162 if (idh.is_valid()) { id = idh; }
163 }
164 if (!id.is_valid() || !m_idHelperSvc->isMuon(id)) continue;
165 Identifier chId = m_idHelperSvc->chamberId(id);
166 // for is summary sTGC split STGC1 and STGC2
167 if (issTgc) chId = m_idHelperSvc->detElId(id);
168 bool isFirst = isFirstProjection(id);
169 bool isMdt = m_idHelperSvc->isMdt(id);
170
171 // check whether first chamber or new chamber
172 if (!currentChamberSummary || currentChamberSummary->m_chId != chId) {
176 if (m_calculateCloseHits && currentChamberSummary && currentChamberPars) {
177 ATH_MSG_VERBOSE(" Calculating close hits (last hit a hole)");
178 calculateRoadHits(*currentChamberSummary, *currentChamberPars);
179 }
180
181 // given that we cannot separate eta/phi holes, redo the assignment before moving to the next chamber
182 if (currentChamberSummary && !currentChamberSummary->isMdt()) { updateHoleContent(*currentChamberSummary); }
183
184 ATH_MSG_VERBOSE(" Adding new chamber (holes) " << m_idHelperSvc->toString(id) << " " << *pars);
185 trackSummary.m_chamberHitSummary.emplace_back(chId, isMdt);
186 currentChamberSummary = &trackSummary.m_chamberHitSummary.back();
187 currentChamberPars = pars;
188 }
189 if (!issTgc) {
191 isFirst ? currentChamberSummary->m_first : currentChamberSummary->m_second;
192 ++proj.nholes;
193 } else {
194 // sTgc holes keep track of phi and eta
195 if (m_idHelperSvc->measuresPhi(id)) {
196 ATH_MSG_VERBOSE(" counting sTGC phi hole ");
198 ++proj.nholes;
199 } else {
200 ATH_MSG_VERBOSE(" counting sTGC eta hole ");
202 ++proj.nholes;
203 }
204 }
205 }
206 continue;
207 }
208
209 // check whether state is a measurement
210 const Trk::MeasurementBase* meas = (*tsit)->measurementOnTrack();
211 if (!meas) { continue; }
212
213 const Trk::PseudoMeasurementOnTrack* pseudo = dynamic_cast<const Trk::PseudoMeasurementOnTrack*>(meas);
214 if (pseudo) {
215 ++trackSummary.m_npseudoMeasurements;
216 continue;
217 }
218
219 if (!pars) {
220 ATH_MSG_DEBUG("measurement without pars");
221 continue;
222 }
223
224 Amg::Vector2D locPos;
225 if (!meas->associatedSurface().globalToLocal(pars->position(), pars->position(), locPos)) {
226 ATH_MSG_DEBUG(" localToGlobal failed !!!!! ");
227 continue;
228 }
229 bool inBounds = true;
230
231 Identifier id;
232 std::set<Identifier> layIds;
233 std::set<Identifier> goodLayIds; // holds mdt hits that have not been deweighted
234
235 // check whether ROT
236 const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(meas);
237 if (rot) {
238 id = rot->identify();
239 if (!m_idHelperSvc->isMuon(id)) continue;
240
241 // bound checks
242 double tol1 = 100.;
243 double tol2 = 2 * tol1;
244 if (!pseudo && m_idHelperSvc->isMdt(id)) tol1 = 5.;
245
246 // we need a special bound check for MDTs so we cast to SL surface
247 const Trk::StraightLineSurface* slSurf = dynamic_cast<const Trk::StraightLineSurface*>(&meas->associatedSurface());
248 // we need a special bound check also for MMs to consider edge passivation
249 const MMClusterOnTrack* mmClusterOnTrack = dynamic_cast<const MMClusterOnTrack*>(meas);
250
251 if (slSurf) {
252 // perform bound check only for second coordinate
253 inBounds = slSurf->bounds().insideLoc2(locPos, tol2);
254 } else if (mmClusterOnTrack) {
255 // for MM, perform the bound check from the detector element
256 inBounds = mmClusterOnTrack->detectorElement()->insideActiveBounds(id, locPos, tol1, tol2);
257 } else {
258 inBounds = meas->associatedSurface().insideBounds(locPos, tol1, tol2);
259 }
260
261 Identifier layId = m_idHelperSvc->layerId(id);
262 layIds.insert(layId);
263 const MdtDriftCircleOnTrack* mdtdc = dynamic_cast<const MdtDriftCircleOnTrack*>(rot);
264 if (mdtdc) {
268 goodLayIds.insert(layId);
269 }
270 } else if (m_idHelperSvc->isCsc(id)) {
271 const Muon::CscClusterOnTrack* cscClus = dynamic_cast<const Muon::CscClusterOnTrack*>(rot);
274 goodLayIds.insert(layId);
275 } else if (m_idHelperSvc->isMM(id)) {
276 // MM quality requirements to be inserted here if needed
277 goodLayIds.insert(layId);
278 } else if (m_idHelperSvc->issTgc(id)) {
279 // sTGC quality requirements to be inserted here if needed
280 goodLayIds.insert(layId);
281 }
282 } else {
283 const Muon::CompetingMuonClustersOnTrack* crot = dynamic_cast<const Muon::CompetingMuonClustersOnTrack*>(meas);
284 if (crot) {
285 if (crot->containedROTs().empty()) continue;
286
287 // take id of first ROT
288 id = crot->containedROTs().front()->identify();
289
290 // count layers in competing rot
291 for (const auto& cl_it : crot->containedROTs()) {
292 // get layer Identifier and insert it into set
293 Identifier layId = m_idHelperSvc->layerId(cl_it->identify());
294 layIds.insert(layId);
295 if (m_idHelperSvc->isCsc(id)) {
296 const Muon::CscClusterOnTrack* cscClus = dynamic_cast<const Muon::CscClusterOnTrack*>(rot);
297 if (cscClus) {
300 goodLayIds.insert(layId);
301 }
302 }
303 }
304 } else {
305 continue;
306 }
307 }
308 Identifier chId = m_idHelperSvc->chamberId(id);
309 // for is summary sTGC split STGC1 and STGC2
310 bool issTgc = m_idHelperSvc->issTgc(id);
311 if (issTgc) chId = m_idHelperSvc->detElId(id);
312 bool isFirst = isFirstProjection(id);
313 bool isMdt = m_idHelperSvc->isMdt(id);
314 ATH_MSG_VERBOSE(" Adding hit " << m_idHelperSvc->toString(id));
315
317 if (!currentChamberSummary || currentChamberSummary->m_chId != chId) {
318 if (m_calculateCloseHits && currentChamberSummary && currentChamberPars) {
319 ATH_MSG_VERBOSE(" Calculating close hits (last hit a measurement)");
320 calculateRoadHits(*currentChamberSummary, *currentChamberPars);
321 }
322
323 // given that we cannot separate eta/phi holes, redo the assignment before moving to the next chamber
324 if (currentChamberSummary && !currentChamberSummary->isMdt()) { updateHoleContent(*currentChamberSummary); }
325
326 ATH_MSG_VERBOSE(" Adding new chamber " << m_idHelperSvc->toString(id) << " " << *pars);
327 trackSummary.m_chamberHitSummary.emplace_back(chId, isMdt);
328 currentChamberSummary = &trackSummary.m_chamberHitSummary.back();
329 currentChamberPars = pars;
330 }
331
333 isFirst ? currentChamberSummary->m_first : currentChamberSummary->m_second;
334
335 if ((*tsit)->type(Trk::TrackStateOnSurface::Outlier)) {
336 // MDTs: count outlier as delta electron if rDrift < rTrack < innerTubeRadius
337 if (isMdt && pars) {
338 double rDrift = std::abs(meas->localParameters()[Trk::locR]);
339 double rTrack = std::abs(pars->parameters()[Trk::locR]);
340 double innerRadius = MuonDetMgr->getMdtReadoutElement(id)->innerTubeRadius();
341 if (rTrack > rDrift && rTrack < innerRadius) {
342 ++proj.ndeltas;
343 continue;
344 }
345 }
346 ++proj.noutliers;
347
348 } else {
349 proj.nhits += layIds.size();
350 proj.ngoodHits += goodLayIds.size();
351 }
352 if (!inBounds && isMdt) proj.noutBounds++;
353
354 } // end of for loop over Track State on Surfaces
355
358 if (m_calculateCloseHits && currentChamberSummary && currentChamberPars) {
359 ATH_MSG_VERBOSE(" Calculating close hits (end of hit list)");
360 calculateRoadHits(*currentChamberSummary, *currentChamberPars);
361 }
362
363 // given that we cannot separate eta/phi holes, redo the assignment before moving to the next chamber
364 if (currentChamberSummary && !currentChamberSummary->isMdt()) { updateHoleContent(*currentChamberSummary); }
365
366 summary.m_muonTrackSummary.reset(muonTrackSummary);
367}
368
370 if (m_idHelperSvc->issTgc(chamberHitSummary.chamberId())) {
371 ATH_MSG_DEBUG(" holes eta " << chamberHitSummary.etaProjection().nholes << " phi " << chamberHitSummary.phiProjection().nholes);
372 }
373
374 if (m_idHelperSvc->issTgc(chamberHitSummary.chamberId()) || m_idHelperSvc->isMM(chamberHitSummary.chamberId())) { return; }
375
376 const EventContext& ctx = Gaudi::Hive::currentContext();
378 const MuonGM::MuonDetectorManager* MuonDetMgr{*DetectorManagerHandle};
379 if (!MuonDetMgr) {
380 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
381 return;
382 }
383
384 bool isCsc = m_idHelperSvc->isCsc(chamberHitSummary.chamberId());
385 int neta = isCsc ? 4 : 2;
386 int nphi = isCsc ? 4 : 2;
387 if (m_idHelperSvc->isTgc(chamberHitSummary.chamberId())) {
388 const MuonGM::TgcReadoutElement* detEl = MuonDetMgr->getTgcReadoutElement(chamberHitSummary.chamberId());
389 if (!detEl) {
390 ATH_MSG_WARNING(" No detector element found for " << m_idHelperSvc->toStringChamber(chamberHitSummary.chamberId()));
391 return;
392 }
393
394 // get list of layers with a hole
395 neta = detEl->nGasGaps();
396 }
397
398 // code to recalculate the hole counts as they are not correct.
399 // This is due to the fact that the identification of the layers goes via the readout element identifier
400 // so it is not possible to separate eta and phi holes
401 int nMisEta = neta - chamberHitSummary.etaProjection().nhits - chamberHitSummary.etaProjection().noutliers;
402 int nMisPhi = nphi - chamberHitSummary.phiProjection().nhits - chamberHitSummary.phiProjection().noutliers;
403 int nholes = chamberHitSummary.etaProjection().nholes + chamberHitSummary.phiProjection().nholes;
404 if (nMisEta > 0 && nholes > 0) {
405 chamberHitSummary.m_first.nholes = nMisEta;
406 nholes -= nMisEta;
407 }
408 if (nMisPhi > 0 && nholes > 0) {
409 chamberHitSummary.m_second.nholes = nholes;
410 if (nholes != nMisPhi) {
411 ATH_MSG_DEBUG("Inconsistent hole count: expected hits eta "
412 << neta << " phi " << nphi << " hits eta "
413 << chamberHitSummary.etaProjection().nhits + chamberHitSummary.etaProjection().noutliers << " phi "
414 << chamberHitSummary.phiProjection().nhits + chamberHitSummary.phiProjection().noutliers << " missed eta "
415 << nMisEta << " phi " << nMisPhi << " holes eta " << chamberHitSummary.etaProjection().nholes << " phi "
416 << chamberHitSummary.phiProjection().nholes << " recalculated phi holes " << nholes);
417 }
418 }
419}
420
422 const Trk::TrackParameters& pars) const {
423 const EventContext& ctx = Gaudi::Hive::currentContext();
424 bool isStraightLine = false;
425 if (pars.parameters().rows() < 5) { // no momentum parameter given
426 isStraightLine = true;
427 } else if (std::abs(pars.parameters()[4]) < 1e-8) { // |p| > 1e8 MeV = 100 TeV
428 isStraightLine = true;
429 } else {
430 // Determine if TrackParameters correspond to a straight track (the ugly way)
431 if (pars.covariance()) {
432 const AmgSymMatrix(5)& covMat = *pars.covariance();
433 if (covMat.rows() < 5) { // no momentum available
434 isStraightLine = true;
435 } else {
436 // if no error on momentum given, assume no momentum was measured (extrapolator fails on zero error)
437 if (std::abs(covMat(4, 4)) < 1e-20) isStraightLine = true;
438 }
439 }
440 }
441 const Trk::IExtrapolator* extrapolator{nullptr};
442 if (m_extrapolator.isEnabled()) extrapolator = m_extrapolator.get();
443 if (isStraightLine && m_slExtrapolator.isEnabled()) {
444 extrapolator = m_slExtrapolator.get();
445 }
446 if (!extrapolator) return;
447
448 ATH_MSG_DEBUG("road hits for chamber " << m_idHelperSvc->toString(chamberHitSummary.chamberId()));
449
450 // currently treating MDTs only
451 if (!chamberHitSummary.isMdt()) return;
452
453 // loop over Mdt Prds (all hits in this chamber) and try to find prds of tubes with hits
454 const Muon::MdtPrepDataCollection* mdtPrdCol = findMdtPrdCollection(chamberHitSummary.chamberId());
455 if (!mdtPrdCol) {
456 ATH_MSG_DEBUG(" Retrieval of MdtPrepDataCollection failed!! ");
457 return;
458 }
459
460 if (isStraightLine) {
461 ATH_MSG_VERBOSE("Doing straight line extrapolation to get hits in road");
462 } else {
463 ATH_MSG_VERBOSE("Doing curved track extrapolation to get hits in road");
464 }
465
466 std::set<Identifier> addedIds;
467
470 for (; pit != pit_end; ++pit) {
471 const Muon::MdtPrepData& mdtPrd = **pit; // hit
472 const Identifier& id = mdtPrd.identify();
473
474 bool isFirst = isFirstProjection(id);
475 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj = isFirst ? chamberHitSummary.m_first : chamberHitSummary.m_second;
476
477 const Trk::Surface& surf = mdtPrd.detectorElement()->surface(id);
478
479 const Trk::TrackParameters* exPars = nullptr;
480 if (pars.associatedSurface() == surf) {
481 exPars = &pars;
482 } else {
483 exPars = extrapolator->extrapolateDirectly(ctx,
484 pars,
485 surf,
486 Trk::anyDirection, false, Trk::muon).release();
487 if (!exPars) {
488 if (isStraightLine) {
489 ATH_MSG_DEBUG(" Straight line propagation to prd " << m_idHelperSvc->toString(id) << " failed");
490 } else {
491 ATH_MSG_DEBUG(" Curved track propagation to prd " << m_idHelperSvc->toString(id) << " failed");
492 }
493 continue;
494 }
495 }
496
497 // use exPars to get distance to wire
498 double distance = exPars->parameters()[Trk::locR];
499
500 // sometimes there is more than one hit in a tube,
501 // which means there are two hits where the distance is the same but the tdc is different
502 if (addedIds.count(id)) {
503 ATH_MSG_DEBUG(" same tube hit, not adding to close hits in road");
504 } else {
505 // add all hits within the road width (defined in job options)
506 if (std::abs(distance) < m_roadWidth) {
507 ATH_MSG_VERBOSE("Hit ID within road: " << m_idHelperSvc->toString(id) << " distance " << distance << " < " << m_roadWidth);
508 ++proj.ncloseHits;
509 addedIds.insert(id);
510 } else {
511 ATH_MSG_VERBOSE("Hit ID outside road: " << m_idHelperSvc->toString(id) << " distance " << distance
512 << " >= " << m_roadWidth);
513 }
514 }
515 // to avoid double deleting when track is deleted, only delete
516 // exPars when it's not the TrackParameters which was passed (pars)
517 if (exPars != &pars) delete exPars;
518 }
519
520 // subtract the hits on the track in both projections:
521 chamberHitSummary.m_first.ncloseHits -= chamberHitSummary.m_first.nhits;
522 chamberHitSummary.m_second.ncloseHits -= chamberHitSummary.m_second.nhits;
523
524 if (chamberHitSummary.m_first.ncloseHits < 0) {
525 ATH_MSG_DEBUG("Number of hits in road < 0 in first projection: " << chamberHitSummary.m_first.ncloseHits
526 << ", setting = 0. (nhits in first projection = "
527 << chamberHitSummary.m_first.ncloseHits << ")");
528 chamberHitSummary.m_first.ncloseHits = 0;
529 }
530
531 if (chamberHitSummary.m_second.ncloseHits < 0) {
532 ATH_MSG_DEBUG("Number of hits in road < 0 in second projection: " << chamberHitSummary.m_second.ncloseHits
533 << ", setting = 0. (nhits in second projection = "
534 << chamberHitSummary.m_second.ncloseHits << ")");
535 chamberHitSummary.m_second.ncloseHits = 0;
536 }
537}
538
540 if (!m_idHelperSvc->isMdt(id)) { return !m_idHelperSvc->measuresPhi(id); }
541 return m_idHelperSvc->mdtIdHelper().multilayer(id) == 1;
542}
543
545 const EventContext& ctx = Gaudi::Hive::currentContext();
547
548 if (!mdtPrdContainer.isValid()) {
549 ATH_MSG_WARNING("Cannot retrieve mdtPrepDataContainer " << m_mdtKey);
550 return nullptr;
551 }
552
553 if (!mdtPrdContainer.isPresent()) {
554 ATH_MSG_DEBUG("No MDT PRD container available");
555 return nullptr;
556 }
557
558 IdentifierHash hash_id;
559 m_idHelperSvc->mdtIdHelper().get_module_hash(chId, hash_id);
560
561 const auto *coll = mdtPrdContainer->indexFindPtr(hash_id);
562 if (coll == nullptr) {
563 ATH_MSG_DEBUG(" MdtPrepDataCollection for: " << m_idHelperSvc->toStringChamber(chId) << " not found in container ");
564 return nullptr;
565 }
566 return coll;
567}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
Handle class for reading from StoreGate.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
const_iterator begin() const noexcept
This is a "hash" representation of an Identifier.
bool is_valid() const
Check if id is in a valid state.
bool insideActiveBounds(const Identifier &id, const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const
boundary check Wrapper Trk::PlaneSurface::insideBounds() taking into account the passivated width
virtual const Trk::Surface & surface() const override final
Return surface associated with this detector element.
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const TgcReadoutElement * getTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
int nGasGaps() const
Returns the number of gas gaps associated with the readout element (2 or 3).
Class for competing MuonClusters, it extends the Trk::CompetingRIOsOnTrack base class.
const std::vector< std::unique_ptr< const MuonClusterOnTrack > > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
Class to represent the calibrated clusters created from CSC strips.
CscClusterStatus status() const
Returns Csc position measurement status flag.
Class to represent calibrated clusters formed from TGC strips.
virtual const MuonGM::MMReadoutElement * detectorElement() const
Returns the detector element, assoicated with the PRD of this class.
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
const MuonDriftCircleErrorStrategy & errorStrategy() const
Get information about the creation strategy used by Muon::MdtDriftCircleOnTrackCreator when making th...
Class to represent measurements from the Monitored Drift Tubes.
Definition MdtPrepData.h:33
virtual const MuonGM::MdtReadoutElement * detectorElement() const override
Returns the detector element corresponding to this PRD.
bool creationParameter(CreationParameter) const
@ StationError
A term is added to account for misaligned.
@ FixedError
A fixed error is given to this hit (user defined via jobProperties).
Gaudi::Property< bool > m_calculateCloseHits
allow us to block the calculation of close hits
static void increment(int &type)
increment the 'type'
void calculateRoadHits(Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary, const Trk::TrackParameters &pars) const
const MdtPrepDataCollection * findMdtPrdCollection(const Identifier &chId) const
void updateHoleContent(Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary) const
virtual void addDetailedTrackSummary(const EventContext &ctx, const Trk::Track &track, Trk::TrackSummary &summary) const override final
MuonTrackSummaryHelperTool(const std::string &, const std::string &, const IInterface *)
ToolHandle< Trk::IExtrapolator > m_extrapolator
Gaudi::Property< double > m_roadWidth
width road use to associate close hits
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
bool isFirstProjection(const Identifier &id) const
ToolHandle< Trk::IExtrapolator > m_slExtrapolator
virtual void analyse(const EventContext &ctx, const Trk::Track &trk, const Trk::RIO_OnTrack *rot, const Trk::TrackStateOnSurface *tsos, std::vector< int > &information, std::bitset< Trk::numberOfDetectorTypes > &hitPattern) const override final
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
virtual void searchForHoles(const Trk::Track &track, std::vector< int > &information, Trk::ParticleHypothesis hyp) const override final
SG::ReadHandleKey< Muon::MdtPrepDataContainer > m_mdtKey
storegate key of MdtPrepDataContainer
virtual bool isValid() override final
Can the handle be successfully dereferenced?
bool isPresent() const
Is the referenced object present in SG?
Base class for all CompetingRIOsOnTack implementations, extends the common MeasurementBase.
virtual unsigned int numberOfContainedROTs() const =0
Number of RIO_OnTracks to be contained by this CompetingRIOsOnTrack.
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
Interface class for the extrapolation AlgTool, it inherits from IAlgTool Detailed information about p...
virtual std::unique_ptr< TrackParameters > extrapolateDirectly(const EventContext &ctx, const TrackParameters &parm, const Surface &sf, PropDirection dir=anyDirection, const BoundaryCheck &bcheck=true, ParticleHypothesis particle=pion) const =0
Extrapolate directly: Forwards directly the call to the configured "Global" propagator.
This class is the pure abstract base class for all fittable tracking measurements.
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
Detailed track summary for the muon system Give access to hit counts per chamber.
std::vector< ChamberHitSummary > m_chamberHitSummary
unsigned int m_npseudoMeasurements
Identifier identify() const
return the identifier
Class to handle pseudo-measurements in fitters and on track objects.
Class to handle RIO On Tracks ROT) for InDet and Muons, it inherits from the common MeasurementBase.
Definition RIO_OnTrack.h:70
Identifier identify() const
return the identifier -extends MeasurementBase
Class for a StraightLineSurface in the ATLAS detector to describe dirft tube and straw like detectors...
virtual const SurfaceBounds & bounds() const override final
This method returns the bounds of the Surface by reference.
virtual bool insideLoc2(const Amg::Vector2D &locpo, double tol2=0.) const =0
Extend the interface to for single inside Loc 1 / Loc2 tests.
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const =0
Specified by each surface type: GlobalToLocal method without dynamic memory allocation - boolean chec...
virtual bool insideBounds(const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const =0
virtual methods to be overwritten by the inherited surfaces
represents the track state (measurement, material, fit parameters and quality) at a surface.
bool type(const TrackStateOnSurfaceType type) const
Use this method to find out if the TSoS is of a certain type: i.e.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
@ Hole
A hole on the track - this is defined in the following way.
A summary of the information contained by a track.
Eigen::Matrix< double, 2, 1 > Vector2D
@ CscStatusUnspoiled
Clean cluster with precision fit.
@ CscStatusSplitUnspoiled
Clean cluster with precision fit after split cluster.
MuonPrepDataCollection< MdtPrepData > MdtPrepDataCollection
Ensure that the ATLAS eigen extensions are properly loaded.
@ anyDirection
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ locR
Definition ParamDefs.h:44
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
@ numberOfMmHits
number of TGC Eta measurements missing from the track
@ numberOfStgcEtaHits
number of TGC Eta measurements missing from the track
@ numberOfStgcPhiHits
number of TGC Phi measurements missing from the track
@ numberOfCscUnspoiltEtaHits
number of unspoilt CSC eta measurements (all CSC phi measurements are by definition spoilt).
structure to hold the information for the eta/phi projection of RPC, TGC and CSC chambers and per mul...
structure to hold information per chamber in the muon system
const Projection & phiProjection() const
access to the data of the phi projection, users have to check whether this is NOT a MDT chamber first...
const Projection & etaProjection() const
access to the data of the eta projection, users have to check whether this is NOT a MDT chamber first...
const Identifier & chamberId() const
returns the chamber identifier
bool isMdt() const
returns whether this is a MDT chamber