ATLAS Offline Software
MuonMatchQuality.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 // get quality of combined track match
8 
9 #include "MuonMatchQuality.h"
10 
11 #include <cmath>
12 #include <iomanip>
13 #include <memory>
14 
15 #include "CLHEP/GenericFunctions/CumulativeChiSquare.hh"
17 #include "TrkTrack/Track.h"
18 namespace Rec {
19 
20  MuonMatchQuality::MuonMatchQuality(const std::string& type, const std::string& name, const IInterface* parent) :
21  AthAlgTool(type, name, parent), m_alignmentUncertainty(nullptr) {
22  declareInterface<IMuonMatchQuality>(this);
23  }
24 
26  ATH_MSG_DEBUG("MuonMatchQuality::initialize().");
27 
28  // get the tools
29  if (!m_tagTool.name().empty()) { ATH_CHECK(m_tagTool.retrieve()); }
30  ATH_CHECK(m_trackQuery.retrieve());
31 
32  // set up alignment uncertainty between ID and MS tracking systems
33  m_alignmentUncertainty = std::make_unique<AmgSymMatrix(5)>();
34  m_alignmentUncertainty->setZero();
35  (*m_alignmentUncertainty)(0, 0) = m_positionUncertainty * m_positionUncertainty;
36  (*m_alignmentUncertainty)(1, 1) = m_positionUncertainty * m_positionUncertainty;
37  (*m_alignmentUncertainty)(2, 2) = m_directionUncertainty * m_directionUncertainty;
38  (*m_alignmentUncertainty)(3, 3) = m_directionUncertainty * m_directionUncertainty;
39 
40  return StatusCode::SUCCESS;
41  }
45  double MuonMatchQuality::innerMatchChi2(const Trk::Track& track1, const Trk::Track& track2, const EventContext& ctx) const {
46  MuonMatchQuality::CacheAll CA = setCache(track1, track2, ctx);
47  return CA.innerMatchChi2;
48  }
49 
51  int MuonMatchQuality::innerMatchDOF(const Trk::Track& track1, const Trk::Track& track2) const {
52  int matchDOF = 0;
53 
54  const Trk::Perigee* perigee1 = track1.perigeeParameters();
55  const Trk::Perigee* perigee2 = track2.perigeeParameters();
56 
57  if (perigee1 && perigee2 && (*perigee1).associatedSurface().center() == (*perigee2).associatedSurface().center()) {
58  if (m_trackQuery->isLineFit(track1) || m_trackQuery->isLineFit(track2)) {
59  matchDOF = 4;
60  } else {
61  matchDOF = 5;
62  }
63  }
64 
65  return matchDOF;
66  }
67  double MuonMatchQuality::innerMatchProbability(const Trk::Track& track1, const Trk::Track& track2, const EventContext& ctx) const {
68  MuonMatchQuality::CacheAll CA = setCache(track1, track2, ctx);
69  return CA.innerMatchProbability;
70  }
71 
72  std::pair<int, std::pair<double, double> > MuonMatchQuality::innerMatchAll(const Trk::Track& track1, const Trk::Track& track2,
73  const EventContext& ctx) const {
74  MuonMatchQuality::CacheAll CA = setCache(track1, track2, ctx);
75 
76  std::pair<int, std::pair<double, double> > aTriad =
77  std::make_pair(CA.innerMatchDOF, std::make_pair(CA.innerMatchChi2, CA.innerMatchProbability));
78 
79  return aTriad;
80  }
81  double MuonMatchQuality::outerMatchChi2(const Trk::Track& track1, const Trk::Track& track2, const EventContext& ctx) const {
82  // caching needs some development...
83  // setCache(track1,track2);
84  double outerMatchChi2 = 999999.;
85  if (!m_tagTool.empty()) { outerMatchChi2 = m_tagTool->chi2(track1, track2, ctx); }
86 
87  return outerMatchChi2;
88  }
89 
91  int MuonMatchQuality::outerMatchDOF(const Trk::Track& /*track1*/, const Trk::Track& /*track2*/) const { return 4; }
92  double MuonMatchQuality::outerMatchProbability(const Trk::Track& track1, const Trk::Track& track2, const EventContext& ctx) const {
93  double outerMatchProbability = 0.;
94  if (!m_tagTool.empty()) {
95  double outer_chi2 = outerMatchChi2(track1, track2, ctx);
96 
97  // probability of MS chi2
98  if (outer_chi2 > 0. && outer_chi2 < 1000.) {
99  Genfun::CumulativeChiSquare func(4);
100  outerMatchProbability = 1. - func(outer_chi2);
101  }
102  }
103  return outerMatchProbability;
104  }
105 
107  bool MuonMatchQuality::shareOrigin(const Trk::Track& track1, const Trk::Track& track2) const {
108  const Trk::Perigee* perigee1 = track1.perigeeParameters();
109  const Trk::Perigee* perigee2 = track2.perigeeParameters();
110 
111  return perigee1 && perigee2 && (*perigee1).associatedSurface().center() == (*perigee2).associatedSurface().center();
112  }
113  double MuonMatchQuality::simpleChi2(const Trk::Track& track1, const Trk::Track& track2, const EventContext& ctx) const {
114  MuonMatchQuality::CacheAll CA = setCache(track1, track2, ctx);
115  return CA.simpleChi2;
116  }
117 
118  /* private method to fill cache */
120  const EventContext& ctx) const {
122  // set match degrees of freedom
123  CA.innerMatchDOF = innerMatchDOF(track1, track2);
124  if (!CA.innerMatchDOF) return CA;
125 
126  // parameter difference
127  const Trk::Perigee* perigee1 = track1.perigeeParameters();
128  const Trk::Perigee* perigee2 = track2.perigeeParameters();
129 
130  // coverity false positive (as null pointers cause innerMatchDOF failure)
131  if (!perigee1 || !perigee2) return CA;
132 
133  double deltaD0 = perigee1->parameters()[Trk::d0] - perigee2->parameters()[Trk::d0];
134  double deltaZ0 = perigee1->parameters()[Trk::z0] - perigee2->parameters()[Trk::z0];
135  double deltaPhi0 = xAOD::P4Helpers::deltaPhi(perigee1->parameters()[Trk::phi0], perigee2->parameters()[Trk::phi0]);
136  double deltaTheta = perigee1->parameters()[Trk::theta] - perigee2->parameters()[Trk::theta];
137  double deltaQoverP = perigee1->parameters()[Trk::qOverP] - perigee2->parameters()[Trk::qOverP];
138 
139  // weight matrix for differences
140  const AmgSymMatrix(5)* cov1 = perigee1->covariance();
141  const AmgSymMatrix(5)* cov2 = perigee2->covariance();
142 
143  AmgSymMatrix(5) covariance;
144  covariance.setZero();
145 
146  if (m_trackQuery->isCombined(track1, ctx)) {
147  // FIXME: should take weighted difference etc -
148  // but this is anyway unreliable due to rounding errors
149  ATH_MSG_WARNING("track1 isCombined: results unreliable ");
150  } else if (m_trackQuery->isCombined(track2, ctx)) {
151  // FIXME: weighted difference etc
152  ATH_MSG_WARNING("track2 isCombined: results unreliable ");
153  }
154 
155  covariance = *cov1 + *cov2 + *m_alignmentUncertainty;
156  if (CA.innerMatchDOF < 5) {
157  deltaQoverP = 0.;
158  for (int i = 0; i != Trk::qOverP; ++i) {
159  covariance(i, Trk::qOverP) = covariance(Trk::qOverP, i) = 0.;
160  }
161  covariance(Trk::qOverP, Trk::qOverP) = 1.;
162  } else {
163  deltaQoverP /= Units::TeV;
164  for (int i = 0; i != Trk::qOverP; ++i) {
165  covariance(i, Trk::qOverP) /= Units::TeV;
166  covariance(Trk::qOverP, i) /= Units::TeV;
167  }
168  covariance(Trk::qOverP, Trk::qOverP) /= (Units::TeV * Units::TeV);
169  }
170 
171  // invert summed covariance
172  AmgMatrix(5, 5) weight = covariance.inverse().eval();
173 
174  AmgMatrix(5, 1) paramDifference;
175  paramDifference.setZero();
176  paramDifference(Trk::d0, 0) = deltaD0;
177  paramDifference(Trk::z0, 0) = deltaZ0;
178  paramDifference(Trk::phi0, 0) = deltaPhi0;
179  paramDifference(Trk::theta, 0) = deltaTheta;
180  paramDifference(Trk::qOverP, 0) = deltaQoverP;
181 
182  double matchChi2 = paramDifference.dot(weight * paramDifference);
183  CA.innerMatchChi2 = matchChi2;
184 
185  // probability of chi2
186  if (CA.innerMatchChi2 >= 0. && CA.innerMatchChi2 < 1000.) {
187  CA.innerMatchProbability = 1. - Genfun::CumulativeChiSquare(CA.innerMatchDOF)(CA.innerMatchChi2);
188  }
189 
190  // Protect against zero division
191  bool nonzerocov = true;
192  for (int k = 0; k < covariance.cols(); k++) {
193  if (covariance(k, k) == 0) nonzerocov = false;
194  }
195 
196  if (nonzerocov) {
197  // simple chi2 as sometimes correlations overestimated
198  CA.simpleChi2 = deltaD0 * deltaD0 / covariance(Trk::d0, Trk::d0) + deltaZ0 * deltaZ0 / covariance(Trk::z0, Trk::z0) +
199  deltaPhi0 * deltaPhi0 / covariance(Trk::phi0, Trk::phi0) +
200  deltaTheta * deltaTheta / covariance(Trk::theta, Trk::theta) +
201  deltaQoverP * deltaQoverP / covariance(Trk::qOverP, Trk::qOverP);
202 
203  if (CA.simpleChi2 + 5. < CA.innerMatchChi2) {
204  ATH_MSG_DEBUG("problem with matchChi2 " << CA.innerMatchChi2 << ", simpleChi2 " << CA.simpleChi2);
205  }
206  } else {
207  ATH_MSG_WARNING("Could not compute simpleChi2. Covariance matrix contains zeros");
208  }
209 
210  ATH_MSG_VERBOSE(std::setiosflags(std::ios::fixed)
211  << "matchDOF" << std::setw(2) << CA.innerMatchDOF << " matchChi2:" << std::setw(6) << std::setprecision(1)
212  << CA.innerMatchChi2 << " simpleChi2:" << std::setw(6) << std::setprecision(1) << CA.simpleChi2 << " pullD0 "
213  << std::setw(5) << std::setprecision(1) << deltaD0 / std::sqrt(covariance(0, 0)) << " pullZ0 " << std::setw(5)
214  << std::setprecision(1) << deltaZ0 / std::sqrt(covariance(1, 1)) << " pullPhi0 " << std::setw(5)
215  << std::setprecision(1) << deltaPhi0 / std::sqrt(covariance(2, 2)) << " pullTheta " << std::setw(5)
216  << std::setprecision(1) << deltaTheta / std::sqrt(covariance(3, 3)) << " pullQoverP " << std::setw(5)
217  << std::setprecision(1) << deltaQoverP / std::sqrt(covariance(4, 4)));
218 
219  return CA;
220  }
221 
222 } // namespace Rec
Rec::MuonMatchQuality::innerMatchDOF
int innerMatchDOF(const Trk::Track &track1, const Trk::Track &track2) const override
IMuonMatchQuality interface: degrees of freedom for chi2 match at IP.
Definition: MuonMatchQuality.cxx:51
Rec::MuonMatchQuality::initialize
StatusCode initialize() override
Definition: MuonMatchQuality.cxx:25
xAOD::EgammaParameters::deltaPhi0
@ deltaPhi0
difference between the cluster phi (presampler) and the eta of the track extrapolated to the presampl...
Definition: EgammaEnums.h:193
Rec::MuonMatchQuality::MuonMatchQuality
MuonMatchQuality(const std::string &type, const std::string &name, const IInterface *parent)
Definition: MuonMatchQuality.cxx:20
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
xAODP4Helpers.h
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
Trk::z0
@ z0
Definition: ParamDefs.h:70
xAOD::P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: xAODP4Helpers.h:69
python.SystemOfUnits.TeV
int TeV
Definition: SystemOfUnits.py:158
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Rec::MuonMatchQuality::m_positionUncertainty
Gaudi::Property< double > m_positionUncertainty
Definition: MuonMatchQuality.h:104
Rec::MuonMatchQuality::innerMatchProbability
double innerMatchProbability(const Trk::Track &track1, const Trk::Track &track2, const EventContext &ctx) const override
IMuonMatchQuality interface: match probability for chi2 match at IP.
Definition: MuonMatchQuality.cxx:67
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
AmgMatrix
#define AmgMatrix(rows, cols)
Definition: EventPrimitives.h:51
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
Track.h
Rec::MuonMatchQuality::setCache
CacheAll setCache(const Trk::Track &track1, const Trk::Track &track2, const EventContext &ctx) const
Definition: MuonMatchQuality.cxx:119
Rec::MuonMatchQuality::outerMatchChi2
double outerMatchChi2(const Trk::Track &track1, const Trk::Track &track2, const EventContext &ctx) const override
IMuonMatchQuality interface: match chiSquared between two tracks expressed at first muon spectrometer...
Definition: MuonMatchQuality.cxx:81
Rec::MuonMatchQuality::m_tagTool
ToolHandle< MuonCombined::IMuonTrackTagTool > m_tagTool
Definition: MuonMatchQuality.h:82
Trk::ParametersT::associatedSurface
virtual const S & associatedSurface() const override final
Access to the Surface method.
lumiFormat.i
int i
Definition: lumiFormat.py:92
Rec
Name: MuonSpContainer.h Package : offline/Reconstruction/MuonIdentification/muonEvent.
Definition: FakeTrackBuilder.h:10
Rec::MuonMatchQuality::outerMatchDOF
virtual int outerMatchDOF(const Trk::Track &track1, const Trk::Track &track2) const override
IMuonMatchQuality interface: degrees of freedom for chi2 match at first MS hit.
Definition: MuonMatchQuality.cxx:91
MuonMatchQuality.h
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
test_pyathena.parent
parent
Definition: test_pyathena.py:15
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
athena.CA
CA
Definition: athena.py:98
Rec::MuonMatchQuality::shareOrigin
virtual bool shareOrigin(const Trk::Track &track1, const Trk::Track &track2) const override
IMuonMatchQuality interface: check the track perigee parameters are expressed at the same surface.
Definition: MuonMatchQuality.cxx:107
Rec::MuonMatchQuality::m_alignmentUncertainty
std::unique_ptr< AmgSymMatrix(5)> m_alignmentUncertainty
Definition: MuonMatchQuality.h:97
Trk::Track::perigeeParameters
const Perigee * perigeeParameters() const
return Perigee.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:163
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
Trk::d0
@ d0
Definition: ParamDefs.h:69
Rec::MuonMatchQuality::m_trackQuery
ToolHandle< IMuonTrackQuery > m_trackQuery
Definition: MuonMatchQuality.h:89
Rec::MuonMatchQuality::CacheAll
Definition: MuonMatchQuality.h:72
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:73
Rec::MuonMatchQuality::outerMatchProbability
double outerMatchProbability(const Trk::Track &track1, const Trk::Track &track2, const EventContext &ctx) const override
IMuonMatchQuality interface: match probability for chi2 match at first MS hit.
Definition: MuonMatchQuality.cxx:92
Rec::MuonMatchQuality::innerMatchChi2
double innerMatchChi2(const Trk::Track &track1, const Trk::Track &track2, const EventContext &ctx) const override
IMuonMatchQuality interface: match chiSquared between two tracks expressed at same inner (IP) surface...
Definition: MuonMatchQuality.cxx:45
AthAlgTool
Definition: AthAlgTool.h:26
Rec::MuonMatchQuality::simpleChi2
double simpleChi2(const Trk::Track &track1, const Trk::Track &track2, const EventContext &ctx) const override
IMuonMatchQuality interface: as inner match chiSquared but simplified to just use diagonal errors.
Definition: MuonMatchQuality.cxx:113
Trk::phi0
@ phi0
Definition: ParamDefs.h:71
Rec::MuonMatchQuality::m_directionUncertainty
Gaudi::Property< double > m_directionUncertainty
Definition: MuonMatchQuality.h:98
Rec::MuonMatchQuality::innerMatchAll
std::pair< int, std::pair< double, double > > innerMatchAll(const Trk::Track &track1, const Trk::Track &track2, const EventContext &ctx) const override
IMuonMatchQuality interface: degrees of freedom, chi2, probability for chi2 match at IP.
Definition: MuonMatchQuality.cxx:72
fitman.k
k
Definition: fitman.py:528