ATLAS Offline Software
Loading...
Searching...
No Matches
Muon::MuonTrackSummaryHelperTool Class Reference

#include <MuonTrackSummaryHelperTool.h>

Inheritance diagram for Muon::MuonTrackSummaryHelperTool:
Collaboration diagram for Muon::MuonTrackSummaryHelperTool:

Public Member Functions

 MuonTrackSummaryHelperTool (const std::string &, const std::string &, const IInterface *)
virtual ~MuonTrackSummaryHelperTool ()=default
virtual StatusCode initialize () override
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 analyse (const Trk::Track &trk, const Trk::CompetingRIOsOnTrack *crot, 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
virtual void addDetailedTrackSummary (const Trk::Track &track, Trk::TrackSummary &summary) const override final

Private Member Functions

const MdtPrepDataCollectionfindMdtPrdCollection (const Identifier &chId) const
void calculateRoadHits (Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary, const Trk::TrackParameters &pars) const
bool isFirstProjection (const Identifier &id) const
void updateHoleContent (Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary) const

Static Private Member Functions

static void increment (int &type)
 increment the 'type'

Private Attributes

ServiceHandle< Muon::IMuonIdHelperSvcm_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
ToolHandle< Trk::IExtrapolatorm_slExtrapolator {this, "StaightLineExtrapolator", "Trk::Extrapolator/MuonStraightLineExtrapolator"}
ToolHandle< Trk::IExtrapolatorm_extrapolator {this, "Extrapolator", "Trk::Extrapolator/AtlasExtrapolator"}
Gaudi::Property< bool > m_calculateCloseHits {this, "CalculateCloseHits", false}
 allow us to block the calculation of close hits
Gaudi::Property< double > m_roadWidth {this, "RoadWidth", 135., "width used to calculate hits within the road (mm)"}
 width road use to associate close hits
SG::ReadHandleKey< Muon::MdtPrepDataContainerm_mdtKey {this, "MdtPrepDataContainer", "MDT_DriftCircles", "MDT PRDs"}
 storegate key of MdtPrepDataContainer
SG::ReadCondHandleKey< MuonGM::MuonDetectorManagerm_DetectorManagerKey

Detailed Description

Definition at line 39 of file MuonTrackSummaryHelperTool.h.

Constructor & Destructor Documentation

◆ MuonTrackSummaryHelperTool()

Muon::MuonTrackSummaryHelperTool::MuonTrackSummaryHelperTool ( const std::string & t,
const std::string & n,
const IInterface * p )

Definition at line 29 of file MuonTrackSummaryHelperTool.cxx.

29 :
30 base_class(t, n, p) {
31 declareInterface<ITrackSummaryHelperTool>(this);
32}

◆ ~MuonTrackSummaryHelperTool()

virtual Muon::MuonTrackSummaryHelperTool::~MuonTrackSummaryHelperTool ( )
virtualdefault

Member Function Documentation

◆ addDetailedTrackSummary()

void Muon::MuonTrackSummaryHelperTool::addDetailedTrackSummary ( const Trk::Track & track,
Trk::TrackSummary & summary ) const
finaloverridevirtual

go back through the chamber, nallhitsinroad - nhitsontrack = ncloseHits for both projection1 and projection2 pass chamber summary to function calculateRoadHits(currentChamberSummary)

check whether first chamber or new chamber

calculate road hits for last chamber on track (otherwise it would have been skipped)

Definition at line 115 of file MuonTrackSummaryHelperTool.cxx.

115 {
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
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) {
190 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj =
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 ");
197 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj = currentChamberSummary->m_second;
198 ++proj.nholes;
199 } else {
200 ATH_MSG_VERBOSE(" counting sTGC eta hole ");
201 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj = currentChamberSummary->m_first;
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();
266 if (!errStrat.creationParameter(MuonDriftCircleErrorStrategy::FixedError) &&
267 !errStrat.creationParameter(MuonDriftCircleErrorStrategy::StationError)) {
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
334 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj =
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}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
bool is_valid() const
Check if id is in a valid state.
const MuonDriftCircleErrorStrategy & errorStrategy() const
Get information about the creation strategy used by Muon::MdtDriftCircleOnTrackCreator when making th...
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
const MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const std::vector< const MuonClusterOnTrack * > & containedROTs() const
returns the vector of SCT_ClusterOnTrack objects .
CscClusterStatus status() const
Returns Csc position measurement status flag.
@ 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
void calculateRoadHits(Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary, const Trk::TrackParameters &pars) const
void updateHoleContent(Trk::MuonTrackSummary::ChamberHitSummary &chamberHitSummary) const
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
bool isFirstProjection(const Identifier &id) const
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
const LocalParameters & localParameters() const
Interface method to get the LocalParameters.
virtual const Surface & associatedSurface() const =0
Interface method to get the associated Surface.
std::vector< ChamberHitSummary > m_chamberHitSummary
unsigned int m_npseudoMeasurements
Identifier identify() const
return the identifier -extends MeasurementBase
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.
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
@ 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.
Eigen::Matrix< double, 2, 1 > Vector2D
@ CscStatusUnspoiled
Clean cluster with precision fit.
@ CscStatusSplitUnspoiled
Clean cluster with precision fit after split cluster.
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ locR
Definition ParamDefs.h:44
ParametersBase< TrackParametersDim, Charged > TrackParameters
bool isMdt() const
returns whether this is a MDT chamber

◆ analyse() [1/2]

void Muon::MuonTrackSummaryHelperTool::analyse ( const Trk::Track & trk,
const Trk::CompetingRIOsOnTrack * crot,
const Trk::TrackStateOnSurface * tsos,
std::vector< int > & information,
std::bitset< Trk::numberOfDetectorTypes > & hitPattern ) const
finaloverridevirtual

Definition at line 85 of file MuonTrackSummaryHelperTool.cxx.

87 {
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}
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 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.

◆ analyse() [2/2]

void Muon::MuonTrackSummaryHelperTool::analyse ( const Trk::Track & trk,
const Trk::RIO_OnTrack * rot,
const Trk::TrackStateOnSurface * tsos,
std::vector< int > & information,
std::bitset< Trk::numberOfDetectorTypes > & hitPattern ) const
finaloverridevirtual
Parameters
trktrk
hitPatternhitPattern

Definition at line 43 of file MuonTrackSummaryHelperTool.cxx.

45 {
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 }
CscClusterStatus status() const
Returns Csc position measurement status flag.
static void increment(int &type)
increment the 'type'
bool type(const TrackStateOnSurfaceType type) const
Use this method to find out if the TSoS is of a certain type: i.e.

◆ calculateRoadHits()

void Muon::MuonTrackSummaryHelperTool::calculateRoadHits ( Trk::MuonTrackSummary::ChamberHitSummary & chamberHitSummary,
const Trk::TrackParameters & pars ) const
private

Definition at line 423 of file MuonTrackSummaryHelperTool.cxx.

424 {
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}
#define AmgSymMatrix(dim)
const_iterator end() const noexcept
const_iterator begin() const noexcept
virtual const Trk::Surface & surface() const override final
Return surface associated with this detector element.
virtual const MuonGM::MdtReadoutElement * detectorElement() const override
Returns the detector element corresponding to this PRD.
const MdtPrepDataCollection * findMdtPrdCollection(const Identifier &chId) const
ToolHandle< Trk::IExtrapolator > m_extrapolator
Gaudi::Property< double > m_roadWidth
width road use to associate close hits
ToolHandle< Trk::IExtrapolator > m_slExtrapolator
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.
Identifier identify() const
return the identifier
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
MuonPrepDataCollection< MdtPrepData > MdtPrepDataCollection
@ anyDirection
const Identifier & chamberId() const
returns the chamber identifier

◆ findMdtPrdCollection()

const Muon::MdtPrepDataCollection * Muon::MuonTrackSummaryHelperTool::findMdtPrdCollection ( const Identifier & chId) const
private

Definition at line 546 of file MuonTrackSummaryHelperTool.cxx.

546 {
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}
SG::ReadHandleKey< Muon::MdtPrepDataContainer > m_mdtKey
storegate key of MdtPrepDataContainer

◆ increment()

void Muon::MuonTrackSummaryHelperTool::increment ( int & type)
staticprivate

increment the 'type'

Definition at line 103 of file MuonTrackSummaryHelperTool.cxx.

103 {
104 if (type < 0)
105 type = 1; // they all start off at -1, so can't just increment
106 else
107 ++type;
108}

◆ initialize()

StatusCode Muon::MuonTrackSummaryHelperTool::initialize ( )
overridevirtual

Definition at line 34 of file MuonTrackSummaryHelperTool.cxx.

34 {
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}
#define ATH_CHECK
Evaluate an expression and check for errors.

◆ isFirstProjection()

bool Muon::MuonTrackSummaryHelperTool::isFirstProjection ( const Identifier & id) const
private

Definition at line 541 of file MuonTrackSummaryHelperTool.cxx.

541 {
542 if (!m_idHelperSvc->isMdt(id)) { return !m_idHelperSvc->measuresPhi(id); }
543 return m_idHelperSvc->mdtIdHelper().multilayer(id) == 1;
544}

◆ searchForHoles()

void Muon::MuonTrackSummaryHelperTool::searchForHoles ( const Trk::Track & track,
std::vector< int > & information,
Trk::ParticleHypothesis hyp ) const
finaloverridevirtual
Parameters
tracktrack
informationinformation
hyphyp

Definition at line 110 of file MuonTrackSummaryHelperTool.cxx.

111 {
112 ATH_MSG_WARNING("searchForHoles is not implemented in MuonTrackSummaryHelperTool");
113}

◆ updateHoleContent()

void Muon::MuonTrackSummaryHelperTool::updateHoleContent ( Trk::MuonTrackSummary::ChamberHitSummary & chamberHitSummary) const
private

Definition at line 371 of file MuonTrackSummaryHelperTool.cxx.

371 {
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}
const TgcReadoutElement * getTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
int nGasGaps() const
Returns the number of gas gaps associated with the readout element (2 or 3)
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...

Member Data Documentation

◆ m_calculateCloseHits

Gaudi::Property<bool> Muon::MuonTrackSummaryHelperTool::m_calculateCloseHits {this, "CalculateCloseHits", false}
private

allow us to block the calculation of close hits

Definition at line 78 of file MuonTrackSummaryHelperTool.h.

78{this, "CalculateCloseHits", false};

◆ m_DetectorManagerKey

SG::ReadCondHandleKey<MuonGM::MuonDetectorManager> Muon::MuonTrackSummaryHelperTool::m_DetectorManagerKey
private
Initial value:
{this, "DetectorManagerKey", "MuonDetectorManager",
"Key of input MuonDetectorManager condition data"}

Definition at line 86 of file MuonTrackSummaryHelperTool.h.

86 {this, "DetectorManagerKey", "MuonDetectorManager",
87 "Key of input MuonDetectorManager condition data"};

◆ m_extrapolator

ToolHandle<Trk::IExtrapolator> Muon::MuonTrackSummaryHelperTool::m_extrapolator {this, "Extrapolator", "Trk::Extrapolator/AtlasExtrapolator"}
private

Definition at line 75 of file MuonTrackSummaryHelperTool.h.

75{this, "Extrapolator", "Trk::Extrapolator/AtlasExtrapolator"};

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> Muon::MuonTrackSummaryHelperTool::m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
private

Definition at line 69 of file MuonTrackSummaryHelperTool.h.

69{this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};

◆ m_mdtKey

SG::ReadHandleKey<Muon::MdtPrepDataContainer> Muon::MuonTrackSummaryHelperTool::m_mdtKey {this, "MdtPrepDataContainer", "MDT_DriftCircles", "MDT PRDs"}
private

storegate key of MdtPrepDataContainer

Definition at line 84 of file MuonTrackSummaryHelperTool.h.

84{this, "MdtPrepDataContainer", "MDT_DriftCircles", "MDT PRDs"};

◆ m_roadWidth

Gaudi::Property<double> Muon::MuonTrackSummaryHelperTool::m_roadWidth {this, "RoadWidth", 135., "width used to calculate hits within the road (mm)"}
private

width road use to associate close hits

Definition at line 81 of file MuonTrackSummaryHelperTool.h.

81{this, "RoadWidth", 135., "width used to calculate hits within the road (mm)"};

◆ m_slExtrapolator

ToolHandle<Trk::IExtrapolator> Muon::MuonTrackSummaryHelperTool::m_slExtrapolator {this, "StaightLineExtrapolator", "Trk::Extrapolator/MuonStraightLineExtrapolator"}
private

Definition at line 72 of file MuonTrackSummaryHelperTool.h.

72{this, "StaightLineExtrapolator", "Trk::Extrapolator/MuonStraightLineExtrapolator"};

The documentation for this class was generated from the following files: