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 EventContext &ctx, const Trk::Track &trk, const Trk::RIO_OnTrack *rot, const Trk::TrackStateOnSurface *tsos, std::vector< int > &information, std::bitset< Trk::numberOfDetectorTypes > &hitPattern) const override final
virtual void analyse (const EventContext &ctx, 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 EventContext &ctx, 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 EventContext & ctx,
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
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 for (const auto& cl_it : crot->containedROTs()) {
292 // get layer Identifier and insert it into set
293 Identifier layId = m_idHelperSvc->layerId(cl_it->identify());
294 layIds.insert(layId);
295 if (m_idHelperSvc->isCsc(id)) {
296 const Muon::CscClusterOnTrack* cscClus = dynamic_cast<const Muon::CscClusterOnTrack*>(rot);
297 if (cscClus) {
300 goodLayIds.insert(layId);
301 }
302 }
303 }
304 } else {
305 continue;
306 }
307 }
308 Identifier chId = m_idHelperSvc->chamberId(id);
309 // for is summary sTGC split STGC1 and STGC2
310 bool issTgc = m_idHelperSvc->issTgc(id);
311 if (issTgc) chId = m_idHelperSvc->detElId(id);
312 bool isFirst = isFirstProjection(id);
313 bool isMdt = m_idHelperSvc->isMdt(id);
314 ATH_MSG_VERBOSE(" Adding hit " << m_idHelperSvc->toString(id));
315
317 if (!currentChamberSummary || currentChamberSummary->m_chId != chId) {
318 if (m_calculateCloseHits && currentChamberSummary && currentChamberPars) {
319 ATH_MSG_VERBOSE(" Calculating close hits (last hit a measurement)");
320 calculateRoadHits(*currentChamberSummary, *currentChamberPars);
321 }
322
323 // given that we cannot separate eta/phi holes, redo the assignment before moving to the next chamber
324 if (currentChamberSummary && !currentChamberSummary->isMdt()) { updateHoleContent(*currentChamberSummary); }
325
326 ATH_MSG_VERBOSE(" Adding new chamber " << m_idHelperSvc->toString(id) << " " << *pars);
327 trackSummary.m_chamberHitSummary.emplace_back(chId, isMdt);
328 currentChamberSummary = &trackSummary.m_chamberHitSummary.back();
329 currentChamberPars = pars;
330 }
331
332 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj =
333 isFirst ? currentChamberSummary->m_first : currentChamberSummary->m_second;
334
335 if ((*tsit)->type(Trk::TrackStateOnSurface::Outlier)) {
336 // MDTs: count outlier as delta electron if rDrift < rTrack < innerTubeRadius
337 if (isMdt && pars) {
338 double rDrift = std::abs(meas->localParameters()[Trk::locR]);
339 double rTrack = std::abs(pars->parameters()[Trk::locR]);
340 double innerRadius = MuonDetMgr->getMdtReadoutElement(id)->innerTubeRadius();
341 if (rTrack > rDrift && rTrack < innerRadius) {
342 ++proj.ndeltas;
343 continue;
344 }
345 }
346 ++proj.noutliers;
347
348 } else {
349 proj.nhits += layIds.size();
350 proj.ngoodHits += goodLayIds.size();
351 }
352 if (!inBounds && isMdt) proj.noutBounds++;
353
354 } // end of for loop over Track State on Surfaces
355
358 if (m_calculateCloseHits && currentChamberSummary && currentChamberPars) {
359 ATH_MSG_VERBOSE(" Calculating close hits (end of hit list)");
360 calculateRoadHits(*currentChamberSummary, *currentChamberPars);
361 }
362
363 // given that we cannot separate eta/phi holes, redo the assignment before moving to the next chamber
364 if (currentChamberSummary && !currentChamberSummary->isMdt()) { updateHoleContent(*currentChamberSummary); }
365
366 summary.m_muonTrackSummary.reset(muonTrackSummary);
367}
#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< std::unique_ptr< 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 EventContext & ctx,
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(ctx, trk, rot, tsos, information, hitPattern);
99 }
100 }
101}
virtual void analyse(const EventContext &ctx, const Trk::Track &trk, const Trk::RIO_OnTrack *rot, const Trk::TrackStateOnSurface *tsos, std::vector< int > &information, std::bitset< Trk::numberOfDetectorTypes > &hitPattern) const override final
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 EventContext & ctx,
const Trk::Track & trk,
const Trk::RIO_OnTrack * rot,
const Trk::TrackStateOnSurface * tsos,
std::vector< int > & information,
std::bitset< Trk::numberOfDetectorTypes > & hitPattern ) const
finaloverridevirtual
Parameters
ctxctx
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 421 of file MuonTrackSummaryHelperTool.cxx.

422 {
423 const EventContext& ctx = Gaudi::Hive::currentContext();
424 bool isStraightLine = false;
425 if (pars.parameters().rows() < 5) { // no momentum parameter given
426 isStraightLine = true;
427 } else if (std::abs(pars.parameters()[4]) < 1e-8) { // |p| > 1e8 MeV = 100 TeV
428 isStraightLine = true;
429 } else {
430 // Determine if TrackParameters correspond to a straight track (the ugly way)
431 if (pars.covariance()) {
432 const AmgSymMatrix(5)& covMat = *pars.covariance();
433 if (covMat.rows() < 5) { // no momentum available
434 isStraightLine = true;
435 } else {
436 // if no error on momentum given, assume no momentum was measured (extrapolator fails on zero error)
437 if (std::abs(covMat(4, 4)) < 1e-20) isStraightLine = true;
438 }
439 }
440 }
441 const Trk::IExtrapolator* extrapolator{nullptr};
442 if (m_extrapolator.isEnabled()) extrapolator = m_extrapolator.get();
443 if (isStraightLine && m_slExtrapolator.isEnabled()) {
444 extrapolator = m_slExtrapolator.get();
445 }
446 if (!extrapolator) return;
447
448 ATH_MSG_DEBUG("road hits for chamber " << m_idHelperSvc->toString(chamberHitSummary.chamberId()));
449
450 // currently treating MDTs only
451 if (!chamberHitSummary.isMdt()) return;
452
453 // loop over Mdt Prds (all hits in this chamber) and try to find prds of tubes with hits
454 const Muon::MdtPrepDataCollection* mdtPrdCol = findMdtPrdCollection(chamberHitSummary.chamberId());
455 if (!mdtPrdCol) {
456 ATH_MSG_DEBUG(" Retrieval of MdtPrepDataCollection failed!! ");
457 return;
458 }
459
460 if (isStraightLine) {
461 ATH_MSG_VERBOSE("Doing straight line extrapolation to get hits in road");
462 } else {
463 ATH_MSG_VERBOSE("Doing curved track extrapolation to get hits in road");
464 }
465
466 std::set<Identifier> addedIds;
467
470 for (; pit != pit_end; ++pit) {
471 const Muon::MdtPrepData& mdtPrd = **pit; // hit
472 const Identifier& id = mdtPrd.identify();
473
474 bool isFirst = isFirstProjection(id);
475 Trk::MuonTrackSummary::ChamberHitSummary::Projection& proj = isFirst ? chamberHitSummary.m_first : chamberHitSummary.m_second;
476
477 const Trk::Surface& surf = mdtPrd.detectorElement()->surface(id);
478
479 const Trk::TrackParameters* exPars = nullptr;
480 if (pars.associatedSurface() == surf) {
481 exPars = &pars;
482 } else {
483 exPars = extrapolator->extrapolateDirectly(ctx,
484 pars,
485 surf,
486 Trk::anyDirection, false, Trk::muon).release();
487 if (!exPars) {
488 if (isStraightLine) {
489 ATH_MSG_DEBUG(" Straight line propagation to prd " << m_idHelperSvc->toString(id) << " failed");
490 } else {
491 ATH_MSG_DEBUG(" Curved track propagation to prd " << m_idHelperSvc->toString(id) << " failed");
492 }
493 continue;
494 }
495 }
496
497 // use exPars to get distance to wire
498 double distance = exPars->parameters()[Trk::locR];
499
500 // sometimes there is more than one hit in a tube,
501 // which means there are two hits where the distance is the same but the tdc is different
502 if (addedIds.count(id)) {
503 ATH_MSG_DEBUG(" same tube hit, not adding to close hits in road");
504 } else {
505 // add all hits within the road width (defined in job options)
506 if (std::abs(distance) < m_roadWidth) {
507 ATH_MSG_VERBOSE("Hit ID within road: " << m_idHelperSvc->toString(id) << " distance " << distance << " < " << m_roadWidth);
508 ++proj.ncloseHits;
509 addedIds.insert(id);
510 } else {
511 ATH_MSG_VERBOSE("Hit ID outside road: " << m_idHelperSvc->toString(id) << " distance " << distance
512 << " >= " << m_roadWidth);
513 }
514 }
515 // to avoid double deleting when track is deleted, only delete
516 // exPars when it's not the TrackParameters which was passed (pars)
517 if (exPars != &pars) delete exPars;
518 }
519
520 // subtract the hits on the track in both projections:
521 chamberHitSummary.m_first.ncloseHits -= chamberHitSummary.m_first.nhits;
522 chamberHitSummary.m_second.ncloseHits -= chamberHitSummary.m_second.nhits;
523
524 if (chamberHitSummary.m_first.ncloseHits < 0) {
525 ATH_MSG_DEBUG("Number of hits in road < 0 in first projection: " << chamberHitSummary.m_first.ncloseHits
526 << ", setting = 0. (nhits in first projection = "
527 << chamberHitSummary.m_first.ncloseHits << ")");
528 chamberHitSummary.m_first.ncloseHits = 0;
529 }
530
531 if (chamberHitSummary.m_second.ncloseHits < 0) {
532 ATH_MSG_DEBUG("Number of hits in road < 0 in second projection: " << chamberHitSummary.m_second.ncloseHits
533 << ", setting = 0. (nhits in second projection = "
534 << chamberHitSummary.m_second.ncloseHits << ")");
535 chamberHitSummary.m_second.ncloseHits = 0;
536 }
537}
#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 544 of file MuonTrackSummaryHelperTool.cxx.

544 {
545 const EventContext& ctx = Gaudi::Hive::currentContext();
546 SG::ReadHandle<Muon::MdtPrepDataContainer> mdtPrdContainer(m_mdtKey, ctx);
547
548 if (!mdtPrdContainer.isValid()) {
549 ATH_MSG_WARNING("Cannot retrieve mdtPrepDataContainer " << m_mdtKey);
550 return nullptr;
551 }
552
553 if (!mdtPrdContainer.isPresent()) {
554 ATH_MSG_DEBUG("No MDT PRD container available");
555 return nullptr;
556 }
557
558 IdentifierHash hash_id;
559 m_idHelperSvc->mdtIdHelper().get_module_hash(chId, hash_id);
560
561 const auto *coll = mdtPrdContainer->indexFindPtr(hash_id);
562 if (coll == nullptr) {
563 ATH_MSG_DEBUG(" MdtPrepDataCollection for: " << m_idHelperSvc->toStringChamber(chId) << " not found in container ");
564 return nullptr;
565 }
566 return coll;
567}
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 539 of file MuonTrackSummaryHelperTool.cxx.

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

◆ 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 369 of file MuonTrackSummaryHelperTool.cxx.

369 {
370 if (m_idHelperSvc->issTgc(chamberHitSummary.chamberId())) {
371 ATH_MSG_DEBUG(" holes eta " << chamberHitSummary.etaProjection().nholes << " phi " << chamberHitSummary.phiProjection().nholes);
372 }
373
374 if (m_idHelperSvc->issTgc(chamberHitSummary.chamberId()) || m_idHelperSvc->isMM(chamberHitSummary.chamberId())) { return; }
375
376 const EventContext& ctx = Gaudi::Hive::currentContext();
377 SG::ReadCondHandle<MuonGM::MuonDetectorManager> DetectorManagerHandle{m_DetectorManagerKey, ctx};
378 const MuonGM::MuonDetectorManager* MuonDetMgr{*DetectorManagerHandle};
379 if (!MuonDetMgr) {
380 ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
381 return;
382 }
383
384 bool isCsc = m_idHelperSvc->isCsc(chamberHitSummary.chamberId());
385 int neta = isCsc ? 4 : 2;
386 int nphi = isCsc ? 4 : 2;
387 if (m_idHelperSvc->isTgc(chamberHitSummary.chamberId())) {
388 const MuonGM::TgcReadoutElement* detEl = MuonDetMgr->getTgcReadoutElement(chamberHitSummary.chamberId());
389 if (!detEl) {
390 ATH_MSG_WARNING(" No detector element found for " << m_idHelperSvc->toStringChamber(chamberHitSummary.chamberId()));
391 return;
392 }
393
394 // get list of layers with a hole
395 neta = detEl->nGasGaps();
396 }
397
398 // code to recalculate the hole counts as they are not correct.
399 // This is due to the fact that the identification of the layers goes via the readout element identifier
400 // so it is not possible to separate eta and phi holes
401 int nMisEta = neta - chamberHitSummary.etaProjection().nhits - chamberHitSummary.etaProjection().noutliers;
402 int nMisPhi = nphi - chamberHitSummary.phiProjection().nhits - chamberHitSummary.phiProjection().noutliers;
403 int nholes = chamberHitSummary.etaProjection().nholes + chamberHitSummary.phiProjection().nholes;
404 if (nMisEta > 0 && nholes > 0) {
405 chamberHitSummary.m_first.nholes = nMisEta;
406 nholes -= nMisEta;
407 }
408 if (nMisPhi > 0 && nholes > 0) {
409 chamberHitSummary.m_second.nholes = nholes;
410 if (nholes != nMisPhi) {
411 ATH_MSG_DEBUG("Inconsistent hole count: expected hits eta "
412 << neta << " phi " << nphi << " hits eta "
413 << chamberHitSummary.etaProjection().nhits + chamberHitSummary.etaProjection().noutliers << " phi "
414 << chamberHitSummary.phiProjection().nhits + chamberHitSummary.phiProjection().noutliers << " missed eta "
415 << nMisEta << " phi " << nMisPhi << " holes eta " << chamberHitSummary.etaProjection().nholes << " phi "
416 << chamberHitSummary.phiProjection().nholes << " recalculated phi holes " << nholes);
417 }
418 }
419}
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: