21 #include "Exception.h"
23 #include "KalmanFitterInfo.h"
24 #include "KalmanFitter.h"
25 #include "KalmanFitterRefTrack.h"
26 #include "KalmanFitStatus.h"
29 #include "TrackPoint.h"
37 #include <Math/QuantFuncMathCore.h>
43 DAF::DAF(
bool useRefKalman,
double deltaPval,
double deltaWeight)
54 kalman_->setMaxIterations(1);
63 kalman_.reset(kalman);
65 kalman_->setMaxIterations(1);
79 debugOut<<
"DAF::processTrack //////////////////////////////////////////////////////////////// \n";
83 bool oneLastIter =
false;
87 for(
unsigned int iBeta = 0;; ++iBeta) {
90 debugOut<<
"DAF::processTrack, trackRep " << rep <<
", iteration " << iBeta+1 <<
", beta = " << betas_.at(iBeta) <<
"\n";
93 kalman_->processTrackWithRep(tr, rep, resortHits);
96 status->setIsFittedWithDaf();
97 status->setNumIterations(iBeta+1);
102 if (! status->isFitted()){
104 debugOut <<
"DAF::Kalman could not fit!\n";
106 status->setIsFitted(
false);
110 if( oneLastIter ==
true){
112 debugOut <<
"DAF::break after one last iteration\n";
114 status->setIsFitConvergedFully(status->getNFailedPoints() == 0);
115 status->setIsFitConvergedPartially();
120 status->setIsFitConvergedFully(
false);
121 status->setIsFitConvergedPartially(
false);
123 debugOut <<
"DAF::number of max iterations reached!\n";
130 bool converged(
false);
132 converged =
calcWeights(tr, rep, betas_.at(iBeta));
134 status->getBackwardPVal() != 0 && fabs(lastPval - status->getBackwardPVal()) < this->deltaPval_) {
136 debugOut <<
"converged by Pval = " << status->getBackwardPVal() <<
" even though weights changed at iBeta = " << iBeta << std::endl;
140 lastPval = status->getBackwardPVal();
146 status->setIsFitted(
false);
147 status->setIsFitConvergedFully(
false);
148 status->setIsFitConvergedPartially(
false);
155 debugOut <<
"DAF::convergence reached in iteration " << iBeta+1 <<
" -> Do one last iteration with updated weights.\n";
158 status->setIsFitConvergedFully(status->getNFailedPoints() == 0);
159 status->setIsFitConvergedPartially();
165 if (status->getForwardPVal() == 0. &&
166 status->getBackwardPVal() == 0.) {
167 status->setIsFitConvergedFully(
false);
168 status->setIsFitConvergedPartially(
false);
175 for (
int i = 1; i < 7; ++i){
181 if ( prob_cut > 1.0 || prob_cut < 0.0){
182 Exception exc(
"DAF::addProbCut prob_cut is not between 0 and 1",__LINE__,__FILE__);
186 if ( measDim < 1 || measDim > 6 ){
187 Exception exc(
"DAF::addProbCut measDim must be in the range [1,6]",__LINE__,__FILE__);
191 chi2Cuts_[measDim] = ROOT::Math::chisquared_quantile_c( prob_cut, measDim);
197 assert(bStart > bFinal);
198 assert(bFinal > 1.E-10);
206 for (
unsigned int i=0; i<nSteps; ++i) {
207 betas_.push_back(bStart * pow(bFinal / bStart, i / (nSteps - 1.)));
224 bool converged(
true);
225 double maxAbsChange(0);
227 const std::vector< TrackPoint* >& trackPoints = tr->getPointsWithMeasurement();
228 for (std::vector< TrackPoint* >::const_iterator tp = trackPoints.begin(); tp != trackPoints.end(); ++tp) {
229 if (! (*tp)->hasFitterInfo(rep)) {
234 Exception exc(
"DAF::getWeights ==> can only use KalmanFitterInfos",__LINE__,__FILE__);
241 debugOut<<
"weights are fixed, continue \n";
246 unsigned int nMeas = kfi->getNumMeasurements();
248 std::vector<double> phi(nMeas, 0.);
251 for(
unsigned int j=0; j<nMeas; j++) {
255 const TVectorD& resid(residual.getState());
256 TMatrixDSym Vinv(residual.getCov());
258 tools::invertMatrix(Vinv, &detV);
259 int hitDim = resid.GetNrows();
263 double twoPiN = 2.*M_PI;
267 twoPiN = pow(twoPiN, hitDim);
269 double chi2 = Vinv.Similarity(resid);
271 debugOut<<
"chi2 = " << chi2 <<
"\n";
275 double norm = 1./sqrt(twoPiN * detV);
277 phi[j] = norm*exp(-0.5*chi2/beta);
280 double cutVal = chi2Cuts_[hitDim];
281 assert(cutVal>1.E-6);
283 phi_cut += norm*exp(-0.5*cutVal/beta);
291 for(
unsigned int j=0; j<nMeas; j++) {
292 double weight = phi[j]/(phi_sum+phi_cut);
296 double absChange(fabs(weight - kfi->getMeasurementOnPlane(j)->getWeight()));
297 if (converged && absChange > deltaWeight_) {
299 if (absChange > maxAbsChange)
300 maxAbsChange = absChange;
304 if (debugLvl_ > 1 || absChange > deltaWeight_) {
305 debugOut<<
"\t old weight: " << kfi->getMeasurementOnPlane(j)->getWeight();
306 debugOut<<
"\t new weight: " << weight;
310 kfi->getMeasurementOnPlane(j)->setWeight(weight);
316 debugOut <<
"max abs weight change = " << maxAbsChange <<
"\n";
324 void DAF::Streamer(TBuffer &R__b)
329 typedef ::genfit::DAF thisClass;
331 if (R__b.IsReading()) {
332 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
if (R__v) { }
335 baseClass0::Streamer(R__b);
336 R__b >> deltaWeight_;
339 std::vector<double> &R__stl = betas_;
343 R__stl.reserve(R__n);
344 for (R__i = 0; R__i < R__n; R__i++) {
347 R__stl.push_back(R__t);
355 for (R__i = 0; R__i < R__n; R__i++) {
356 memset(chi2Cuts_, 0,
sizeof(chi2Cuts_));
361 if (R__t >= 1 && R__t <= 6)
362 chi2Cuts_[R__t] = R__t2;
367 assert(n_chi2Cuts == 6);
369 R__b.ReadFastArray(&chi2Cuts_[1], n_chi2Cuts);
374 R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
376 R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
379 baseClass0::Streamer(R__b);
380 R__b << deltaWeight_;
382 std::vector<double> &R__stl = betas_;
383 int R__n=int(R__stl.size());
386 std::vector<double>::iterator R__k;
387 for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
394 R__b.WriteFastArray(&chi2Cuts_[1], 6);
396 R__b << kalman_.get();
397 R__b.SetByteCount(R__c, kTRUE);
This class collects all information needed and produced by a specific AbsFitter and is specific to on...
Abstract base class for Kalman fitter and derived fitting algorithms.
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.
Abstract base class for a track representation.
void processTrackWithRep(Track *tr, const AbsTrackRep *rep, bool resortHits=false) override
Process a track using the DAF.
void setProbCut(const double prob_cut)
Set the probability cut for the weight calculation for the hits.
void setAnnealingScheme(double bStart, double bFinal, unsigned int nSteps)
Configure the annealing scheme.
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...
bool calcWeights(Track *trk, const AbsTrackRep *rep, double beta)
Calculate and set the weights for the next fitting pass.
Exception class for error handling in GENFIT (provides storage for diagnostic information)
void setFatal(bool b=true)
Set fatal flag.
FitStatus for use with AbsKalmanFitter implementations.
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
MeasurementOnPlane getResidual(unsigned int iMeasurement=0, bool biased=false, bool onlyMeasurementErrors=true) const override
Get unbiased (default) or biased residual from ith measurement.
bool areWeightsFixed() const
Are the weights fixed?
Kalman filter implementation with linearization around a reference track.
Simple Kalman filter implementation.
Measured coordinates on a plane.
Collection of TrackPoint objects, AbsTrackRep objects and FitStatus objects.
FitStatus * getFitStatus(const AbsTrackRep *rep=nullptr) const
Get FitStatus for a AbsTrackRep. Per default, return FitStatus for cardinalRep.
Defines for I/O streams used for error and debug printing.
std::ostream debugOut
Default stream for debug output.
@ weightedAverage
weighted average between measurements; used by DAF
std::ostream errorOut
Default stream for error output.