ATLAS Offline Software
Loading...
Searching...
No Matches
Muon::TimePointBetaFitter Class Reference

#include <TimePointBetaFitter.h>

Collaboration diagram for Muon::TimePointBetaFitter:

Classes

struct  FitResult
 simple struct holding the fit result More...
struct  Hit
 simple struct holding the input to the fit More...

Public Types

typedef std::vector< HitHitVec

Public Member Functions

 TimePointBetaFitter ()
 constructor
FitResult fitWithOutlierLogic (HitVec &hits) const
 fit beta with outlier logic

Static Public Member Functions

static FitResult fit (HitVec &hits)
 fit beta

Detailed Description

Definition at line 15 of file TimePointBetaFitter.h.

Member Typedef Documentation

◆ HitVec

typedef std::vector<Hit> Muon::TimePointBetaFitter::HitVec

Definition at line 30 of file TimePointBetaFitter.h.

Constructor & Destructor Documentation

◆ TimePointBetaFitter()

Muon::TimePointBetaFitter::TimePointBetaFitter ( )
inline

constructor

Definition at line 49 of file TimePointBetaFitter.h.

49{}

Member Function Documentation

◆ fit()

TimePointBetaFitter::FitResult Muon::TimePointBetaFitter::fit ( TimePointBetaFitter::HitVec & hits)
static

fit beta

Formula chi2 = sum( t_meas-t_pred)^2/sigma_meas^2 ) t_pred = dist / v = dist / ( beta*c )

minimize chi2 -> d chi2 / d beta = 0

beta = sum( ( d^2/( c * sigma_meas^2 ) ) )/ sum( (d*t_meas)/( sigma_meas^2 ) )

Definition at line 12 of file TimePointBetaFitter.cxx.

12 {
13
22
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
77 FitResult result(1,beta,chi2,ndof);
78 if (log.level()<=MSG::VERBOSE) log << "beta " << beta << " chi2 " << chi2 << " ndof " << ndof << " chi2/ndof " << result.chi2PerDOF() << endmsg;
79 return result;
80 }
#define endmsg
std::pair< std::vector< unsigned int >, bool > res
static Double_t a
static constexpr double const & invSpeedOfLight
double chi2(TH1 *h0, TH1 *h1)
IMessageSvc * getMessageSvc(bool quiet=false)
float ndof(const U &p)
simple struct holding the fit result

◆ fitWithOutlierLogic()

TimePointBetaFitter::FitResult Muon::TimePointBetaFitter::fitWithOutlierLogic ( TimePointBetaFitter::HitVec & hits) const

fit beta with outlier logic

Definition at line 83 of file TimePointBetaFitter.cxx.

83 {
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
88 TimePointBetaFitter::FitResult result = fit( hits );
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 }
FitResult fitWithOutlierLogic(HitVec &hits) const
fit beta with outlier logic
static FitResult fit(HitVec &hits)
fit beta

The documentation for this class was generated from the following files: