ATLAS Offline Software
MuonErrorOptimisationTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include <iostream>
8 
11 #include "TrkTrack/Track.h"
14 
15 namespace Muon {
16 
17  MuonErrorOptimisationTool::MuonErrorOptimisationTool(const std::string& ty, const std::string& na, const IInterface* pa) :
18  AthAlgTool(ty, na, pa) {
19  declareProperty("PrepareForFit", m_refitSettings.prepareForFit = true);
20  declareProperty("RecreateStartingParameters", m_refitSettings.recreateStartingParameters = true);
21  declareProperty("UpdateErrors", m_refitSettings.updateErrors = true);
22  declareProperty("RemoveOutliers", m_refitSettings.removeOutliers = false);
23  declareProperty("RemoveOtherSectors", m_refitSettings.removeOtherSectors = false);
24  declareProperty("RemoveBarrelEndcapOverlap", m_refitSettings.removeBarrelEndcapOverlap = false);
25  declareProperty("RemoveBEE", m_refitSettings.removeBEE = false);
26  declareProperty("DeweightOtherSectors", m_refitSettings.deweightOtherSectors = true);
27 
28  declareInterface<IMuonErrorOptimisationTool>(this);
29  }
30 
32  ATH_MSG_INFO("Initializing MuonErrorOptimisationTool");
33 
34  ATH_CHECK(m_printer.retrieve());
35  ATH_CHECK(m_edmHelperSvc.retrieve());
36  ATH_CHECK(m_trackSummaryTool.retrieve());
37  if (!m_refitTool.empty()) ATH_CHECK(m_refitTool.retrieve());
38 
39  return StatusCode::SUCCESS;
40  }
41 
43  if (m_nrefitAll > 0) {
44  double scale = 1. / m_nrefitAll;
45  double scaleLowPt = m_nrefitAllLowPt > 0 ? 1. / m_nrefitAllLowPt : 1.;
46  ATH_MSG_INFO(" Number of all refits " << m_nrefitAll << " fraction of total calls "
47  << scale * m_nrefitAll);
48  ATH_MSG_INFO(" Number of refits with precise errors " << m_nrefitPrecise << " fraction of total calls "
49  << scale * m_nrefitPrecise);
50  ATH_MSG_INFO(" Number of refits with large errors " << m_nrefit << " fraction of total calls " << scale * m_nrefit);
51  ATH_MSG_INFO(" Number of all refits (low pt) " << m_nrefitAllLowPt << " fraction of total calls "
52  << scaleLowPt * m_nrefitAllLowPt);
53  ATH_MSG_INFO(" Number of refits with precise errors (low pt) " << m_nrefitPreciseLowPt << " fraction of total calls "
54  << scaleLowPt * m_nrefitPreciseLowPt);
55  ATH_MSG_INFO(" Number of refits with large errors (low pt) " << m_nrefitLowPt << " fraction of total calls "
56  << scaleLowPt * m_nrefitLowPt);
57  ATH_MSG_INFO(" Precise refit bad but better than input " << m_nbetterPreciseFit << " fraction of total calls "
59  ATH_MSG_INFO(" Large error refit bad but better than input " << m_nbetterFit << " fraction of total calls "
60  << scale * m_nbetterFit);
61  }
62 
63  return StatusCode::SUCCESS;
64  }
65 
66  std::unique_ptr<Trk::Track> MuonErrorOptimisationTool::optimiseErrors(Trk::Track& track, const EventContext& ctx) const {
67  if (m_refitTool.empty()) return nullptr;
68  const Trk::Perigee* pp = track.perigeeParameters();
69  bool isLowPt = false;
70  if (pp && pp->momentum().mag() < m_lowPtThreshold) isLowPt = true;
71  if (isLowPt)
73  else
74  ++m_nrefitAll;
75 
76  std::unique_ptr<Trk::Track> result1;
77  std::unique_ptr<Trk::Track> result2;
78 
79  // first refit with precise errors
81  settings.broad = false;
82  std::unique_ptr<Trk::Track> refittedTrack = m_refitTool->refit(track, ctx, &settings);
83  if (refittedTrack) {
84  // check whether it is ok
85  if (!m_edmHelperSvc->goodTrack(*refittedTrack, m_chi2NdofCutRefit)) {
86  ATH_MSG_VERBOSE("Precise fit bad " << std::endl
87  << m_printer->print(*refittedTrack) << std::endl
88  << m_printer->printStations(*refittedTrack));
89 
90  // if not delete track
91  result1.swap(refittedTrack);
92  } else {
93  ATH_MSG_VERBOSE("Precise fit ok " << std::endl
94  << m_printer->print(*refittedTrack) << std::endl
95  << m_printer->printStations(*refittedTrack));
96  if (isLowPt)
98  else
100  }
101  } else {
102  ATH_MSG_VERBOSE("Precise fit failed");
103  }
104 
105  // only do second fit if first is not ok
106  if (!refittedTrack) {
107  // second refit track
108  settings.broad = true;
109  refittedTrack = m_refitTool->refit(track, ctx, &settings);
110  if (refittedTrack) {
111  // check whether it is ok
112  if (!m_edmHelperSvc->goodTrack(*refittedTrack, m_chi2NdofCutRefit)) {
113  ATH_MSG_VERBOSE("Loose fit bad " << std::endl
114  << m_printer->print(*refittedTrack) << std::endl
115  << m_printer->printStations(*refittedTrack));
116  // if not delete track
117  result2.swap(refittedTrack);
118  } else {
119  ATH_MSG_VERBOSE("Loose fit ok " << std::endl
120  << m_printer->print(*refittedTrack) << std::endl
121  << m_printer->printStations(*refittedTrack));
122  if (isLowPt)
123  ++m_nrefitLowPt;
124  else
125  ++m_nrefit;
126  ++m_nrefit;
127  }
128  } else {
129  ATH_MSG_VERBOSE("Loose fit failed");
130  }
131  }
132 
133  // if failed to refit or refit returned original track, return 0
134  if (!refittedTrack || *refittedTrack->perigeeParameters() == *track.perigeeParameters()) {
135  // check if any refit succeeded
136  if (!result1 && !result2) return nullptr;
137 
138  // now compare chi2
139  const Trk::FitQuality* fq0 = track.fitQuality();
140  const Trk::FitQuality* fq1 = result1 ? result1->fitQuality() : nullptr;
141  const Trk::FitQuality* fq2 = result2 ? result2->fitQuality() : nullptr;
142 
143  bool doSelection = true;
144 
145  // ensure that each track if present has a fit quality
146  if (!fq0 || (result1 && !fq1) || (result2 && !fq2)) {
147  ATH_MSG_WARNING("track without fit quality after refit");
148  doSelection = false;
149  // chech that ndof didn't change
150  } else if ((fq1 && fq0->numberDoF() != fq1->numberDoF()) || (fq2 && fq0->numberDoF() != fq2->numberDoF())) {
151  doSelection = false;
152  // ugly bit of code to get the hit counts for the three tracks
153  int nhits0 = -1;
154  Trk::TrackSummary* summary0 = track.trackSummary();
155  Trk::MuonTrackSummary* muonSummary0 = nullptr;
156  if (summary0) {
157  if (summary0->muonTrackSummary()) {
158  muonSummary0 = summary0->muonTrackSummary();
159  if (muonSummary0) nhits0 = muonSummary0->netaHits() + muonSummary0->nphiHits();
160  } else {
161  Trk::TrackSummary tmpSum(*summary0);
162  m_trackSummaryTool->addDetailedTrackSummary(track, tmpSum);
163  muonSummary0 = tmpSum.muonTrackSummary();
164  if (muonSummary0) nhits0 = muonSummary0->netaHits() + muonSummary0->nphiHits();
165  }
166  } else {
167  Trk::TrackSummary tmpSummary;
168  m_trackSummaryTool->addDetailedTrackSummary(track, tmpSummary);
169  if (tmpSummary.muonTrackSummary()) muonSummary0 = tmpSummary.muonTrackSummary();
170  if (muonSummary0) nhits0 = muonSummary0->netaHits() + muonSummary0->nphiHits();
171  }
172 
173  int nhits1 = -1;
174  Trk::TrackSummary* summary1 = track.trackSummary();
175  Trk::MuonTrackSummary* muonSummary1 = nullptr;
176  if (summary1) {
177  if (summary1->muonTrackSummary())
178  muonSummary1 = summary1->muonTrackSummary();
179  else {
180  Trk::TrackSummary* tmpSum = summary1;
181  if (tmpSum) m_trackSummaryTool->addDetailedTrackSummary(track, *tmpSum);
182  if (tmpSum->muonTrackSummary()) muonSummary1 = tmpSum->muonTrackSummary();
183  }
184  if (muonSummary1) nhits1 = muonSummary1->netaHits() + muonSummary1->nphiHits();
185  } else {
186  Trk::TrackSummary tmpSummary;
187  m_trackSummaryTool->addDetailedTrackSummary(track, tmpSummary);
188  if (tmpSummary.muonTrackSummary()) muonSummary1 = tmpSummary.muonTrackSummary();
189  if (muonSummary1) nhits1 = muonSummary1->netaHits() + muonSummary1->nphiHits();
190  }
191 
192  int nhits2 = -1;
193  Trk::TrackSummary* summary2 = track.trackSummary();
194  Trk::MuonTrackSummary* muonSummary2 = nullptr;
195  if (summary2) {
196  if (summary2->muonTrackSummary())
197  muonSummary2 = summary2->muonTrackSummary();
198  else {
199  Trk::TrackSummary* tmpSum = summary2;
200  if (tmpSum) m_trackSummaryTool->addDetailedTrackSummary(track, *tmpSum);
201  if (tmpSum->muonTrackSummary()) muonSummary2 = tmpSum->muonTrackSummary();
202  }
203  if (muonSummary2) nhits2 = muonSummary2->netaHits() + muonSummary2->nphiHits();
204  } else {
205  Trk::TrackSummary tmpSummary;
206  m_trackSummaryTool->addDetailedTrackSummary(track, tmpSummary);
207  if (tmpSummary.muonTrackSummary()) muonSummary2 = tmpSummary.muonTrackSummary();
208  if (muonSummary2) nhits2 = muonSummary2->netaHits() + muonSummary2->nphiHits();
209  }
210 
211  if (nhits0 != -1 && nhits1 != -1 && nhits2 != -1) {
212  if (nhits0 == nhits1 && nhits0 == nhits2) doSelection = true;
213  }
214 
215  if (!doSelection) ATH_MSG_WARNING("Ndof changed after refit");
216  }
217 
218  if (doSelection) {
219  // check whether the chi2 after refit is smaller than original even if above threshold. If so use refit
220  bool firstIsBest = true;
221  if (!fq1 && fq2) firstIsBest = false;
222  if (fq1 && fq2) firstIsBest = fq1->chiSquared() < fq2->chiSquared();
223 
224  double chi2Refit = firstIsBest ? fq1->chiSquared() : fq2->chiSquared();
225  if (chi2Refit < fq0->chiSquared()) {
226  if (firstIsBest) {
227  ATH_MSG_DEBUG("Keeping precise refit");
229  return result1;
230  } else {
231  ATH_MSG_DEBUG("Keeping loose refit");
232  ++m_nbetterFit;
233  return result2;
234  }
235  }
236  }
237  return nullptr;
238  }
239  return refittedTrack;
240  }
241 
242 } // namespace Muon
Muon::MuonErrorOptimisationTool::MuonErrorOptimisationTool
MuonErrorOptimisationTool(const std::string &ty, const std::string &na, const IInterface *pa)
Constructor with parameters:
Definition: MuonErrorOptimisationTool.cxx:17
Trk::Track::fitQuality
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
Muon::IMuonRefitTool::Settings::recreateStartingParameters
bool recreateStartingParameters
prepare the input track for a refit
Definition: IMuonRefitTool.h:47
Muon::MuonErrorOptimisationTool::m_nbetterFit
std::atomic_uint m_nbetterFit
Definition: MuonErrorOptimisationTool.h:53
TrackParameters.h
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
MuonTrackSummary.h
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
Muon::IMuonRefitTool::Settings::broad
bool broad
Definition: IMuonRefitTool.h:39
Muon::IMuonRefitTool::Settings::removeBarrelEndcapOverlap
bool removeBarrelEndcapOverlap
all trigger eta hits are turned into outliers
Definition: IMuonRefitTool.h:52
Muon::IMuonRefitTool::Settings
Definition: IMuonRefitTool.h:21
Muon::MuonErrorOptimisationTool::m_edmHelperSvc
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
Definition: MuonErrorOptimisationTool.h:34
Muon::MuonErrorOptimisationTool::m_trackSummaryTool
ToolHandle< Trk::ITrackSummaryHelperTool > m_trackSummaryTool
Definition: MuonErrorOptimisationTool.h:39
Muon::MuonErrorOptimisationTool::m_nbetterPreciseFit
std::atomic_uint m_nbetterPreciseFit
Definition: MuonErrorOptimisationTool.h:52
Muon::IMuonRefitTool::Settings::removeOtherSectors
bool removeOtherSectors
recreate starting parameters by extrapolating from first hit on track
Definition: IMuonRefitTool.h:48
Trk::MuonTrackSummary::netaHits
unsigned int netaHits() const
number of eta hits on the track
Definition: MuonTrackSummary.cxx:18
Muon::MuonErrorOptimisationTool::m_nrefitAllLowPt
std::atomic_uint m_nrefitAllLowPt
Definition: MuonErrorOptimisationTool.h:46
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Muon
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:49
Muon::MuonErrorOptimisationTool::m_nrefitAll
std::atomic_uint m_nrefitAll
Definition: MuonErrorOptimisationTool.h:45
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
Muon::MuonErrorOptimisationTool::m_lowPtThreshold
Gaudi::Property< double > m_lowPtThreshold
Definition: MuonErrorOptimisationTool.h:44
Muon::MuonErrorOptimisationTool::m_nrefitLowPt
std::atomic_uint m_nrefitLowPt
Definition: MuonErrorOptimisationTool.h:49
Track.h
Muon::IMuonRefitTool::Settings::removeOutliers
bool removeOutliers
toogle on/off refit of the track
Definition: IMuonRefitTool.h:41
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
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
Trk::MuonTrackSummary
Detailed track summary for the muon system Give access to hit counts per chamber.
Definition: MuonTrackSummary.h:26
Trk::FitQuality
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition: FitQuality.h:97
TrackSummary.h
Muon::MuonErrorOptimisationTool::optimiseErrors
virtual std::unique_ptr< Trk::Track > optimiseErrors(Trk::Track &track, const EventContext &ctx) const override
optimise the error strategy used for the track
Definition: MuonErrorOptimisationTool.cxx:66
Trk::Track::perigeeParameters
const Perigee * perigeeParameters() const
return Perigee.
Definition: Tracking/TrkEvent/TrkTrack/src/Track.cxx:163
Muon::MuonErrorOptimisationTool::m_nrefitPreciseLowPt
std::atomic_uint m_nrefitPreciseLowPt
Definition: MuonErrorOptimisationTool.h:51
Trk::TrackSummary
A summary of the information contained by a track.
Definition: Tracking/TrkEvent/TrkTrackSummary/TrkTrackSummary/TrackSummary.h:287
Muon::IMuonRefitTool::Settings::prepareForFit
bool prepareForFit
update the errors of the trigger hits
Definition: IMuonRefitTool.h:46
Trk::MuonTrackSummary::nphiHits
unsigned int nphiHits() const
number of phi hits on the track
Definition: MuonTrackSummary.cxx:32
Muon::MuonErrorOptimisationTool::m_refitTool
ToolHandle< IMuonRefitTool > m_refitTool
Definition: MuonErrorOptimisationTool.h:41
IDTPM::chiSquared
float chiSquared(const U &p)
Definition: TrackParametersHelper.h:136
Muon::MuonErrorOptimisationTool::finalize
virtual StatusCode finalize() override
Definition: MuonErrorOptimisationTool.cxx:42
Muon::MuonErrorOptimisationTool::m_nrefitPrecise
std::atomic_uint m_nrefitPrecise
Definition: MuonErrorOptimisationTool.h:50
Muon::MuonErrorOptimisationTool::m_refitSettings
IMuonRefitTool::Settings m_refitSettings
Definition: MuonErrorOptimisationTool.h:55
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Muon::IMuonRefitTool::Settings::updateErrors
bool updateErrors
recalibrate the hits
Definition: IMuonRefitTool.h:44
Muon::MuonErrorOptimisationTool::initialize
virtual StatusCode initialize() override
Definition: MuonErrorOptimisationTool.cxx:31
Muon::IMuonRefitTool::Settings::removeBEE
bool removeBEE
turn all hits in the barrel/endcap part of the track with least hits into outliers
Definition: IMuonRefitTool.h:53
Trk::FitQuality::chiSquared
double chiSquared() const
returns the of the overall track fit
Definition: FitQuality.h:56
Trk::FitQuality::numberDoF
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition: FitQuality.h:60
xAOD::track
@ track
Definition: TrackingPrimitives.h:512
AthAlgTool
Definition: AthAlgTool.h:26
Muon::MuonErrorOptimisationTool::m_chi2NdofCutRefit
Gaudi::Property< double > m_chi2NdofCutRefit
Definition: MuonErrorOptimisationTool.h:43
Trk::TrackSummary::muonTrackSummary
const MuonTrackSummary * muonTrackSummary() const
returns a pointer to the MuonTrackSummary if available
FitQuality.h
Muon::MuonErrorOptimisationTool::m_printer
PublicToolHandle< MuonEDMPrinterTool > m_printer
Definition: MuonErrorOptimisationTool.h:37
Muon::IMuonRefitTool::Settings::deweightOtherSectors
bool deweightOtherSectors
remove all hits in sectors that are not the main sector
Definition: IMuonRefitTool.h:49
Muon::MuonErrorOptimisationTool::m_nrefit
std::atomic_uint m_nrefit
Definition: MuonErrorOptimisationTool.h:48
MuonErrorOptimisationTool.h