ATLAS Offline Software
TimePointBetaFitter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 #include "GaudiKernel/MsgStream.h"
9 
10 namespace Muon {
11 
13 
23  // we need at least one hit
24  if( hits.empty() ) return {};
25 
26  MsgStream log(Athena::getMessageSvc(),"TimePointBetaFitter");
27  if (log.level()<=MSG::VERBOSE) log << MSG::VERBOSE << "Performing fit, hits " << hits.size() << endmsg;
28 
29  // loop over hits and calculate beta
30  float sum1 = 0.;
31  float sum2 = 0.;
32  float maxInvBeta = 5; // cut at a beta of 0.2
33  float pullCut = 2.5;
34  for( HitVec::iterator it=hits.begin(); it!=hits.end(); ++it ){
35  float a = it->distance*invSpeedOfLight;
36  float invBeta = it->time/a;
37  float invBetaError = it->error/a;
38  if (log.level()<=MSG::VERBOSE) {
39  const char* text = it->useInFit ? " hit " : " outlier ";
40  float beta = it->distance*invSpeedOfLight/it->time;
41  float dbeta = it->distance*invSpeedOfLight/(it->time*it->time)*it->error;
42  log << MSG::VERBOSE << text << ", d " << it->distance << " tof " << it->distance*invSpeedOfLight << " time " << it->time
43  << " error " << it->error << " beta " << beta << " error " << dbeta
44  << " 1./beta " << invBeta << " error " << invBetaError << " use " << it->useInFit << endmsg;
45  }
46  if( it->useInFit && (invBeta - pullCut*invBetaError > maxInvBeta || invBeta + pullCut*invBetaError < 1) ) {
47  if (log.level()<=MSG::VERBOSE) log << "Removing hit outside beta range " << endmsg;
48  it->useInFit = false;
49  }
50  if( !it->useInFit ) continue;
51  sum1 += it->distance*it->distance*invSpeedOfLight*it->weight2;
52  sum2 += it->distance*it->time*it->weight2;
53  }
54  // check if sum2 is none zero
55  if( sum2 == 0 ) return {};
56 
57  // calculate beta and chi2
58  float beta = sum1/sum2;
59  float invBeta = 1./beta;
60  if (log.level()<=MSG::VERBOSE) log << "beta " << beta << " sum1 " << sum1 << " sum2 " << sum2 << endmsg;
61 
62  float chi2 = 0;
63  int ndof = 0;
64  for( HitVec::iterator it=hits.begin(); it!=hits.end(); ++it ){
65  float res = it->time - it->distance*invSpeedOfLight*invBeta;
66  it->residual = res;
67  if (log.level()<=MSG::VERBOSE) {
68  const char* text = it->useInFit ? " hit " : " outlier ";
69  log << text << "residual " << res << " pull " << res/it->error << " chi2 " << res*res*it->weight2 << endmsg;
70  }
71  if( !it->useInFit ) continue;
72  ++ndof;
73  chi2 += res*res*it->weight2;
74  }
75  if( ndof == 0 ) return {};
76 
78  if (log.level()<=MSG::VERBOSE) log << "beta " << beta << " chi2 " << chi2 << " ndof " << ndof << " chi2/ndof " << result.chi2PerDOF() << endmsg;
79  return result;
80  }
81 
82 
84  MsgStream log(Athena::getMessageSvc(),"TimePointBetaFitter");
85  if (log.level()<=MSG::VERBOSE) log << "Performing fit with outlier logic, hits " << hits.size() << endmsg;
86 
87  // initial fit, stop if it fails
89 
90  // return result if the fit failed, there were less than three hits or we are happy with the chi2
91  if( result.status == 0 || hits.size() < 3 || result.chi2PerDOF() < 5 ) {
92  if (log.level()<=MSG::VERBOSE) log << "no outlier logic applied: hits " << hits.size()
93  << " chi2/ndof " << result.chi2PerDOF() << endmsg;
94  return result;
95  }
96  // if we get here, run the outlier logic
97  // strategy: refit all combinations removing one of the hits, select the combination with the best chi2
98 
99  int worstHit = -1;
100  float bestChi2Ndof = result.chi2PerDOF();
101  for( unsigned int i=0;i<hits.size();++i ){
102 
103  // skip hits that are already flagged as outlier
104  if( !hits[i].useInFit ) continue;
105 
106  // flag hit so it is not used in fit
107  hits[i].useInFit = false;
108  // fit and select if fit is ok and better that the best
109  TimePointBetaFitter::FitResult resultNew = fit( hits );
110  if( resultNew.status != 0 ){
111  float chi2Ndof = resultNew.chi2PerDOF();
112  if( chi2Ndof < bestChi2Ndof ){
113  bestChi2Ndof = chi2Ndof;
114  worstHit = i;
115  }
116  }
117  // add back hit unless it is really bad
118  hits[i].useInFit = true;
119  }
120 
121  // if we didn't find an improvement return the initial result
122  if( worstHit == -1 ) {
123  if (log.level()<=MSG::VERBOSE) log << "unable to improve result, keep initial result " << endmsg;
124  return result;
125  }
126  // now refit once more removing the worst hit and return the result so the residuals are calculated correctly
127  hits[worstHit].useInFit = false;
128  if (log.level()<=MSG::VERBOSE) log << "removed hit " << worstHit << " new chi2 " << bestChi2Ndof << endmsg;
129  return fitWithOutlierLogic( hits );
130  }
131 
132 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
IDTPM::ndof
float ndof(const U &p)
Definition: TrackParametersHelper.h:134
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
get_generator_info.result
result
Definition: get_generator_info.py:21
getMessageSvc.h
singleton-like access to IMessageSvc via open function and helper
skel.it
it
Definition: skel.GENtoEVGEN.py:396
Muon::TimePointBetaFitter::fitWithOutlierLogic
FitResult fitWithOutlierLogic(HitVec &hits) const
fit beta with outlier logic
Definition: TimePointBetaFitter.cxx:83
Muon::TimePointBetaFitter::FitResult::chi2PerDOF
float chi2PerDOF() const
chi2/ndof, return 0 if ndof == 0 or status == 0
Definition: TimePointBetaFitter.h:39
Muon
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
Definition: TrackSystemController.h:45
Athena::getMessageSvc
IMessageSvc * getMessageSvc(bool quiet=false)
Definition: getMessageSvc.cxx:20
Muon::TimePointBetaFitter::FitResult
simple struct holding the fit result
Definition: TimePointBetaFitter.h:33
lumiFormat.i
int i
Definition: lumiFormat.py:85
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
res
std::pair< std::vector< unsigned int >, bool > res
Definition: JetGroupProductTest.cxx:14
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:523
Muon::TimePointBetaFitter::fit
static FitResult fit(HitVec &hits)
fit beta
Definition: TimePointBetaFitter.cxx:12
a
TList * a
Definition: liststreamerinfos.cxx:10
Muon::TimePointBetaFitter::HitVec
std::vector< Hit > HitVec
Definition: TimePointBetaFitter.h:30
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
makeTransCanvas.text
text
Definition: makeTransCanvas.py:11
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:14
MuonParameters::beta
@ beta
Definition: MuonParamDefs.h:144
TimePointBetaFitter.h
Muon::TimePointBetaFitter::FitResult::status
int status
data members
Definition: TimePointBetaFitter.h:42