SND@LHC Software
Loading...
Searching...
No Matches
genfit::DAF Class Reference

Determinstic Annealing Filter (DAF) implementation. More...

#include <DAF.h>

Inheritance diagram for genfit::DAF:
Collaboration diagram for genfit::DAF:

Public Member Functions

 DAF (bool useRefKalman=true, double deltaWeight=1e-3, double deltaPval=1e-3)
 Create DAF. Per default, use KalmanFitterRefTrack as fitter.
 
 DAF (AbsKalmanFitter *kalman, double deltaWeight=1e-3, double deltaPval=1e-3)
 Create DAF. Use the provided AbsKalmanFitter as fitter.
 
 ~DAF ()
 
void processTrackWithRep (Track *tr, const AbsTrackRep *rep, bool resortHits=false)
 Process a track using the DAF.
 
void setProbCut (const double prob_cut)
 Set the probability cut for the weight calculation for the hits.
 
void addProbCut (const double prob_cut, const int measDim)
 Set the probability cut for the weight calculation for the hits for a specific measurement dimensionality.
 
void setBetas (double b1, double b2=-1, double b3=-1., double b4=-1., double b5=-1., double b6=-1., double b7=-1., double b8=-1., double b9=-1., double b10=-1.)
 Configure the annealing scheme.
 
void setAnnealingScheme (double bStart, double bFinal, unsigned int nSteps)
 Configure the annealing scheme.
 
void setMaxIterations (unsigned int n)
 Set the maximum number of iterations.
 
void setConvergenceDeltaWeight (double delta)
 If all weights change less than delta between two iterations, the fit is regarded as converged.
 
AbsKalmanFittergetKalman () const
 
virtual void setMaxFailedHits (int val)
 
virtual void setDebugLvl (unsigned int lvl=1)
 
- Public Member Functions inherited from genfit::AbsKalmanFitter
 AbsKalmanFitter (unsigned int maxIterations=4, double deltaPval=1e-3, double blowUpFactor=1e3)
 
virtual ~AbsKalmanFitter ()
 
void getChiSquNdf (const Track *tr, const AbsTrackRep *rep, double &bChi2, double &fChi2, double &bNdf, double &fNdf) const
 
double getChiSqu (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
double getNdf (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
double getRedChiSqu (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
double getPVal (const Track *tr, const AbsTrackRep *rep, int direction=-1) const
 
eMultipleMeasurementHandling getMultipleMeasurementHandling () const
 
virtual void setMinIterations (unsigned int n)
 Set the minimum number of iterations.
 
void setDeltaPval (double deltaPval)
 Set Convergence criterion.
 
void setRelChi2Change (double relChi2Change)
 
void setMultipleMeasurementHandling (eMultipleMeasurementHandling mmh)
 How should multiple measurements be handled?
 
bool isTrackPrepared (const Track *tr, const AbsTrackRep *rep) const
 
bool isTrackFitted (const Track *tr, const AbsTrackRep *rep) const
 
bool canIgnoreWeights () const
 returns if the fitter can ignore the weights and handle the MeasurementOnPlanes as if they had weight 1.
 
- Public Member Functions inherited from genfit::AbsFitter
 AbsFitter ()
 
virtual ~AbsFitter ()
 
void processTrack (Track *, bool resortHits=true)
 

Private Member Functions

 DAF (const DAF &)
 
DAFoperator= (genfit::DAF const &)
 
bool calcWeights (Track *trk, const AbsTrackRep *rep, double beta)
 Calculate and set the weights for the next fitting pass. Return if convergence is met. The convergence criterium is the largest absolute change of all weights.
 

Private Attributes

double deltaWeight_
 
std::vector< double > betas_
 
std::map< int, double > chi2Cuts_
 
boost::scoped_ptr< AbsKalmanFitterkalman_
 

Additional Inherited Members

- Protected Member Functions inherited from genfit::AbsKalmanFitter
const std::vector< MeasurementOnPlane * > getMeasurements (const KalmanFitterInfo *fi, const TrackPoint *tp, int direction) const
 get the measurementsOnPlane taking the multipleMeasurementHandling_ into account
 
- Protected Attributes inherited from genfit::AbsKalmanFitter
unsigned int minIterations_
 Minimum number of iterations to attempt. Forward and backward are counted as one iteration.
 
unsigned int maxIterations_
 Maximum number of iterations to attempt. Forward and backward are counted as one iteration.
 
double deltaPval_
 Convergence criterion.
 
double relChi2Change_
 
double blowUpFactor_
 Blow up the covariance of the forward (backward) fit by this factor before seeding the backward (forward) fit.
 
eMultipleMeasurementHandling multipleMeasurementHandling_
 How to handle if there are multiple MeasurementsOnPlane.
 
int maxFailedHits_
 
- Protected Attributes inherited from genfit::AbsFitter
unsigned int debugLvl_
 

Detailed Description

Determinstic Annealing Filter (DAF) implementation.

Author
Christian Höppner (Technische Universität München, original author)
Karl Bicker (Technische Universität München)

The DAF is an iterative Kalman filter with annealing. It is capable of fitting tracks which are contaminated with noise hits. The algorithm is taken from the references R. Fruehwirth & A. Strandlie, Computer Physics Communications 120 (1999) 197-214 and CERN thesis: Dissertation by Matthias Winkler.

The weights which were assigned to the hits by the DAF are accessible in the MeasurementOnPlane objects in the KalmanFitterInfo objects.

Definition at line 48 of file DAF.h.

Constructor & Destructor Documentation

◆ DAF() [1/3]

genfit::DAF::DAF ( const DAF )
private

◆ DAF() [2/3]

genfit::DAF::DAF ( bool  useRefKalman = true,
double  deltaWeight = 1e-3,
double  deltaPval = 1e-3 
)

Create DAF. Per default, use KalmanFitterRefTrack as fitter.

Parameters
useRefKalmanIf false, use KalmanFitter as fitter.

Definition at line 42 of file DAF.cc.

43 : AbsKalmanFitter(10, deltaPval), deltaWeight_(deltaWeight)
44{
45 if (useRefKalman) {
46 kalman_.reset(new KalmanFitterRefTrack());
47 static_cast<KalmanFitterRefTrack*>(kalman_.get())->setRefitAll();
48 }
49 else
50 kalman_.reset(new KalmanFitter());
51
52 kalman_->setMultipleMeasurementHandling(weightedAverage);
53 kalman_->setMaxIterations(1);
54
55 setAnnealingScheme(100, 0.1, 5); // also sets maxIterations_
56 setProbCut(0.01);
57}
AbsKalmanFitter(unsigned int maxIterations=4, double deltaPval=1e-3, double blowUpFactor=1e3)
void setAnnealingScheme(double bStart, double bFinal, unsigned int nSteps)
Configure the annealing scheme.
Definition DAF.cc:230
double deltaWeight_
Definition DAF.h:118
void setProbCut(const double prob_cut)
Set the probability cut for the weight calculation for the hits.
Definition DAF.cc:173
boost::scoped_ptr< AbsKalmanFitter > kalman_
Definition DAF.h:122

◆ DAF() [3/3]

genfit::DAF::DAF ( AbsKalmanFitter kalman,
double  deltaWeight = 1e-3,
double  deltaPval = 1e-3 
)

Create DAF. Use the provided AbsKalmanFitter as fitter.

Definition at line 59 of file DAF.cc.

60 : AbsKalmanFitter(10, deltaPval), deltaWeight_(deltaWeight)
61{
62 kalman_.reset(kalman);
63 kalman_->setMultipleMeasurementHandling(weightedAverage); // DAF makes no sense otherwise
64 kalman_->setMaxIterations(1);
65
66 if (dynamic_cast<KalmanFitterRefTrack*>(kalman_.get()) != NULL) {
67 static_cast<KalmanFitterRefTrack*>(kalman_.get())->setRefitAll();
68 }
69
70 setAnnealingScheme(100, 0.1, 5); // also sets maxIterations_
71 setProbCut(0.01);
72}

◆ ~DAF()

genfit::DAF::~DAF ( )
inline

Definition at line 67 of file DAF.h.

67{};

Member Function Documentation

◆ addProbCut()

void genfit::DAF::addProbCut ( const double  prob_cut,
const int  measDim 
)

Set the probability cut for the weight calculation for the hits for a specific measurement dimensionality.

Definition at line 179 of file DAF.cc.

179 {
180 if ( prob_cut > 1.0 || prob_cut < 0.0){
181 Exception exc("DAF::addProbCut prob_cut is not between 0 and 1",__LINE__,__FILE__);
182 exc.setFatal();
183 throw exc;
184 }
185 if ( measDim < 1){
186 Exception exc("DAF::addProbCut measDim must be > 0",__LINE__,__FILE__);
187 exc.setFatal();
188 throw exc;
189 }
190 chi2Cuts_[measDim] = ROOT::Math::chisquared_quantile_c( prob_cut, measDim);
191}
std::map< int, double > chi2Cuts_
Definition DAF.h:120

◆ calcWeights()

bool genfit::DAF::calcWeights ( Track trk,
const AbsTrackRep rep,
double  beta 
)
private

Calculate and set the weights for the next fitting pass. Return if convergence is met. The convergence criterium is the largest absolute change of all weights.

Definition at line 254 of file DAF.cc.

254 {
255
256 if (debugLvl_ > 0) {
257 std::cout<<"DAF::calcWeights \n";
258 }
259
260 bool converged(true);
261 double maxAbsChange(0);
262
263 const std::vector< TrackPoint* >& trackPoints = tr->getPointsWithMeasurement();
264 for (std::vector< TrackPoint* >::const_iterator tp = trackPoints.begin(); tp != trackPoints.end(); ++tp) {
265 if (! (*tp)->hasFitterInfo(rep)) {
266 continue;
267 }
268 AbsFitterInfo* fi = (*tp)->getFitterInfo(rep);
269 if (dynamic_cast<KalmanFitterInfo*>(fi) == NULL){
270 Exception exc("DAF::getWeights ==> can only use KalmanFitterInfos",__LINE__,__FILE__);
271 throw exc;
272 }
273 KalmanFitterInfo* kfi = static_cast<KalmanFitterInfo*>(fi);
274
275 if (kfi->areWeightsFixed()) {
276 if (debugLvl_ > 0) {
277 std::cout<<"weights are fixed, continue \n";
278 }
279 continue;
280 }
281
282 unsigned int nMeas = kfi->getNumMeasurements();
283
284 std::vector<double> phi(nMeas, 0.);
285 double phi_sum = 0;
286 double phi_cut = 0;
287 for(unsigned int j=0; j<nMeas; j++) {
288
289 try{
290 const MeasurementOnPlane& residual = kfi->getResidual(j, true, true);
291 const TVectorD& resid(residual.getState());
292 TMatrixDSym Vinv(residual.getCov());
293 double detV;
294 tools::invertMatrix(Vinv, &detV); // can throw an Exception
295 int hitDim = resid.GetNrows();
296 // Needed for normalization, special cases for the two common cases,
297 // shouldn't matter, but the original code made some efforts to make
298 // this calculation faster, and it's not complex ...
299 double twoPiN = 2.*M_PI;
300 if (hitDim == 2)
301 twoPiN *= twoPiN;
302 else if (hitDim > 2)
303 twoPiN = pow(twoPiN, hitDim);
304
305 double chi2 = Vinv.Similarity(resid);
306 if (debugLvl_ > 1) {
307 std::cout<<"chi2 = " << chi2 << "\n";
308 }
309
310 double norm = 1./sqrt(twoPiN * detV);
311
312 phi[j] = norm*exp(-0.5*chi2/beta);
313 phi_sum += phi[j];
314 //std::cerr << "hitDim " << hitDim << " fchi2Cuts[hitDim] " << fchi2Cuts[hitDim] << std::endl;
315 double cutVal = chi2Cuts_[hitDim];
316 assert(cutVal>1.E-6);
317 //the following assumes that in the competing hits could have different V otherwise calculation could be simplified
318 phi_cut += norm*exp(-0.5*cutVal/beta);
319 }
320 catch(Exception& e) {
321 std::cerr << e.what();
322 e.info();
323 }
324 }
325
326 for(unsigned int j=0; j<nMeas; j++) {
327 double weight = phi[j]/(phi_sum+phi_cut);
328
329 // check convergence
330 double absChange(fabs(weight - kfi->getMeasurementOnPlane(j)->getWeight()));
331 if (converged && absChange > deltaWeight_) {
332 converged = false;
333 if (absChange > maxAbsChange)
334 maxAbsChange = absChange;
335 }
336
337 if (debugLvl_ > 0) {
338 if (debugLvl_ > 1 || absChange > deltaWeight_) {
339 std::cout<<"\t old weight: " << kfi->getMeasurementOnPlane(j)->getWeight();
340 std::cout<<"\t new weight: " << weight;
341 }
342 }
343
344 kfi->getMeasurementOnPlane(j)->setWeight(weight);
345 }
346 }
347
348 if (debugLvl_ > 0) {
349 std::cout << "\t ";
350 std::cout << "max abs weight change = " << maxAbsChange << "\n";
351 }
352
353 return converged;
354}
unsigned int debugLvl_
Definition AbsFitter.h:55
void invertMatrix(const TMatrixDSym &mat, TMatrixDSym &inv, double *determinant=NULL)
Invert a matrix, throwing an Exception when inversion fails. Optional calculation of determinant.
Definition Tools.cc:38

◆ getKalman()

AbsKalmanFitter * genfit::DAF::getKalman ( ) const
inline

Definition at line 103 of file DAF.h.

103{return kalman_.get();}

◆ operator=()

DAF & genfit::DAF::operator= ( genfit::DAF const &  )
private

◆ processTrackWithRep()

void genfit::DAF::processTrackWithRep ( Track tr,
const AbsTrackRep rep,
bool  resortHits = false 
)
virtual

Process a track using the DAF.

Implements genfit::AbsFitter.

Definition at line 75 of file DAF.cc.

75 {
76
77 if (debugLvl_ > 0) {
78 std::cout<<"DAF::processTrack //////////////////////////////////////////////////////////////// \n";
79 }
80
81 KalmanFitStatus* status = 0;
82 bool oneLastIter = false;
83
84 double lastPval = -1;
85
86 for(unsigned int iBeta = 0;; ++iBeta) {
87
88 if (debugLvl_ > 0) {
89 std::cout<<"DAF::processTrack, trackRep " << rep << ", iteration " << iBeta+1 << ", beta = " << betas_.at(iBeta) << "\n";
90 }
91
92 kalman_->processTrackWithRep(tr, rep, resortHits);
93
94 status = static_cast<KalmanFitStatus*>(tr->getFitStatus(rep));
95 status->setIsFittedWithDaf();
96 status->setNumIterations(iBeta+1);
97
98
99 // check break conditions
100
101 if (! status->isFitted()){
102 if (debugLvl_ > 0) {
103 std::cout << "DAF::Kalman could not fit!\n";
104 }
105 status->setIsFitted(false);
106 break;
107 }
108
109 if( oneLastIter == true){
110 if (debugLvl_ > 0) {
111 std::cout << "DAF::break after one last iteration\n";
112 }
113 status->setIsFitConvergedFully(status->getNFailedPoints() == 0);
114 status->setIsFitConvergedPartially();
115 break;
116 }
117
118 if(iBeta >= maxIterations_-1){
119 status->setIsFitConvergedFully(false);
120 status->setIsFitConvergedPartially(false);
121 if (debugLvl_ > 0) {
122 std::cout << "DAF::number of max iterations reached!\n";
123 }
124 break;
125 }
126
127
128 // get and update weights
129 bool converged(false);
130 try{
131 converged = calcWeights(tr, rep, betas_.at(iBeta));
132 if (!converged && iBeta >= minIterations_-1 &&
133 status->getBackwardPVal() != 0 && fabs(lastPval - status->getBackwardPVal()) < this->deltaPval_) {
134 if (debugLvl_ > 0) {
135 std::cout << "converged by Pval = " << status->getBackwardPVal() << " even though weights changed at iBeta = " << iBeta << std::endl;
136 }
137 converged = true;
138 }
139 lastPval = status->getBackwardPVal();
140 } catch(Exception& e) {
141 std::cerr<<e.what();
142 e.info();
143 //std::cerr << "calc weights failed" << std::endl;
144 //mini_trk->getTrackRep(0)->setStatusFlag(1);
145 status->setIsFitted(false);
146 status->setIsFitConvergedFully(false);
147 status->setIsFitConvergedPartially(false);
148 break;
149 }
150
151 // check if converged
152 if (iBeta >= minIterations_-1 && converged) {
153 if (debugLvl_ > 0) {
154 std::cout << "DAF::convergence reached in iteration " << iBeta+1 << " -> Do one last iteration with updated weights.\n";
155 }
156 oneLastIter = true;
157 status->setIsFitConvergedFully(status->getNFailedPoints() == 0);
158 status->setIsFitConvergedPartially();
159 }
160
161 } // end loop over betas
162
163
164 if (status->getForwardPVal() == 0. &&
165 status->getBackwardPVal() == 0.) {
166 status->setIsFitConvergedFully(false);
167 status->setIsFitConvergedPartially(false);
168 }
169
170}
unsigned int maxIterations_
Maximum number of iterations to attempt. Forward and backward are counted as one iteration.
unsigned int minIterations_
Minimum number of iterations to attempt. Forward and backward are counted as one iteration.
std::vector< double > betas_
Definition DAF.h:119
bool calcWeights(Track *trk, const AbsTrackRep *rep, double beta)
Calculate and set the weights for the next fitting pass. Return if convergence is met....
Definition DAF.cc:254

◆ setAnnealingScheme()

void genfit::DAF::setAnnealingScheme ( double  bStart,
double  bFinal,
unsigned int  nSteps 
)

Configure the annealing scheme.

Set a start and end temperature and the number of steps. A logarithmic sequence of temperatures will be calculated. Also sets minIterations_ and maxIterations_.

Definition at line 230 of file DAF.cc.

230 {
231 // The betas are calculated as a geometric series that takes nSteps
232 // steps to go from bStart to bFinal.
233 assert(bStart > bFinal);
234 assert(bFinal > 1.E-10);
235 assert(nSteps > 1);
236
237 minIterations_ = nSteps;
238 maxIterations_ = nSteps + 4;
239
240 betas_.clear();
241
242 for (unsigned int i=0; i<nSteps; ++i) {
243 betas_.push_back(bStart * pow(bFinal / bStart, i / (nSteps - 1.)));
244 }
245
246 betas_.resize(maxIterations_,betas_.back()); //make sure main loop has a maximum of 10 iterations and also make sure the last beta value is used for if more iterations are needed then the ones set by the user.
247
248 /*for (unsigned int i=0; i<betas_.size(); ++i) {
249 std::cout<< betas_.at(i) << ", ";
250 }*/
251}
int i
Definition ShipAna.py:86

◆ setBetas()

void genfit::DAF::setBetas ( double  b1,
double  b2 = -1,
double  b3 = -1.,
double  b4 = -1.,
double  b5 = -1.,
double  b6 = -1.,
double  b7 = -1.,
double  b8 = -1.,
double  b9 = -1.,
double  b10 = -1. 
)

Configure the annealing scheme.

In the current implementation you need to provide at least one temperature and not more then ten temperatures. Also sets minIterations_ and maxIterations_.

Definition at line 194 of file DAF.cc.

194 {
195 betas_.clear();
196 assert(b1>0);betas_.push_back(b1);
197 if(b2>0){
198 assert(b2<=b1);betas_.push_back(b2);
199 if(b3>=0.) {
200 assert(b3<=b2);betas_.push_back(b3);
201 if(b4>=0.) {
202 assert(b4<=b3);betas_.push_back(b4);
203 if(b5>=0.) {
204 assert(b5<=b4);betas_.push_back(b5);
205 if(b6>=0.) {
206 assert(b6<=b5);betas_.push_back(b6);
207 if(b7>=0.) {
208 assert(b7<=b6);betas_.push_back(b7);
209 if(b8>=0.) {
210 assert(b8<=b7);betas_.push_back(b8);
211 if(b9>=0.) {
212 assert(b9<=b8);betas_.push_back(b9);
213 if(b10>=0.) {
214 assert(b10<=b9);betas_.push_back(b10);
215 }
216 }
217 }
218 }
219 }
220 }
221 }
222 }
223 }
224 minIterations_ = betas_.size();
225 maxIterations_ = betas_.size() + 4;
226 betas_.resize(maxIterations_,betas_.back()); //make sure main loop has a maximum of maxIterations_ and also make sure the last beta value is used for if more iterations are needed then the ones set by the user.
227}

◆ setConvergenceDeltaWeight()

void genfit::DAF::setConvergenceDeltaWeight ( double  delta)
inline

If all weights change less than delta between two iterations, the fit is regarded as converged.

Definition at line 101 of file DAF.h.

◆ setDebugLvl()

virtual void genfit::DAF::setDebugLvl ( unsigned int  lvl = 1)
inlinevirtual

Reimplemented from genfit::AbsFitter.

Definition at line 107 of file DAF.h.

107{AbsFitter::setDebugLvl(lvl); if (lvl > 1) getKalman()->setDebugLvl(lvl-1);}
virtual void setDebugLvl(unsigned int lvl=1)
Definition AbsFitter.h:50
AbsKalmanFitter * getKalman() const
Definition DAF.h:103

◆ setMaxFailedHits()

virtual void genfit::DAF::setMaxFailedHits ( int  val)
inlinevirtual

Reimplemented from genfit::AbsKalmanFitter.

Definition at line 105 of file DAF.h.

virtual void setMaxFailedHits(int val)

◆ setMaxIterations()

void genfit::DAF::setMaxIterations ( unsigned int  n)
inlinevirtual

Set the maximum number of iterations.

Reimplemented from genfit::AbsKalmanFitter.

Definition at line 98 of file DAF.h.

◆ setProbCut()

void genfit::DAF::setProbCut ( const double  prob_cut)

Set the probability cut for the weight calculation for the hits.

By default the cut values for measurements of dimensionality from 1 to 5 are calculated. If you what to have cut values for an arbitrary measurement dimensionality use addProbCut(double prob_cut, int maxDim);

Definition at line 173 of file DAF.cc.

173 {
174 for ( int i = 1; i != 6; ++i){
175 addProbCut(prob_cut, i);
176 }
177}
void addProbCut(const double prob_cut, const int measDim)
Set the probability cut for the weight calculation for the hits for a specific measurement dimensiona...
Definition DAF.cc:179

Member Data Documentation

◆ betas_

std::vector<double> genfit::DAF::betas_
private

Definition at line 119 of file DAF.h.

◆ chi2Cuts_

std::map<int,double> genfit::DAF::chi2Cuts_
private

Definition at line 120 of file DAF.h.

◆ deltaWeight_

double genfit::DAF::deltaWeight_
private

Definition at line 118 of file DAF.h.

◆ kalman_

boost::scoped_ptr<AbsKalmanFitter> genfit::DAF::kalman_
private

Definition at line 122 of file DAF.h.


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