ATLAS Offline Software
Loading...
Searching...
No Matches
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
15namespace 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 "
58 << scale * m_nbetterPreciseFit);
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
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)
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
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
PublicToolHandle< MuonEDMPrinterTool > m_printer
Gaudi::Property< double > m_lowPtThreshold
virtual std::unique_ptr< Trk::Track > optimiseErrors(Trk::Track &track, const EventContext &ctx) const override
optimise the error strategy used for the track
Gaudi::Property< double > m_chi2NdofCutRefit
virtual StatusCode initialize() override
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
MuonErrorOptimisationTool(const std::string &ty, const std::string &na, const IInterface *pa)
Constructor with parameters:
virtual StatusCode finalize() override
ToolHandle< Trk::ITrackSummaryHelperTool > m_trackSummaryTool
ToolHandle< IMuonRefitTool > m_refitTool
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
Detailed track summary for the muon system Give access to hit counts per chamber.
unsigned int netaHits() const
number of eta hits on the track
unsigned int nphiHits() const
number of phi hits on the track
const Amg::Vector3D & momentum() const
Access method for the momentum.
A summary of the information contained by a track.
const MuonTrackSummary * muonTrackSummary() const
returns a pointer to the MuonTrackSummary if available
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee