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(std::tuple<double, double, int> annealingScheme,
int minIter,
int maxIter,
int minIterForPval,
bool useRefKalman,
44 double deltaPval,
double deltaWeight,
double probCut)
45 :
AbsKalmanFitter(10, deltaPval), deltaWeight_(deltaWeight), minIterForPval_(minIterForPval)
54 kalman_->setMaxIterations(1);
57 std::get<1>(annealingScheme),
58 std::get<2>(annealingScheme),
63 DAF::DAF(
bool useRefKalman,
double deltaPval,
double deltaWeight)
73 kalman_->setMaxIterations(1);
82 kalman_.reset(kalman);
84 kalman_->setMaxIterations(1);
99 debugOut <<
"DAF::processTrack //////////////////////////////////////////////////////////////// \n";
103 bool oneLastIter =
false;
105 double lastPval = -1;
107 for (
unsigned int iBeta = 0;; ++iBeta) {
110 debugOut <<
"DAF::processTrack, trackRep " << rep <<
", iteration " << iBeta + 1 <<
", beta = " << betas_.at(iBeta) <<
"\n";
113 kalman_->processTrackWithRep(tr, rep, resortHits);
116 status->setIsFittedWithDaf();
117 status->setNumIterations(iBeta + 1);
122 if (! status->isFitted()) {
124 debugOut <<
"DAF::Kalman could not fit!\n";
126 status->setIsFitted(
false);
130 if (oneLastIter ==
true) {
132 debugOut <<
"DAF::break after one last iteration\n";
134 status->setIsFitConvergedFully(status->getNFailedPoints() == 0);
135 status->setIsFitConvergedPartially();
140 status->setIsFitConvergedFully(
false);
141 status->setIsFitConvergedPartially(
false);
143 debugOut <<
"DAF::number of max iterations reached!\n";
150 bool converged(
false);
152 converged =
calcWeights(tr, rep, betas_.at(iBeta));
153 if (!converged && iBeta >= minIterForPval_ - 1 &&
154 status->getBackwardPVal() > 1e-10 && lastPval > 1e-10 && fabs(lastPval - status->getBackwardPVal()) < this->deltaPval_) {
156 debugOut <<
"converged by Pval = " << status->getBackwardPVal() <<
" even though weights changed at iBeta = " << iBeta << std::endl;
160 lastPval = status->getBackwardPVal();
166 status->setIsFitted(
false);
167 status->setIsFitConvergedFully(
false);
168 status->setIsFitConvergedPartially(
false);
175 debugOut <<
"DAF::convergence reached in iteration " << iBeta + 1 <<
" -> Do one last iteration with updated weights.\n";
178 status->setIsFitConvergedFully(status->getNFailedPoints() == 0);
179 status->setIsFitConvergedPartially();
185 if (status->getForwardPVal() == 0. &&
186 status->getBackwardPVal() == 0.) {
187 status->setIsFitConvergedFully(
false);
188 status->setIsFitConvergedPartially(
false);
196 for (
int i = 1; i < 7; ++i) {
203 if (prob_cut > 1.0 || prob_cut < 0.0) {
204 Exception exc(
"DAF::addProbCut prob_cut is not between 0 and 1", __LINE__, __FILE__);
208 if (measDim < 1 || measDim > 6) {
209 Exception exc(
"DAF::addProbCut measDim must be in the range [1,6]", __LINE__, __FILE__);
213 chi2Cuts_[measDim] = ROOT::Math::chisquared_quantile_c(prob_cut, measDim);
220 assert(bStart > bFinal);
221 assert(bFinal > 1.E-10);
226 minIterForPval_ = nSteps;
230 for (
unsigned int i = 0; i < nSteps; ++i) {
231 betas_.push_back(bStart * pow(bFinal / bStart, i / (nSteps - 1.)));
243 assert(bStart > bFinal);
244 assert(bFinal > 1.E-10);
252 for (
unsigned int i = 0; i < nSteps; ++i) {
253 betas_.push_back(bStart * pow(bFinal / bStart, i / (nSteps - 1.)));
269 bool converged(
true);
270 double maxAbsChange(0);
272 const std::vector< TrackPoint* >& trackPoints = tr->getPointsWithMeasurement();
273 for (std::vector< TrackPoint* >::const_iterator tp = trackPoints.begin(); tp != trackPoints.end(); ++tp) {
274 if (!(*tp)->hasFitterInfo(rep)) {
279 Exception exc(
"DAF::getWeights ==> can only use KalmanFitterInfos", __LINE__, __FILE__);
286 debugOut <<
"weights are fixed, continue \n";
291 unsigned int nMeas = kfi->getNumMeasurements();
293 std::vector<double> phi(nMeas, 0.);
296 for (
unsigned int j = 0; j < nMeas; j++) {
300 const TVectorD& resid(residual.getState());
301 TMatrixDSym Vinv(residual.getCov());
303 tools::invertMatrix(Vinv, &detV);
304 int hitDim = resid.GetNrows();
308 double twoPiN = 2.*M_PI;
312 twoPiN = pow(twoPiN, hitDim);
314 double chi2 = Vinv.Similarity(resid);
316 debugOut <<
"chi2 = " << chi2 <<
"\n";
320 double norm = 1. /
sqrt(twoPiN * detV);
322 phi[j] = norm * exp(-0.5 * chi2 / beta);
325 double cutVal = chi2Cuts_[hitDim];
326 assert(cutVal > 1.E-6);
328 phi_cut += norm * exp(-0.5 * cutVal / beta);
335 for (
unsigned int j = 0; j < nMeas; j++) {
336 double weight = phi[j] / (phi_sum + phi_cut);
340 double absChange(fabs(weight - kfi->getMeasurementOnPlane(j)->getWeight()));
341 if (converged && absChange > deltaWeight_) {
343 if (absChange > maxAbsChange)
344 maxAbsChange = absChange;
348 if (debugLvl_ > 1 || absChange > deltaWeight_) {
349 debugOut <<
"\t old weight: " << kfi->getMeasurementOnPlane(j)->getWeight();
350 debugOut <<
"\t new weight: " << weight;
354 kfi->getMeasurementOnPlane(j)->setWeight(weight);
360 debugOut <<
"max abs weight change = " << maxAbsChange <<
"\n";
368 void DAF::Streamer(TBuffer& R__b)
373 typedef ::genfit::DAF thisClass;
375 if (R__b.IsReading()) {
376 Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
380 baseClass0::Streamer(R__b);
381 R__b >> deltaWeight_;
384 std::vector<double>& R__stl = betas_;
388 R__stl.reserve(R__n);
389 for (R__i = 0; R__i < R__n; R__i++) {
392 R__stl.push_back(R__t);
400 for (R__i = 0; R__i < R__n; R__i++) {
401 memset(chi2Cuts_, 0,
sizeof(chi2Cuts_));
406 if (R__t >= 1 && R__t <= 6)
407 chi2Cuts_[R__t] = R__t2;
412 assert(n_chi2Cuts == 6);
414 R__b.ReadFastArray(&chi2Cuts_[1], n_chi2Cuts);
419 R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
421 R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
424 baseClass0::Streamer(R__b);
425 R__b << deltaWeight_;
427 std::vector<double>& R__stl = betas_;
428 int R__n = int(R__stl.size());
431 std::vector<double>::iterator R__k;
432 for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
439 R__b.WriteFastArray(&chi2Cuts_[1], 6);
441 R__b << kalman_.get();
442 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.
double sqrt(double a)
sqrt for double
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.