ATLAS Offline Software
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 
19 #include "StoreGate/ReadHandle.h"
25 #include "TrkSurfaces/Surface.h"
26 #include "TrkTrack/Track.h"
28 
29 Muon::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)))
63  increment(information[numberOfCscUnspoiltEtaHits]);
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 
111  Trk::ParticleHypothesis ) const {
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();
121  SG::ReadCondHandle<MuonGM::MuonDetectorManager> DetectorManagerHandle{m_DetectorManagerKey, ctx};
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
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) {
265  MuonDriftCircleErrorStrategy errStrat = mdtdc->errorStrategy();
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();
379  SG::ReadCondHandle<MuonGM::MuonDetectorManager> DetectorManagerHandle{m_DetectorManagerKey, ctx};
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 
471  Muon::MdtPrepDataCollection::const_iterator pit_end = mdtPrdCol->end();
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 
541 bool Muon::MuonTrackSummaryHelperTool::isFirstProjection(const Identifier& id) const {
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();
548  SG::ReadHandle<Muon::MdtPrepDataContainer> mdtPrdContainer(m_mdtKey, ctx);
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 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
Trk::MuonTrackSummary::ChamberHitSummary::phiProjection
const Projection & phiProjection() const
access to the data of the phi projection, users have to check whether this is NOT a MDT chamber first...
Definition: MuonTrackSummary.h:106
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
Muon::MuonDriftCircleErrorStrategy
Definition: MuonDriftCircleErrorStrategy.h:15
MdtReadoutElement.h
Muon::MuonTrackSummaryHelperTool::searchForHoles
virtual void searchForHoles(const Trk::Track &track, std::vector< int > &information, Trk::ParticleHypothesis hyp) const override final
Definition: MuonTrackSummaryHelperTool.cxx:110
TrkDetElementBase.h
MuonDriftCircleErrorStrategy.h
Muon::MuonTrackSummaryHelperTool::isFirstProjection
bool isFirstProjection(const Identifier &id) const
Definition: MuonTrackSummaryHelperTool.cxx:541
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
Trk::StraightLineSurface::bounds
virtual const SurfaceBounds & bounds() const override final
This method returns the bounds of the Surface by reference.
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
TrackParameters.h
MeasurementBase.h
MuonGM::MMReadoutElement::insideActiveBounds
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
Definition: MMReadoutElement.h:257
Muon::MuonTrackSummaryHelperTool::addDetailedTrackSummary
virtual void addDetailedTrackSummary(const Trk::Track &track, Trk::TrackSummary &summary) const override final
Definition: MuonTrackSummaryHelperTool.cxx:115
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
CompetingRIOsOnTrack.h
Trk::MuonTrackSummary::ChamberHitSummary::chamberId
const Identifier & chamberId() const
returns the chamber identifier
Definition: MuonTrackSummary.h:58
Surface.h
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
Trk::numberOfCscEtaHits
@ numberOfCscEtaHits
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:108
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
Trk::numberOfCscUnspoiltEtaHits
@ numberOfCscUnspoiltEtaHits
number of unspoilt CSC eta measurements (all CSC phi measurements are by definition spoilt).
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:142
Trk::MuonTrackSummary::ChamberHitSummary::isMdt
bool isMdt() const
returns whether this is a MDT chamber
Definition: MuonTrackSummary.h:61
Trk::MuonTrackSummary::m_npseudoMeasurements
unsigned int m_npseudoMeasurements
Definition: MuonTrackSummary.h:156
CompetingMuonClustersOnTrack.h
Trk::MuonTrackSummary::ChamberHitSummary::m_second
Projection m_second
Definition: MuonTrackSummary.h:117
Muon::MdtDriftCircleOnTrack::errorStrategy
const MuonDriftCircleErrorStrategy & errorStrategy() const
Get information about the creation strategy used by Muon::MdtDriftCircleOnTrackCreator when making th...
Definition: MdtDriftCircleOnTrack.h:283
Trk::RIO_OnTrack
Definition: RIO_OnTrack.h:70
Trk::numberOfTgcPhiHits
@ numberOfTgcPhiHits
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:105
Trk::locR
@ locR
Definition: ParamDefs.h:50
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Muon::CompetingMuonClustersOnTrack
Definition: CompetingMuonClustersOnTrack.h:54
MdtDriftCircleOnTrack.h
Trk::MuonTrackSummary::ChamberHitSummary::Projection::nhits
int nhits
Definition: MuonTrackSummary.h:40
Trk::MuonTrackSummary::ChamberHitSummary::m_chId
Identifier m_chId
Definition: MuonTrackSummary.h:113
Trk::MuonTrackSummary::ChamberHitSummary::Projection::nholes
int nholes
Definition: MuonTrackSummary.h:41
Trk::MuonTrackSummary::ChamberHitSummary::Projection::ncloseHits
int ncloseHits
Definition: MuonTrackSummary.h:44
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
MuonGM::TgcReadoutElement::nGasGaps
int nGasGaps() const
Returns the number of gas gaps associated with the readout element (2 or 3)
MMClusterOnTrack.h
Trk::MuonTrackSummary::ChamberHitSummary
structure to hold information per chamber in the muon system
Definition: MuonTrackSummary.h:32
Trk::MuonTrackSummary::m_chamberHitSummary
std::vector< ChamberHitSummary > m_chamberHitSummary
Definition: MuonTrackSummary.h:157
Trk::MuonTrackSummary::m_nscatterers
unsigned int m_nscatterers
Definition: MuonTrackSummary.h:155
Trk::numberOfMmHits
@ numberOfMmHits
number of TGC Eta measurements missing from the track
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:132
Trk::MuonTrackSummary::ChamberHitSummary::m_first
Projection m_first
Definition: MuonTrackSummary.h:116
Trk::TrackStateOnSurface::Outlier
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
Definition: TrackStateOnSurface.h:122
Track.h
Trk::PseudoMeasurementOnTrack
Class to handle pseudo-measurements in fitters and on track objects.
Definition: PseudoMeasurementOnTrack.h:44
Trk::ParticleHypothesis
ParticleHypothesis
Definition: ParticleHypothesis.h:25
Muon::MuonTrackSummaryHelperTool::MuonTrackSummaryHelperTool
MuonTrackSummaryHelperTool(const std::string &, const std::string &, const IInterface *)
Definition: MuonTrackSummaryHelperTool.cxx:29
Trk::TrackStateOnSurface::type
bool type(const TrackStateOnSurfaceType type) const
Use this method to find out if the TSoS is of a certain type: i.e.
Trk::CompetingRIOsOnTrack::rioOnTrack
virtual const RIO_OnTrack & rioOnTrack(unsigned int) const =0
returns the RIO_OnTrack (also known as ROT) objects depending on the integer.
Muon::MuonTrackSummaryHelperTool::analyse
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
Definition: MuonTrackSummaryHelperTool.cxx:43
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Muon::MuonDriftCircleErrorStrategy::FixedError
@ FixedError
A fixed error is given to this hit (user defined via jobProperties)
Definition: MuonDriftCircleErrorStrategy.h:20
Trk::CompetingRIOsOnTrack::numberOfContainedROTs
virtual unsigned int numberOfContainedROTs() const =0
Number of RIO_OnTracks to be contained by this CompetingRIOsOnTrack.
Trk::TrackStateOnSurface::Hole
@ Hole
A hole on the track - this is defined in the following way.
Definition: TrackStateOnSurface.h:128
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
urldecode::states
states
Definition: urldecode.h:39
Trk::MuonTrackSummary::ChamberHitSummary::Projection::noutliers
int noutliers
Definition: MuonTrackSummary.h:42
Muon::MuonTrackSummaryHelperTool::initialize
virtual StatusCode initialize() override
Definition: MuonTrackSummaryHelperTool.cxx:34
CscClusterOnTrack.h
TileDCSDataPlotter.pr
pr
Definition: TileDCSDataPlotter.py:922
Trk::CompetingRIOsOnTrack
Base class for all CompetingRIOsOnTack implementations, extends the common MeasurementBase.
Definition: CompetingRIOsOnTrack.h:64
MuonGM::TgcReadoutElement
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/TgcReadoutElement.h:42
PseudoMeasurementOnTrack.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::MuonTrackSummary
Detailed track summary for the muon system Give access to hit counts per chamber.
Definition: MuonTrackSummary.h:26
Trk::ParametersBase
Definition: ParametersBase.h:55
Muon::MuonTrackSummaryHelperTool::increment
static void increment(int &type)
increment the 'type'
Definition: MuonTrackSummaryHelperTool.cxx:103
Trk::muon
@ muon
Definition: ParticleHypothesis.h:28
Muon::MuonPrepDataCollection
Template to hold collections of MuonPrepRawData objects.
Definition: MuonPrepDataCollection.h:46
Trk::MuonTrackSummary::ChamberHitSummary::etaProjection
const Projection & etaProjection() const
access to the data of the eta projection, users have to check whether this is NOT a MDT chamber first...
Definition: MuonTrackSummary.h:103
DataVector< const Trk::TrackStateOnSurface >
Muon::MuonTrackSummaryHelperTool::calculateRoadHits
void calculateRoadHits(Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary, const Trk::TrackParameters &pars) const
Definition: MuonTrackSummaryHelperTool.cxx:423
Trk::SurfaceBounds::insideLoc2
virtual bool insideLoc2(const Amg::Vector2D &locpo, double tol2=0.) const =0
Extend the interface to for single inside Loc 1 / Loc2 tests.
make_coralServer_rep.proj
proj
Definition: make_coralServer_rep.py:48
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CscClusterStatus.h
Trk::numberOfStgcEtaHits
@ numberOfStgcEtaHits
number of TGC Eta measurements missing from the track
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:128
Trk::numberOfTgcEtaHits
@ numberOfTgcEtaHits
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:106
Muon::MMClusterOnTrack
Class to represent calibrated clusters formed from TGC strips.
Definition: MMClusterOnTrack.h:26
Trk::MeasurementBase
Definition: MeasurementBase.h:58
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
Muon::MuonTrackSummaryHelperTool::findMdtPrdCollection
const MdtPrepDataCollection * findMdtPrdCollection(const Identifier &chId) const
Definition: MuonTrackSummaryHelperTool.cxx:546
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::numberOfRpcPhiHits
@ numberOfRpcPhiHits
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:109
Muon::MuonDriftCircleErrorStrategy::StationError
@ StationError
A term is added to account for misaligned.
Definition: MuonDriftCircleErrorStrategy.h:22
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
Muon::CscStatusUnspoiled
@ CscStatusUnspoiled
Clean cluster with precision fit.
Definition: CscClusterStatus.h:26
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:194
Trk::TrackSummary
A summary of the information contained by a track.
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:287
Trk::MeasurementBase::associatedSurface
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
Muon::MdtDriftCircleOnTrack
This class represents the corrected MDT measurements, where the corrections include the effects of wi...
Definition: MdtDriftCircleOnTrack.h:37
Muon::MdtPrepData
Class to represent measurements from the Monitored Drift Tubes.
Definition: MdtPrepData.h:37
Muon::CompetingMuonClustersOnTrack::containedROTs
const std::vector< const MuonClusterOnTrack * > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
Definition: CompetingMuonClustersOnTrack.h:184
Trk::Surface::insideBounds
virtual bool insideBounds(const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const =0
virtual methods to be overwritten by the inherited surfaces
Trk::IExtrapolator
Definition: IExtrapolator.h:62
MuonDetectorManager.h
Trk::MeasurementBase::localParameters
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
Definition: MeasurementBase.h:132
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
IdentifiableContainerMT::indexFindPtr
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
Definition: IdentifiableContainerMT.h:292
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
Muon::CscClusterOnTrack
Class to represent the calibrated clusters created from CSC strips.
Definition: CscClusterOnTrack.h:47
Trk::numberOfStgcPhiHits
@ numberOfStgcPhiHits
number of TGC Phi measurements missing from the track
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:130
Muon::CscStatusSplitUnspoiled
@ CscStatusSplitUnspoiled
Clean cluster with precision fit after split cluster.
Definition: CscClusterStatus.h:59
Trk::Surface::globalToLocal
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...
MuonGM::MuonDetectorManager
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:49
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Muon::CscClusterOnTrack::status
CscClusterStatus status() const
Returns Csc position measurement status flag.
Definition: CscClusterOnTrack.h:178
MuonTrackSummaryHelperTool.h
MuonGM::MdtReadoutElement::surface
virtual const Trk::Surface & surface() const override final
Return surface associated with this detector element.
Definition: MuonDetDescr/MuonReadoutGeometry/src/MdtReadoutElement.cxx:875
Trk::RIO_OnTrack::identify
virtual Identifier identify() const final
return the identifier -extends MeasurementBase
Definition: RIO_OnTrack.h:155
Trk::TrackStateOnSurface::Scatterer
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
Definition: TrackStateOnSurface.h:113
SG::VarHandleBase::isPresent
bool isPresent() const
Is the referenced object present in SG?
Definition: StoreGate/src/VarHandleBase.cxx:397
Trk::MuonTrackSummary::ChamberHitSummary::Projection
structure to hold the information for the eta/phi projection of RPC, TGC and CSC chambers and per mul...
Definition: MuonTrackSummary.h:38
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
Trk::numberOfRpcEtaHits
@ numberOfRpcEtaHits
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:110
ReadHandle.h
Handle class for reading from StoreGate.
Trk::Surface
Definition: Tracking/TrkDetDescr/TrkSurfaces/TrkSurfaces/Surface.h:75
Muon::MMClusterOnTrack::detectorElement
virtual const MuonGM::MMReadoutElement * detectorElement() const
Returns the detector element, assoicated with the PRD of this class.
Definition: MMClusterOnTrack.h:139
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
Trk::numberOfCscPhiHits
@ numberOfCscPhiHits
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:107
Muon::MdtPrepData::detectorElement
virtual const MuonGM::MdtReadoutElement * detectorElement() const override
Returns the detector element corresponding to this PRD.
Definition: MdtPrepData.h:156
Muon::MuonDriftCircleErrorStrategy::creationParameter
bool creationParameter(CreationParameter) const
Definition: MuonDriftCircleErrorStrategy.h:84
TrackStateOnSurface.h
Trk::StraightLineSurface
Definition: StraightLineSurface.h:51
Trk::numberOfMdtHits
@ numberOfMdtHits
number of mdt hits
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:103
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
Muon::MuonTrackSummaryHelperTool::updateHoleContent
void updateHoleContent(Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary) const
Definition: MuonTrackSummaryHelperTool.cxx:371
SCT_Monitoring::summary
@ summary
Definition: SCT_MonitoringNumbers.h:65