ATLAS Offline Software
Loading...
Searching...
No Matches
EMTrackMatchBuilder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4
5// INCLUDE HEADER FILES:
6
8
11
16
20
21#include "GaudiKernel/EventContext.h"
24
25// END OF HEADER FILES INCLUDE
26
28
30 const std::string& name,
31 const IInterface* parent)
32 : AthAlgTool(type, name, parent)
33{
34 // declare interface
35 declareInterface<IEMTrackMatchBuilder>(this);
36}
37
38StatusCode
40{
41 ATH_CHECK(m_TrackParticlesKey.initialize());
42 ATH_CHECK(m_caloDetDescrMgrKey.initialize());
43 // the extrapolation tool
45
46 // set things up for the sorting
51
52 return StatusCode::SUCCESS;
53}
54
55StatusCode
56EMTrackMatchBuilder::executeRec(const EventContext& ctx,
57 EgammaRecContainer* egammas) const
58{
59 // protection against bad pointers
60 if (egammas == nullptr) {
61 return StatusCode::SUCCESS;
62 }
63 // retrieve the trackparticle container
65 ctx);
66
67 SG::ReadCondHandle<CaloDetDescrManager> caloDetDescrMgrHandle{
69 };
70 ATH_CHECK(caloDetDescrMgrHandle.isValid());
71
72 const CaloDetDescrManager* caloDD = *caloDetDescrMgrHandle;
73
74 // check is only used for serial running; remove when MT scheduler used
75 ATH_CHECK(trackPC.isValid());
76 // Loop over calling the trackExecute method
77 for (egammaRec* eg : *egammas) {
78 // retrieve the cluster
79 ATH_CHECK(trackExecute(ctx, eg, trackPC.cptr(), *caloDD));
80 }
81 return StatusCode::SUCCESS;
82}
83
84StatusCode
85EMTrackMatchBuilder::trackExecute(const EventContext& ctx,
86 egammaRec* eg,
87 const xAOD::TrackParticleContainer* trackPC,
88 const CaloDetDescrManager& caloDD) const
89{
90 if (!eg || !trackPC) {
92 "trackExecute: NULL pointer to egammaRec or TrackParticleContainer");
93 return StatusCode::SUCCESS;
94 }
95 // retrieve corresponding cluster
96 const xAOD::CaloCluster* cluster = eg->caloCluster();
97 // check if the cluster is sane
98 if (cluster && cluster->e() == 0.0) {
99 ATH_MSG_WARNING("trackExecute: cluster energy is 0.0! Ignoring cluster.");
100 return StatusCode::SUCCESS;
101 }
102
103 // Loop over tracks and fill TrackMatch vector
104 std::vector<TrackMatch> trkMatches;
106 for (unsigned int trackNumber = 0; trkIt != trackPC->end();
107 ++trkIt, ++trackNumber) {
108 // Avoid TRT alone
109 if (xAOD::EgammaHelpers::numberOfSiHits(*trkIt) < 4) {
110 continue;
111 }
112 /*
113 * Try with normal directions.
114 * For cosmics allow a retry with inverted direction.
115 */
116 if (isCandidateMatch(cluster, (*trkIt), false)) {
117 inBroadWindow(ctx, trkMatches, *cluster, trackNumber, (**trkIt), caloDD);
118 }
119 }
120
121 if (!trkMatches.empty()) {
122 // sort the track matches
123 std::sort(trkMatches.begin(), trkMatches.end(), m_sorter);
124 // set the matching values
125 TrackMatch bestTrkMatch = trkMatches.at(0);
126 eg->setDeltaEta(bestTrkMatch.deltaEta);
127 eg->setDeltaPhi(bestTrkMatch.deltaPhi);
128 eg->setDeltaPhiRescaled(bestTrkMatch.deltaPhiRescaled);
129 eg->setDeltaPhiLast(bestTrkMatch.deltaPhiLast);
130
131 // set the element Links
133 std::vector<EL> trackParticleLinks;
134 trackParticleLinks.reserve(trkMatches.size());
135 const std::string key = EL(*trackPC, 0, ctx).dataID();
136 for (const TrackMatch& m : trkMatches) {
137 ATH_MSG_DEBUG("Match dR: " << m.dR << " second dR: " << m.seconddR
138 << " hasPix: " << m.hasPix
139 << " hitsScore: " << m.hitsScore);
140 if (key.empty()) {
141 trackParticleLinks.emplace_back(*trackPC, m.trackNumber, ctx);
142 } else {
143 trackParticleLinks.emplace_back(key, m.trackNumber, ctx);
144 }
145 }
146 eg->setTrackParticles(trackParticleLinks);
147 }
148 return StatusCode::SUCCESS;
149}
150
151bool
153 std::vector<TrackMatch>& trackMatches,
154 const xAOD::CaloCluster& cluster,
155 int trackNumber,
156 const xAOD::TrackParticle& trkPB,
157 const CaloDetDescrManager& caloDD) const
158{
159
162
163 // Now get the delta eta/phi and eta correction at the calorimeter
164 // final arrays that we will write
165 // Save the value of deltaPhiRescale. If we do not use rescaled
166 // perigee, we recalculate deltaPhi using rescaled momentum. This
167 // will be saved in EMTrackMatch
168 std::array<double, 4> eta = { -999.0, -999.0, -999.0, -999.0 };
169 std::array<double, 4> phi = { -999.0, -999.0, -999.0, -999.0 };
170 std::array<double, 4> deltaEta = { -999.0, -999.0, -999.0, -999.0 };
171 std::array<double, 4> deltaPhi = { -999.0, -999.0, -999.0, -999.0 };
172
173 /*
174 * Try both from perigee
175 * and from perigee Rescale.
176 *
177 * We need anyhow both to be there at the end.
178 */
179 std::pair<std::vector<CaloSampling::CaloSample>,
180 std::vector<std::unique_ptr<Trk::Surface>>>
181 layersAndSurfaces =
182 m_extrapolationTool->getClusterLayerSurfaces(cluster, caloDD);
184 ->getMatchAtCalo(ctx,
185 cluster,
186 trkPB,
187 layersAndSurfaces.first,
188 layersAndSurfaces.second,
189 eta,
190 phi,
191 deltaEta,
192 deltaPhi,
193 extrapFrom)
194 .isFailure()) {
195 return false;
196 }
197
200 std::array<double, 4> etaRes = { -999.0, -999.0, -999.0, -999.0 };
201 std::array<double, 4> phiRes = { -999.0, -999.0, -999.0, -999.0 };
202 std::array<double, 4> deltaEtaRes = { -999.0, -999.0, -999.0, -999.0 };
203 std::array<double, 4> deltaPhiRes = { -999.0, -999.0, -999.0, -999.0 };
204
206 ->getMatchAtCalo(ctx,
207 cluster,
208 trkPB,
209 layersAndSurfaces.first,
210 layersAndSurfaces.second,
211 etaRes,
212 phiRes,
213 deltaEtaRes,
214 deltaPhiRes,
215 extrapFromRes)
216 .isFailure()) {
217 return false;
218 }
219
220 double deltaPhiRescale = deltaPhiRes[2];
221 /*
222 * Sanity check for very far away matches
223 * The assumption is when we rescale we should be in the
224 * correct neighborhood for a valid track-cluster pair.
225 */
226 if (std::abs(deltaPhiRes[2]) > m_MaxDeltaPhiRescale) {
227 ATH_MSG_DEBUG("DeltaPhiRescaled above maximum: "
228 << deltaPhiRes[2] << " (max: " << m_MaxDeltaPhiRescale
229 << ")");
230 return false;
231 }
232 /*
233 * Try to match : First standard way.
234 * If this fails and the cluster Et is larger than the track Pt
235 * it might get matched only under the rescaled assumption that
236 * should be less sensitive to radiative losses.
237 */
238 if (std::abs(deltaEta[2]) < m_narrowDeltaEta && deltaPhi[2] < m_narrowDeltaPhi &&
240 ATH_MSG_DEBUG("Matched with Perigee");
241 } else if (m_SecondPassRescale && cluster.et() > trkPB.pt() &&
242 std::abs(deltaEtaRes[2]) < m_narrowDeltaEta &&
243 deltaPhiRes[2] < m_narrowDeltaPhiRescale &&
244 deltaPhiRes[2] > -m_narrowDeltaPhiRescaleBrem) {
245 ATH_MSG_DEBUG("Not Perigee but matched with Rescale");
246 } else {
247 ATH_MSG_DEBUG("Normal matched Failed deltaPhi/deltaEta "
248 << deltaPhi[2] << " / " << deltaEta[2]);
249 ATH_MSG_DEBUG("Rescaled matched Failed deltaPhi/deltaEta "
250 << deltaPhiRes[2] << " / " << deltaEtaRes[2]);
251 return false;
252 }
253
254 // Always the deltaPhiLast will be from the last measurement
257 std::array<double, 4> eta1 = { -999.0, -999.0, -999.0, -999.0 };
258 std::array<double, 4> phi1 = { -999.0, -999.0, -999.0, -999.0 };
259 std::array<double, 4> deltaEta1 = { -999.0, -999.0, -999.0, -999.0 };
260 std::array<double, 4> deltaPhi1 = { -999.0, -999.0, -999.0, -999.0 };
261
263 ->getMatchAtCalo(ctx,
264 cluster,
265 trkPB,
266 layersAndSurfaces.first,
267 layersAndSurfaces.second,
268 eta1,
269 phi1,
270 deltaEta1,
271 deltaPhi1,
272 extrapFrom1)
273 .isFailure()) {
274 ATH_MSG_DEBUG("Extrapolation from last measurement failed");
275 return false;
276 }
277 double deltaPhiLast = deltaPhi1[2];
278 ATH_MSG_DEBUG("Rescale dPhi " << deltaPhiRescale);
279 ATH_MSG_DEBUG("dPhi Last measurement " << deltaPhiLast);
280 /*
281 * Done with extrapolation
282 * Lets do the matching logic
283 */
284 TrackMatch trkmatch{};
285 // Add the matching variable to the TrackMAtch
286 trkmatch.deltaEta = deltaEta;
287 trkmatch.deltaPhi = deltaPhi;
288 trkmatch.deltaPhiRescaled = deltaPhiRes;
289 trkmatch.deltaPhiLast = deltaPhiLast;
290
291 // Variables used for the sorting. Note both dPhi's will be used.
292 trkmatch.trackNumber = trackNumber;
293 if (m_useRescaleMetric) {
294 trkmatch.dR = sqrt(std::pow(m_deltaEtaWeight * deltaEta[2], 2) +
295 std::pow(m_deltaPhiRescaleWeight * deltaPhiRescale, 2));
296 trkmatch.seconddR = sqrt(std::pow(m_deltaEtaWeight * deltaEta[2], 2) +
297 std::pow(m_deltaPhiWeight * deltaPhi[2], 2));
298 } else {
299 trkmatch.dR = sqrt(std::pow(m_deltaEtaWeight * deltaEta[2], 2) +
300 std::pow(m_deltaPhiWeight * deltaPhi[2], 2));
301 trkmatch.seconddR =
302 sqrt(std::pow(m_deltaEtaWeight * deltaEta[2], 2) +
303 std::pow(m_deltaPhiRescaleWeight * deltaPhiRescale, 2));
304 }
305 ATH_MSG_DEBUG(" DR " << trkmatch.dR << " deltaPhi " << deltaPhi[2]
306 << " deltaEta " << deltaEta[2]);
307 /*
308 * The first thing is
309 * Prefer pixel over SCT only
310 */
311 // Check number of pixel hits
312 int nPixel = summaryValueInt(trkPB, xAOD::numberOfPixelDeadSensors, 0);
313 nPixel += summaryValueInt(trkPB, xAOD::numberOfPixelHits, 0);
314 trkmatch.hasPix = (nPixel > 0);
315
316 /*
317 * Seconday hitsScore score based on hits to be used
318 * for track that are very close
319 * to each other at the calo i.e similar dR with cluster,
320 * pick the longest possible one
321 */
322 trkmatch.hitsScore = 0;
323 if (m_useScoring) {
324 // Check the 2 innermost layers
325 int nInnerMost = summaryValueInt(trkPB, xAOD::numberOfInnermostPixelLayerHits, 0);
326 int expectInnermostPixelLayerHit = summaryValueInt(trkPB, xAOD::expectInnermostPixelLayerHit, 0);
327 int nNextToInnerMost = summaryValueInt(trkPB, xAOD::numberOfNextToInnermostPixelLayerHits, 0);
328 int expectNextToInnermostPixelLayerHit = summaryValueInt(trkPB, xAOD::expectNextToInnermostPixelLayerHit, 0);
329
330 // Secondary score , find the longest track possible,
331 // i.e the one with the most inner hists in the pixel
332 // npixel*5
333 trkmatch.hitsScore += (nPixel * 5);
334 // Extra points for NextToInnermost
335 if (!expectNextToInnermostPixelLayerHit || nNextToInnerMost > 0) {
336 trkmatch.hitsScore += 5;
337 }
338 // Extra points for Innermost
339 if (!expectInnermostPixelLayerHit || nInnerMost > 0) {
340 trkmatch.hitsScore += 10;
341 }
342 }
343 ATH_MSG_DEBUG("hasPix : " << trkmatch.hasPix
344 << " hitsScore : " << trkmatch.hitsScore);
345
346 trackMatches.push_back(trkmatch);
347 return true;
348}
349
350bool
352 const xAOD::TrackParticle* track,
353 bool flip) const
354{
355 // loose cluster-track matching
356 if (!m_useCandidateMatch) {
357 return true;
358 }
359
360 // Tracking
361 const Trk::Perigee& candidatePerigee = track->perigeeParameters();
362 // Decide whether to try the opposite direction (cosmics)
363 const double trkPhi = (!flip) ? candidatePerigee.parameters()[Trk::phi]
364 : -candidatePerigee.parameters()[Trk::phi];
365 const double trkEta =
366 (!flip) ? candidatePerigee.eta() : -candidatePerigee.eta();
367 const double z_perigee = candidatePerigee.position().z();
368 const double r_perigee = candidatePerigee.position().perp();
369 const Amg::Vector3D PerigeeXYZPosition(candidatePerigee.position().x(),
370 candidatePerigee.position().y(),
371 z_perigee);
372 // Cluster variables
373 const double clusterEta = cluster->eta();
374 const bool isEndCap = !xAOD::EgammaHelpers::isBarrel(cluster);
375 const double Et = cluster->e() / cosh(trkEta);
376 const double clusterPhi = cluster->phi();
377
378 // Avoid clusters with |eta| > 10 or Et less than 10 MeV
379 if (std::abs(clusterEta) > 10.0 || Et < 10) {
380 return false;
381 }
382 // Calculate the eta/phi of the cluster as would be seen from the perigee
383 // position of the Track
384 const Amg::Vector3D XYZClusterWrtTrackPerigee =
386 *cluster, PerigeeXYZPosition, isEndCap);
387
388 const double clusterEtaCorrected = XYZClusterWrtTrackPerigee.eta();
389 // check eta match . Both metrics need to fail in order to disgard the track
390 if ((std::abs(clusterEta - trkEta) > 2. * m_broadDeltaEta) &&
391 (std::abs(clusterEtaCorrected - trkEta) > 2. * m_broadDeltaEta)) {
392 ATH_MSG_DEBUG(" Fails broad window eta match (track eta, cluster eta, "
393 "cluster eta corrected): ( "
394 << trkEta << ", " << clusterEta << ", " << clusterEtaCorrected
395 << ")");
396 return false;
397 }
398 // Calculate the possible rotation of the track
399 // Once assuming the cluster Et being the better estimate (e.g big brem)
400 const double phiRotRescaled = CandidateMatchHelpers::PhiROT(
401 Et, trkEta, track->charge(), r_perigee, isEndCap);
402 // And also assuming the track Pt being correct
403 const double phiRotTrack = CandidateMatchHelpers::PhiROT(
404 track->pt(), trkEta, track->charge(), r_perigee, isEndCap);
405 //
406 const double clusterPhiCorrected = XYZClusterWrtTrackPerigee.phi();
407 // deltaPhi between the track and the cluster
408 const double deltaPhiStd = P4Helpers::deltaPhi(clusterPhiCorrected, trkPhi);
409 // deltaPhi between the track and the cluster accounting for rotation assuming
410 // cluster Et is a better estimator
411 const double trkPhiRescaled = P4Helpers::deltaPhi(trkPhi, phiRotRescaled);
412 const double deltaPhiRescaled =
413 P4Helpers::deltaPhi(clusterPhiCorrected, trkPhiRescaled);
414 // deltaPhi between the track and the cluster accounting for rotation
415 const double trkPhiCorrTrack = P4Helpers::deltaPhi(trkPhi, phiRotTrack);
416 const double deltaPhiTrack =
417 P4Helpers::deltaPhi(clusterPhiCorrected, trkPhiCorrTrack);
418
419 // It has to fail all phi metrics in order to be disgarded
420 if ((std::abs(deltaPhiRescaled) > 2. * m_broadDeltaPhi) &&
421 (std::abs(deltaPhiTrack) > 2. * m_broadDeltaPhi) &&
422 (std::abs(deltaPhiStd) > 2. * m_broadDeltaPhi)) {
423
425 "FAILS broad window phi match (track phi, phirotCluster , phiRotTrack , "
426 << "cluster phi corrected, cluster phi): ( " << trkPhi << ", "
427 << phiRotRescaled << ", " << phiRotTrack << ", " << clusterPhiCorrected
428 << ", " << clusterPhi << ")");
429
430 return false;
431 }
432 // if not false returned we end up here
433 return true;
434}
435
436bool
439 const EMTrackMatchBuilder::TrackMatch& match2) const
440{
441 if (match1.hasPix != match2.hasPix) { // prefer pixels first
442 return match1.hasPix;
443 }
444 // sqrt(0.025**2)*sqrt(2)/sqrt(12) ~ 0.01
445 if (std::abs(match1.dR - match2.dR) < m_distance) {
446
447 if (std::abs(match1.seconddR - match2.seconddR) >
448 m_distance) { // Can the second distance separate them?
449 return match1.seconddR < match2.seconddR;
450 }
451 if ((match1.hitsScore != match2.hitsScore)) { // use the one with more pixel
452 return match1.hitsScore > match2.hitsScore;
453 }
454 }
455 // closest DR
456 return match1.dR < match2.dR;
457}
int summaryValueInt(const xAOD::TrackParticle &tp, const xAOD::SummaryType &info, int deflt=-999)
return the summary value for a TrackParticle or default value (-999) (to be used mostly in python whe...
Scalar eta() const
pseudorapidity method
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Hold a pointer to the current event store.
Handle class for reading from StoreGate.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
This class provides the client interface for accessing the detector description information common to...
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
function object to sort track matches based on quality
bool operator()(const TrackMatch &match1, const TrackMatch &match2) const
EMTrackMatchBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Default constructor.
Gaudi::Property< bool > m_useScoring
Boolean to apply heuristic when tracks have close deltaR.
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloDetDescrMgrKey
StatusCode initialize() override final
Gaudi algorithm hooks.
Gaudi::Property< double > m_narrowDeltaPhi
narrow cut on deltaPhiRescale
virtual StatusCode executeRec(const EventContext &ctx, EgammaRecContainer *egammas) const override final
execute method
Gaudi::Property< float > m_distanceForScore
The distance from which one goes from using better deltaR to using score.
ToolHandle< IEMExtrapolationTools > m_extrapolationTool
Gaudi::Property< double > m_MaxDeltaPhiRescale
@Maximum deltaPhi (Res) allowed for a match
bool isCandidateMatch(const xAOD::CaloCluster *cluster, const xAOD::TrackParticle *track, bool flip) const
Loose track-cluster matching.
SG::ReadHandleKey< xAOD::TrackParticleContainer > m_TrackParticlesKey
name of TrackParticle container in TDS
Gaudi::Property< double > m_narrowDeltaPhiRescale
narrow cut on deltaPhiRescale
Gaudi::Property< bool > m_useCandidateMatch
flag to turn on/off use of isCandidateMatch
bool inBroadWindow(const EventContext &ctx, std::vector< TrackMatch > &trackMatches, const xAOD::CaloCluster &cluster, int trackNumber, const xAOD::TrackParticle &trkPB, const CaloDetDescrManager &caloDD) const
Compute for tracks passing the loose matching the distance between track extrapolated to 2nd sampling...
Gaudi::Property< double > m_narrowDeltaPhiRescaleBrem
narrow cut on deltaPhiRescale for electrons
Gaudi::Property< float > m_deltaPhiRescaleResolution
Gaudi::Property< float > m_deltaPhiResolution
Gaudi::Property< bool > m_useRescaleMetric
Boolean to use Rescale in the metric.
StatusCode trackExecute(const EventContext &ctx, egammaRec *eg, const xAOD::TrackParticleContainer *trackPC, const CaloDetDescrManager &caloDD) const
execute method
Gaudi::Property< double > m_narrowDeltaEta
narrow cut on deltaEta
Gaudi::Property< bool > m_SecondPassRescale
Boolean to do second pass with Rescale.
Gaudi::Property< double > m_broadDeltaEta
broad cut on deltaEta
Gaudi::Property< double > m_broadDeltaPhi
broad cut on deltaPhi
Gaudi::Property< float > m_deltaEtaResolution
The resolutions: might be good to split in barrel/end-cap in the future.
Gaudi::Property< double > m_narrowDeltaPhiBrem
narrow cut on deltaPhi for electrons
TrackMatchSorter m_sorter
TrkExtrapDef
Enum for track extrapolation to calo.
@ fromPerigee
from the perigee of TrackParticle
@ fromLastMeasurement
from the last measurement of TrackParticle
@ fromPerigeeRescaled
from the perigee of TrackParticle recaled by Ecluster
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
double eta() const
Access method for pseudorapidity - from momentum.
const Amg::Vector3D & position() const
Access method for the position.
Represent an egamma object for internal egamma usage during reconstruction.
Definition egammaRec.h:31
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double e() const
The total energy of the particle.
virtual double phi() const
The azimuthal angle ( ) of the particle.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
DataVector< egammaRec > EgammaRecContainer
The container is a simple typedef for now.
Eigen::Matrix< double, 3, 1 > Vector3D
double PhiROT(const double pt, const double eta, const int charge, const double r_start, const bool isEndCap)
Function to calculate the approximate rotation in phi/bending of a track until it reaches the calo.
Amg::Vector3D approxXYZwrtPoint(const xAOD::CaloCluster &cluster, const Amg::Vector3D &point, const bool isEndCap)
Function to get the (x,y,z) of the cluster wrt to a point (x0,y0,z0)
This module defines the arguments passed from the BATCH driver to the BATCH worker.
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition P4Helpers.h:34
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ phi
Definition ParamDefs.h:75
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
bool isBarrel(const xAOD::Egamma *eg)
return true if the cluster is in the barrel
int summaryValueInt(const xAOD::TrackParticle &tp, const xAOD::SummaryType &info, int deflt=-999)
return the summary value for a TrackParticle or default value (-999) (to be used mostly in python whe...
std::size_t numberOfSiHits(const xAOD::TrackParticle *tp)
return the number of Si hits in the track particle
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfNextToInnermostPixelLayerHits
these are the hits in the 1st pixel barrel layer
@ expectNextToInnermostPixelLayerHit
Do we expect a 1st-layer barrel hit for this track?
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ numberOfPixelDeadSensors
number of dead pixel sensors crossed [unit8_t].
A structure for keeping track match information.
std::array< double, 4 > deltaPhiRescaled