ATLAS Offline Software
MuonTrackTagTestTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "MuonTrackTagTestTool.h"
6 
7 #include "GaudiKernel/MsgStream.h"
16 #include "TrkTrack/Track.h"
17 
18 #ifdef MUONCOMBDEBUG
19 #include "AtlasHepMC/GenParticle.h"
22 #endif
23 
24 namespace {
25  constexpr double dummy_chi2 = 1.e25;
26 }
27 namespace MuonCombined {
28 
29  MuonTrackTagTestTool::MuonTrackTagTestTool(const std::string &type, const std::string &name, const IInterface *parent) :
31  declareInterface<IMuonTrackTagTool>(this);
32  declareProperty("Chi2Cut", m_chi2cut = 50.);
33 #ifdef MUONCOMBDEBUG
34  declareProperty("Truth", m_truth = false);
35 #endif
36  }
37 
39  ATH_CHECK(m_extrapolator.retrieve());
42  } else {
43  ATH_MSG_ERROR("Could not retrieve a valid tracking geometry");
44  }
45 
46  ATH_MSG_INFO("Initialized successfully");
47 
48  return StatusCode::SUCCESS;
49  }
50 
51  double MuonTrackTagTestTool::chi2(const Trk::Track &idTrack, const Trk::Track &msTrack, const EventContext &ctx) const {
52  const Trk::TrackingVolume *msEntrance = getVolume("MuonSpectrometerEntrance", ctx);
53  if (!msEntrance) {
54  ATH_MSG_ERROR("No MS entrance available");
55  return dummy_chi2;
56  }
57  if (idTrack.perigeeParameters() == nullptr) {
58  ATH_MSG_WARNING("Skipping track combination - no perigee parameters for ID track");
59  return dummy_chi2;
60  }
61  if (msTrack.perigeeParameters() == nullptr) {
62  ATH_MSG_WARNING("Skipping track combination - no perigee parameters for MS track");
63  return dummy_chi2;
64  }
65  // skip tracks from backtracking
66  if (dynamic_cast<const Trk::StraightLineSurface *>(&(**idTrack.measurementsOnTrack()->begin()).associatedSurface())) return 0;
67  if (idTrack.measurementsOnTrack()->size() < 7 ||
68  dynamic_cast<const Trk::StraightLineSurface *>(&(*idTrack.measurementsOnTrack())[6]->associatedSurface()) ||
69  !dynamic_cast<const InDet::PixelClusterOnTrack *>(*idTrack.measurementsOnTrack()->begin()))
70  return 0;
73  int noutl = 0, ntrt = 0;
74  for (; itStates != endState; ++itStates) {
75  if ((**itStates).measurementOnTrack()) {
76  const InDet::TRT_DriftCircleOnTrack *trthit =
77  dynamic_cast<const InDet::TRT_DriftCircleOnTrack *>((**itStates).measurementOnTrack());
78  if (trthit) {
79  if ((**itStates).type(Trk::TrackStateOnSurface::Outlier))
80  noutl++;
81  else
82  ntrt++;
83  }
84  }
85  }
86  double eta = idTrack.perigeeParameters()->eta();
87  ATH_MSG_DEBUG("ntrt: " << ntrt << " ntrtoutl: " << noutl << " eta: " << eta);
88  if (noutl >= 15 || (ntrt == 0 && std::abs(eta) > .1 && std::abs(eta) < 1.9)) return 0;
89 
90  // skip tracks below 2.5 GeV
91  double idqoverp = idTrack.perigeeParameters()->parameters()[Trk::qOverP];
92  if (idqoverp != 0 && std::abs(1 / idqoverp) < 2500) return 0;
93 
94  const Trk::TrackParameters *muonpar = msTrack.trackParameters()->front();
95 
96  bool checkphiflip = false, muonisstraight = false;
97 
98  if (std::abs(muonpar->parameters()[Trk::qOverP]) < 1.e-9) checkphiflip = muonisstraight = true;
99 
100  double phiID = (**idTrack.trackParameters()->rbegin()).parameters()[Trk::phi], phiMS = muonpar->position().phi();
101  double thetaID = (**idTrack.trackParameters()->rbegin()).parameters()[Trk::theta], thetaMS = muonpar->parameters()[Trk::theta];
102 
103  ATH_MSG_DEBUG("phi ID: " << phiID << " phi MS: " << phiMS << " diff: " << phiID - phiMS
104  << " pt ID: " << idTrack.perigeeParameters()->pT() << " pt ms: " << muonpar->pT());
105  ATH_MSG_DEBUG("theta ID: " << thetaID << " theta MS: " << thetaMS << " diff: " << thetaID - thetaMS);
106  double phidiff = std::abs(phiID - phiMS);
107  if (std::abs(phidiff - 2 * M_PI) < phidiff) phidiff = 2 * M_PI - phidiff;
108  if (checkphiflip && std::abs(phidiff - M_PI) < phidiff) phidiff = std::abs(M_PI - phidiff);
109  double thetalimit = .6, philimit = .8;
110  if (muonisstraight) {
111  thetalimit = 1.;
112  philimit = 2;
113  }
114  if (!(std::abs(thetaID - thetaMS) < thetalimit && std::abs(phidiff) < philimit)) return 0;
115 
116  const Trk::TrackParameters *lastmeasidpar = nullptr;
117  int index = (int)idTrack.trackParameters()->size();
118  while (!lastmeasidpar && index > 0) {
119  index--;
120  lastmeasidpar = (*idTrack.trackParameters())[index]->covariance() ? (*idTrack.trackParameters())[index] : nullptr;
121  }
122  if (!lastmeasidpar) {
123  ATH_MSG_WARNING("ID track parameters don't have error matrix!");
124  return 0;
125  }
126 
127  const Trk::TrackParameters *mspar = nullptr;
129 
130  while (tsosit != msTrack.trackStateOnSurfaces()->end() && !mspar) {
131  if ((**tsosit).type(Trk::TrackStateOnSurface::Measurement) && !(**tsosit).type(Trk::TrackStateOnSurface::Outlier)) {
132  mspar = (**tsosit).trackParameters();
133  }
134  ++tsosit;
135  }
136 
137  if (!mspar) {
138  ATH_MSG_WARNING("Could not find muon track parameters!");
139  return 0;
140  }
141 
142  std::unique_ptr<const Trk::TrackParameters> idextrapolatedpar = std::unique_ptr<const Trk::TrackParameters>(
143  m_extrapolator->extrapolateToVolume(ctx, *lastmeasidpar, *msEntrance, Trk::alongMomentum, Trk::muon));
144 
145  if (!idextrapolatedpar && lastmeasidpar->parameters()[Trk::qOverP] != 0 &&
146  std::abs(1. / lastmeasidpar->parameters()[Trk::qOverP]) < 5. * CLHEP::GeV) {
147  ATH_MSG_DEBUG("Extrapolating with p=5 GeV");
148  AmgVector(5) params = lastmeasidpar->parameters();
149  double sign = (params[Trk::qOverP] > 0) ? 1 : -1;
150  double newqoverp = sign / (5. * CLHEP::GeV);
151  params[Trk::qOverP] = newqoverp;
152  std::unique_ptr<const Trk::TrackParameters> newlastidpar = lastmeasidpar->associatedSurface().createUniqueTrackParameters(
153  params[0], params[1], params[2], params[3], params[4], AmgSymMatrix(5)(*lastmeasidpar->covariance()));
154  if (newlastidpar) {
155  idextrapolatedpar = std::unique_ptr<const Trk::TrackParameters>(
156  m_extrapolator->extrapolateToVolume(ctx, *newlastidpar, *msEntrance, Trk::alongMomentum, Trk::muon));
157  }
158  }
159 
160  if (!idextrapolatedpar || !idextrapolatedpar->covariance()) {
161  ATH_MSG_DEBUG("ID extrapolated par null or missing error matrix, par: " << idextrapolatedpar.get());
162  return 0;
163  }
164  const Trk::TrackParameters *msparforextrapolator = mspar;
165  std::unique_ptr<const Trk::TrackParameters> created_mspar;
166  if (muonisstraight) {
167  const AmgSymMatrix(5) &idcovmat = *idextrapolatedpar->covariance();
168  AmgVector(5) params = mspar->parameters();
169  params[Trk::qOverP] = idextrapolatedpar->parameters()[Trk::qOverP];
170  if (!mspar->covariance()) {
171  ATH_MSG_DEBUG("Muons parameters missing Error matrix: " << mspar);
172  return 1e5; // Sometimes it's 0, sometimes 1e15. Maybe for comparison of chi2? Just in case, will copy this
173  // value from earlier check on ms track. EJWM.
174  }
175  AmgSymMatrix(5) newcovmat = AmgSymMatrix(5)(*mspar->covariance());
176  for (int i = 0; i < 5; i++) (newcovmat)(i, 4) = idcovmat(i, 4);
177  created_mspar = msparforextrapolator->associatedSurface().createUniqueTrackParameters(params[0], params[1], params[2],
178  params[3], params[4], newcovmat);
179  msparforextrapolator = created_mspar.get();
180  }
183  msparforextrapolator->position(), msparforextrapolator->momentum().unit());
184  double distance = 0;
185  if (distsol.numberOfSolutions() == 1)
186  distance = distsol.first();
187  else if (distsol.numberOfSolutions() == 2) {
188  distance = (std::abs(distsol.first()) < std::abs(distsol.second())) ? distsol.first() : distsol.second();
189  }
190 
191  if (distance > 0 && distsol.numberOfSolutions() > 0) propdir = Trk::alongMomentum;
192 
193  std::unique_ptr<const Trk::TrackParameters> msextrapolatedpar = std::unique_ptr<const Trk::TrackParameters>(
194  m_extrapolator->extrapolate(ctx, *msparforextrapolator, idextrapolatedpar->associatedSurface(), propdir, false, Trk::muon));
195 
196  if (muonisstraight) { ATH_MSG_DEBUG("Muon track is straight line"); }
197 
198  if ((!msextrapolatedpar && !muonisstraight)) {
199  ATH_MSG_DEBUG("extrapolation failed, id:" << idextrapolatedpar.get() << " ms: " << msextrapolatedpar.get());
200  return 0;
201  }
202  double mychi2 = 1e15;
203  if (msextrapolatedpar) mychi2 = chi2(*idextrapolatedpar, *msextrapolatedpar);
204  if (muonisstraight) {
205  std::unique_ptr<const Trk::TrackParameters> idpar_firsthit = std::unique_ptr<const Trk::TrackParameters>(
206  m_extrapolator->extrapolate(ctx, *idextrapolatedpar, mspar->associatedSurface(), Trk::alongMomentum, false, Trk::muon));
207  if (idpar_firsthit) {
208  double chi2_2 = chi2(*idpar_firsthit, *mspar);
209  if (chi2_2 < mychi2) mychi2 = chi2_2;
210  }
211  }
212  return mychi2;
213  }
214 
215  double MuonTrackTagTestTool::chi2(const Trk::TrackParameters &idextrapolatedpar, const Trk::TrackParameters &msextrapolatedpar) const {
216  double loc1ID = idextrapolatedpar.parameters()[Trk::loc1];
217  double loc2ID = idextrapolatedpar.parameters()[Trk::loc2];
218  double phiID = idextrapolatedpar.parameters()[Trk::phi];
219  double thetaID = idextrapolatedpar.parameters()[Trk::theta];
220 
221  double loc1MS = msextrapolatedpar.parameters()[Trk::loc1];
222  double loc2MS = msextrapolatedpar.parameters()[Trk::loc2];
223  double phiMS = msextrapolatedpar.parameters()[Trk::phi];
224  double thetaMS = msextrapolatedpar.parameters()[Trk::theta];
225 
226  if (!idextrapolatedpar.covariance() || !msextrapolatedpar.covariance()) {
227  ATH_MSG_DEBUG("track parameters don't have error matrix! id: " << idextrapolatedpar.covariance()
228  << " ms: " << msextrapolatedpar.covariance());
229  return 1e15;
230  }
231  const AmgSymMatrix(5) &idcovmat = *idextrapolatedpar.covariance();
232  const AmgSymMatrix(5) &mscovmat = *msextrapolatedpar.covariance();
233 
234  double loc1diff = std::abs(loc1ID - loc1MS);
235  double loc2diff = std::abs(loc2ID - loc2MS);
236  const Trk::CylinderSurface *cylsurf = dynamic_cast<const Trk::CylinderSurface *>(&idextrapolatedpar.associatedSurface());
237  const Trk::DiscSurface *discsurf = dynamic_cast<const Trk::DiscSurface *>(&idextrapolatedpar.associatedSurface());
238 
239  if (cylsurf) {
240  double length = 2 * M_PI * cylsurf->bounds().r();
241  if (std::abs(loc1diff - length) < loc1diff) loc1diff = length - loc1diff;
242  }
243  if (discsurf) {
244  if (std::abs(loc2diff - 2 * M_PI) < loc2diff) loc2diff = 2 * M_PI - loc2diff;
245  }
246  double phidiff = std::abs(phiID - phiMS);
247  if (std::abs(phidiff - 2 * M_PI) < phidiff) phidiff = 2 * M_PI - phidiff;
248  if (std::abs(phidiff - M_PI) < phidiff) phidiff -= M_PI; // catch singularity in phi near theta=0
249 
250  double thetadiff = thetaID - thetaMS;
251 
252  double chi2 = loc1diff * loc1diff / (idcovmat(0, 0) + mscovmat(0, 0)) + loc2diff * loc2diff / (idcovmat(1, 1) + mscovmat(1, 1)) +
253  phidiff * phidiff / (idcovmat(2, 2) + mscovmat(2, 2)) + thetadiff * thetadiff / (idcovmat(3, 3) + mscovmat(3, 3));
254  chi2 = std::abs(chi2);
255 
256  ATH_MSG_DEBUG(" chi2: " << chi2);
257  return chi2;
258  }
259 } // namespace MuonCombined
MuonCombined::MuonTrackTagTestTool::m_extrapolator
ToolHandle< Trk::IExtrapolator > m_extrapolator
Definition: MuonTrackTagTestTool.h:32
MuonCombined::MuonTrackTagTestTool::chi2
double chi2(const Trk::TrackParameters &idParsAtEntry, const Trk::TrackParameters &msParsAtEntry) const override
Definition: MuonTrackTagTestTool.cxx:215
MuonTrackTagTestTool.h
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
StraightLineSurface.h
TrackParameters.h
MeasurementBase.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Trk::DistanceSolution
Definition: DistanceSolution.h:25
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
Trk::oppositeMomentum
@ oppositeMomentum
Definition: PropDirection.h:21
Trk::DistanceSolution::numberOfSolutions
int numberOfSolutions() const
Number of intersection solutions.
index
Definition: index.py:1
Trk::ParametersBase::associatedSurface
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Trk::Surface::straightLineDistanceEstimate
virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D &pos, const Amg::Vector3D &dir) const =0
fast straight line distance evaluation to Surface
Trk::Track::trackStateOnSurfaces
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
M_PI
#define M_PI
Definition: ActiveFraction.h:11
MuonCombined::MuonTrackTagTestTool::initialize
StatusCode initialize() override
Definition: MuonTrackTagTestTool.cxx:38
Trk::loc2
@ loc2
generic first and second local coordinate
Definition: ParamDefs.h:41
Trk::CylinderSurface::bounds
virtual const CylinderBounds & bounds() const override final
This method returns the CylinderBounds by reference (NoBounds is not possible for cylinder)
Trk::alongMomentum
@ alongMomentum
Definition: PropDirection.h:20
Trk::DiscSurface
Definition: DiscSurface.h:54
Trk::DistanceSolution::first
double first() const
Distance to first intersection solution along direction.
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
InDet::TRT_DriftCircleOnTrack
Definition: TRT_DriftCircleOnTrack.h:53
GenParticle.h
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
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::PropDirection
PropDirection
Definition: PropDirection.h:19
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrackTruthCollection.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
Trk::Surface::createUniqueTrackParameters
virtual ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theat, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const =0
Use the Surface as a ParametersBase constructor, from local parameters - charged.
Trk::theta
@ theta
Definition: ParamDefs.h:72
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
Trk::CylinderSurface
Definition: CylinderSurface.h:55
AmgVector
AmgVector(4) T2BSTrackFilterTool
Definition: T2BSTrackFilterTool.cxx:114
Trk::DistanceSolution::second
double second() const
Distance to second intersection solution along direction (for a cylinder surface)
CylinderSurface.h
test_pyathena.parent
parent
Definition: test_pyathena.py:15
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:127
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::ParametersBase
Definition: ParametersBase.h:55
TRT_DriftCircleOnTrack.h
Trk::muon
@ muon
Definition: ParticleHypothesis.h:28
MuonCombined::MuonTrackTagTestTool::m_trackingGeometryReadKey
SG::ReadCondHandleKey< Trk::TrackingGeometry > m_trackingGeometryReadKey
Definition: MuonTrackTagTestTool.h:37
Trk::Track::trackParameters
const DataVector< const TrackParameters > * trackParameters() const
Return a pointer to a vector of TrackParameters.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:97
Trk::Track::perigeeParameters
const Perigee * perigeeParameters() const
return Perigee.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:163
Trk::ParametersBase::pT
double pT() const
Access method for transverse momentum.
TrackTruth.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
MuonCombined::MuonTrackTagTestTool::m_chi2cut
double m_chi2cut
Definition: MuonTrackTagTestTool.h:41
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
Trk::Track::measurementsOnTrack
const DataVector< const MeasurementBase > * measurementsOnTrack() const
return a pointer to a vector of MeasurementBase (NOT including any that come from outliers).
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:178
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
TrackingVolume.h
InDet::PixelClusterOnTrack
Definition: PixelClusterOnTrack.h:51
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
MuonCombined
The MuonTagToSegMap is an auxillary construct that links the MuonSegments associated with a combined ...
Definition: IMuonSystemExtensionTool.h:23
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:73
DiscSurface.h
physics_parameters.parameters
parameters
Definition: physics_parameters.py:144
Trk::phi
@ phi
Definition: ParamDefs.h:81
MuonCombined::MuonTrackTagTestTool::MuonTrackTagTestTool
MuonTrackTagTestTool(const std::string &type, const std::string &name, const IInterface *parent)
Definition: MuonTrackTagTestTool.cxx:29
PowhegControl_ttFCNC_NLO.params
params
Definition: PowhegControl_ttFCNC_NLO.py:226
AthAlgTool
Definition: AthAlgTool.h:26
PixelClusterOnTrack.h
Trk::loc1
@ loc1
Definition: ParamDefs.h:40
Trk::TrackingVolume
Definition: TrackingVolume.h:121
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
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
length
double length(const pvec &v)
Definition: FPGATrackSimLLPDoubletHoughTransformTool.cxx:26
Trk::TrackStateOnSurface::Measurement
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
Definition: TrackStateOnSurface.h:101
Trk::StraightLineSurface
Definition: StraightLineSurface.h:51
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
MuonCombined::MuonTrackTagTestTool::getVolume
const Trk::TrackingVolume * getVolume(const std::string &&vol_name, const EventContext &ctx) const
Definition: MuonTrackTagTestTool.h:45
Trk::CylinderBounds::r
virtual double r() const override final
This method returns the radius.