ATLAS Offline Software
Loading...
Searching...
No Matches
MuonTrackSummaryHelperTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 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
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
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(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
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 const EventContext& ctx = Gaudi::Hive::currentContext();
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 std::vector<const Muon::MuonClusterOnTrack*>::const_iterator cl_it = crot->containedROTs().begin();
292 std::vector<const Muon::MuonClusterOnTrack*>::const_iterator cl_it_end = crot->containedROTs().end();
293 for (; cl_it != cl_it_end; ++cl_it) {
294 // get layer Identifier and insert it into set
295 Identifier layId = m_idHelperSvc->layerId((*cl_it)->identify());
296 layIds.insert(layId);
297 if (m_idHelperSvc->isCsc(id)) {
298 const Muon::CscClusterOnTrack* cscClus = dynamic_cast<const Muon::CscClusterOnTrack*>(rot);
299 if (cscClus) {
302 goodLayIds.insert(layId);
303 }
304 }
305 }
306 } else {
307 continue;
308 }
309 }
310 Identifier chId = m_idHelperSvc->chamberId(id);
311 // for is summary sTGC split STGC1 and STGC2
312 bool issTgc = m_idHelperSvc->issTgc(id);
313 if (issTgc) chId = m_idHelperSvc->detElId(id);
314 bool isFirst = isFirstProjection(id);
315 bool isMdt = m_idHelperSvc->isMdt(id);
316 ATH_MSG_VERBOSE(" Adding hit " << m_idHelperSvc->toString(id));
317
319 if (!currentChamberSummary || currentChamberSummary->m_chId != chId) {
320 if (m_calculateCloseHits && currentChamberSummary && currentChamberPars) {
321 ATH_MSG_VERBOSE(" Calculating close hits (last hit a measurement)");
322 calculateRoadHits(*currentChamberSummary, *currentChamberPars);
323 }
324
325 // given that we cannot separate eta/phi holes, redo the assignment before moving to the next chamber
326 if (currentChamberSummary && !currentChamberSummary->isMdt()) { updateHoleContent(*currentChamberSummary); }
327
328 ATH_MSG_VERBOSE(" Adding new chamber " << m_idHelperSvc->toString(id) << " " << *pars);
329 trackSummary.m_chamberHitSummary.emplace_back(chId, isMdt);
330 currentChamberSummary = &trackSummary.m_chamberHitSummary.back();
331 currentChamberPars = pars;
332 }
333
335 isFirst ? currentChamberSummary->m_first : currentChamberSummary->m_second;
336
337 if ((*tsit)->type(Trk::TrackStateOnSurface::Outlier)) {
338 // MDTs: count outlier as delta electron if rDrift < rTrack < innerTubeRadius
339 if (isMdt && pars) {
340 double rDrift = std::abs(meas->localParameters()[Trk::locR]);
341 double rTrack = std::abs(pars->parameters()[Trk::locR]);
342 double innerRadius = MuonDetMgr->getMdtReadoutElement(id)->innerTubeRadius();
343 if (rTrack > rDrift && rTrack < innerRadius) {
344 ++proj.ndeltas;
345 continue;
346 }
347 }
348 ++proj.noutliers;
349
350 } else {
351 proj.nhits += layIds.size();
352 proj.ngoodHits += goodLayIds.size();
353 }
354 if (!inBounds && isMdt) proj.noutBounds++;
355
356 } // end of for loop over Track State on Surfaces
357
360 if (m_calculateCloseHits && currentChamberSummary && currentChamberPars) {
361 ATH_MSG_VERBOSE(" Calculating close hits (end of hit list)");
362 calculateRoadHits(*currentChamberSummary, *currentChamberPars);
363 }
364
365 // given that we cannot separate eta/phi holes, redo the assignment before moving to the next chamber
366 if (currentChamberSummary && !currentChamberSummary->isMdt()) { updateHoleContent(*currentChamberSummary); }
367
368 summary.m_muonTrackSummary.reset(muonTrackSummary);
369}
370
372 if (m_idHelperSvc->issTgc(chamberHitSummary.chamberId())) {
373 ATH_MSG_DEBUG(" holes eta " << chamberHitSummary.etaProjection().nholes << " phi " << chamberHitSummary.phiProjection().nholes);
374 }
375
376 if (m_idHelperSvc->issTgc(chamberHitSummary.chamberId()) || m_idHelperSvc->isMM(chamberHitSummary.chamberId())) { return; }
377
378 const EventContext& ctx = Gaudi::Hive::currentContext();
380 const MuonGM::MuonDetectorManager* MuonDetMgr{*DetectorManagerHandle};
381 if (!MuonDetMgr) {
382 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
383 return;
384 }
385
386 bool isCsc = m_idHelperSvc->isCsc(chamberHitSummary.chamberId());
387 int neta = isCsc ? 4 : 2;
388 int nphi = isCsc ? 4 : 2;
389 if (m_idHelperSvc->isTgc(chamberHitSummary.chamberId())) {
390 const MuonGM::TgcReadoutElement* detEl = MuonDetMgr->getTgcReadoutElement(chamberHitSummary.chamberId());
391 if (!detEl) {
392 ATH_MSG_WARNING(" No detector element found for " << m_idHelperSvc->toStringChamber(chamberHitSummary.chamberId()));
393 return;
394 }
395
396 // get list of layers with a hole
397 neta = detEl->nGasGaps();
398 }
399
400 // code to recalculate the hole counts as they are not correct.
401 // This is due to the fact that the identification of the layers goes via the readout element identifier
402 // so it is not possible to separate eta and phi holes
403 int nMisEta = neta - chamberHitSummary.etaProjection().nhits - chamberHitSummary.etaProjection().noutliers;
404 int nMisPhi = nphi - chamberHitSummary.phiProjection().nhits - chamberHitSummary.phiProjection().noutliers;
405 int nholes = chamberHitSummary.etaProjection().nholes + chamberHitSummary.phiProjection().nholes;
406 if (nMisEta > 0 && nholes > 0) {
407 chamberHitSummary.m_first.nholes = nMisEta;
408 nholes -= nMisEta;
409 }
410 if (nMisPhi > 0 && nholes > 0) {
411 chamberHitSummary.m_second.nholes = nholes;
412 if (nholes != nMisPhi) {
413 ATH_MSG_DEBUG("Inconsistent hole count: expected hits eta "
414 << neta << " phi " << nphi << " hits eta "
415 << chamberHitSummary.etaProjection().nhits + chamberHitSummary.etaProjection().noutliers << " phi "
416 << chamberHitSummary.phiProjection().nhits + chamberHitSummary.phiProjection().noutliers << " missed eta "
417 << nMisEta << " phi " << nMisPhi << " holes eta " << chamberHitSummary.etaProjection().nholes << " phi "
418 << chamberHitSummary.phiProjection().nholes << " recalculated phi holes " << nholes);
419 }
420 }
421}
422
424 const Trk::TrackParameters& pars) const {
425 const EventContext& ctx = Gaudi::Hive::currentContext();
426 bool isStraightLine = false;
427 if (pars.parameters().rows() < 5) { // no momentum parameter given
428 isStraightLine = true;
429 } else if (std::abs(pars.parameters()[4]) < 1e-8) { // |p| > 1e8 MeV = 100 TeV
430 isStraightLine = true;
431 } else {
432 // Determine if TrackParameters correspond to a straight track (the ugly way)
433 if (pars.covariance()) {
434 const AmgSymMatrix(5)& covMat = *pars.covariance();
435 if (covMat.rows() < 5) { // no momentum available
436 isStraightLine = true;
437 } else {
438 // if no error on momentum given, assume no momentum was measured (extrapolator fails on zero error)
439 if (std::abs(covMat(4, 4)) < 1e-20) isStraightLine = true;
440 }
441 }
442 }
443 const Trk::IExtrapolator* extrapolator{nullptr};
444 if (m_extrapolator.isEnabled()) extrapolator = m_extrapolator.get();
445 if (isStraightLine && m_slExtrapolator.isEnabled()) {
446 extrapolator = m_slExtrapolator.get();
447 }
448 if (!extrapolator) return;
449
450 ATH_MSG_DEBUG("road hits for chamber " << m_idHelperSvc->toString(chamberHitSummary.chamberId()));
451
452 // currently treating MDTs only
453 if (!chamberHitSummary.isMdt()) return;
454
455 // loop over Mdt Prds (all hits in this chamber) and try to find prds of tubes with hits
456 const Muon::MdtPrepDataCollection* mdtPrdCol = findMdtPrdCollection(chamberHitSummary.chamberId());
457 if (!mdtPrdCol) {
458 ATH_MSG_DEBUG(" Retrieval of MdtPrepDataCollection failed!! ");
459 return;
460 }
461
462 if (isStraightLine) {
463 ATH_MSG_VERBOSE("Doing straight line extrapolation to get hits in road");
464 } else {
465 ATH_MSG_VERBOSE("Doing curved track extrapolation to get hits in road");
466 }
467
468 std::set<Identifier> addedIds;
469
472 for (; pit != pit_end; ++pit) {
473 const Muon::MdtPrepData& mdtPrd = **pit; // hit
474 const Identifier& id = mdtPrd.identify();
475
476 bool isFirst = isFirstProjection(id);
477 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj = isFirst ? chamberHitSummary.m_first : chamberHitSummary.m_second;
478
479 const Trk::Surface& surf = mdtPrd.detectorElement()->surface(id);
480
481 const Trk::TrackParameters* exPars = nullptr;
482 if (pars.associatedSurface() == surf) {
483 exPars = &pars;
484 } else {
485 exPars = extrapolator->extrapolateDirectly(ctx,
486 pars,
487 surf,
488 Trk::anyDirection, false, Trk::muon).release();
489 if (!exPars) {
490 if (isStraightLine) {
491 ATH_MSG_DEBUG(" Straight line propagation to prd " << m_idHelperSvc->toString(id) << " failed");
492 } else {
493 ATH_MSG_DEBUG(" Curved track propagation to prd " << m_idHelperSvc->toString(id) << " failed");
494 }
495 continue;
496 }
497 }
498
499 // use exPars to get distance to wire
500 double distance = exPars->parameters()[Trk::locR];
501
502 // sometimes there is more than one hit in a tube,
503 // which means there are two hits where the distance is the same but the tdc is different
504 if (addedIds.count(id)) {
505 ATH_MSG_DEBUG(" same tube hit, not adding to close hits in road");
506 } else {
507 // add all hits within the road width (defined in job options)
508 if (std::abs(distance) < m_roadWidth) {
509 ATH_MSG_VERBOSE("Hit ID within road: " << m_idHelperSvc->toString(id) << " distance " << distance << " < " << m_roadWidth);
510 ++proj.ncloseHits;
511 addedIds.insert(id);
512 } else {
513 ATH_MSG_VERBOSE("Hit ID outside road: " << m_idHelperSvc->toString(id) << " distance " << distance
514 << " >= " << m_roadWidth);
515 }
516 }
517 // to avoid double deleting when track is deleted, only delete
518 // exPars when it's not the TrackParameters which was passed (pars)
519 if (exPars != &pars) delete exPars;
520 }
521
522 // subtract the hits on the track in both projections:
523 chamberHitSummary.m_first.ncloseHits -= chamberHitSummary.m_first.nhits;
524 chamberHitSummary.m_second.ncloseHits -= chamberHitSummary.m_second.nhits;
525
526 if (chamberHitSummary.m_first.ncloseHits < 0) {
527 ATH_MSG_DEBUG("Number of hits in road < 0 in first projection: " << chamberHitSummary.m_first.ncloseHits
528 << ", setting = 0. (nhits in first projection = "
529 << chamberHitSummary.m_first.ncloseHits << ")");
530 chamberHitSummary.m_first.ncloseHits = 0;
531 }
532
533 if (chamberHitSummary.m_second.ncloseHits < 0) {
534 ATH_MSG_DEBUG("Number of hits in road < 0 in second projection: " << chamberHitSummary.m_second.ncloseHits
535 << ", setting = 0. (nhits in second projection = "
536 << chamberHitSummary.m_second.ncloseHits << ")");
537 chamberHitSummary.m_second.ncloseHits = 0;
538 }
539}
540
542 if (!m_idHelperSvc->isMdt(id)) { return !m_idHelperSvc->measuresPhi(id); }
543 return m_idHelperSvc->mdtIdHelper().multilayer(id) == 1;
544}
545
547 const EventContext& ctx = Gaudi::Hive::currentContext();
549
550 if (!mdtPrdContainer.isValid()) {
551 ATH_MSG_WARNING("Cannot retrieve mdtPrepDataContainer " << m_mdtKey);
552 return nullptr;
553 }
554
555 if (!mdtPrdContainer.isPresent()) {
556 ATH_MSG_DEBUG("No MDT PRD container available");
557 return nullptr;
558 }
559
560 IdentifierHash hash_id;
561 m_idHelperSvc->mdtIdHelper().get_module_hash(chId, hash_id);
562
563 const auto *coll = mdtPrdContainer->indexFindPtr(hash_id);
564 if (coll == nullptr) {
565 ATH_MSG_DEBUG(" MdtPrepDataCollection for: " << m_idHelperSvc->toStringChamber(chId) << " not found in container ");
566 return nullptr;
567 }
568 return coll;
569}
#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< 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
virtual void addDetailedTrackSummary(const Trk::Track &track, Trk::TrackSummary &summary) const override final
void updateHoleContent(Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary) const
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
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
virtual void analyse(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
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.
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