78 std::vector<EventT0::EventT0Component>& eventT0WithQualityIndex)
80 if (not eventT0->hasEventT0()) {
81 B2DEBUG(25,
"No event t0 is set. Not testing.");
87 const double quality = chi2_with_ndf.second;
89 if (std::isnan(quality)) {
90 B2DEBUG(25,
"The calculated quality is nan. Not using this EventT0 of " << eventT0->getEventT0());
94 B2DEBUG(25,
"The iteration gave a result of " << quality <<
" for " << eventT0->getEventT0());
96 eventT0Component.
quality = quality;
97 eventT0WithQualityIndex.emplace_back(eventT0Component);
98 eventT0->addTemporaryEventT0(eventT0Component);
99 eventT0->setEventT0(eventT0Component);
107 double summedChi2 = 0;
108 double summedNDF = 0;
109 unsigned int numberOfFittableRecoTracks = 0;
111 for (
RecoTrack* recoTrack : recoTracks) {
113 recoTrack->setDirtyFlag();
116 if (not trackFitter.
fit(*recoTrack)) {
121 const double ndf = recoTrack->getTrackFitStatus()->getNdf();
123 if (std::isnan(chi2)) {
127 numberOfFittableRecoTracks++;
132 if (numberOfFittableRecoTracks == 0) {
136 return {summedChi2 / numberOfFittableRecoTracks, summedNDF / numberOfFittableRecoTracks};
145 double sumFirstDerivatives = 0;
146 double sumSecondDerivatives = 0;
147 unsigned int numberOfFittableRecoTracks = 0;
149 for (
RecoTrack* recoTrack : recoTracks) {
151 recoTrack->setDirtyFlag();
154 if (not trackFitter.
fit(*recoTrack)) {
159 const double dchi2da = chi2Derivatives.first;
160 const double d2chi2da2 = chi2Derivatives.second;
162 if (std::isnan(dchi2da) or std::isnan(d2chi2da2)) {
166 if (d2chi2da2 > 20) {
167 B2DEBUG(25,
"Track with bad second derivative");
171 numberOfFittableRecoTracks++;
172 sumFirstDerivatives += dchi2da;
173 sumSecondDerivatives += d2chi2da2;
176 if (numberOfFittableRecoTracks == 0) {
180 const double extractedEventT0 = sumFirstDerivatives / sumSecondDerivatives;
181 const double extractedEventT0Uncertainty = std::sqrt(2 / sumSecondDerivatives);
183 return {extractedEventT0, extractedEventT0Uncertainty};
203 B2DEBUG(200,
"No CDC hits in track.");
211 if (fs->isTrackPruned()) {
212 B2WARNING(
"Skipping pruned track");
220 TMatrixDSym fullCovariance;
226 TMatrixDSym fullResidualCovariance;
227 TMatrixDSym inverseFullMeasurementCovariance;
229 inverseFullMeasurementCovariance);
232 TVectorD residualsTimeDerivative;
238 const double dchi2da = 2. * residualsTimeDerivative * (inverseFullMeasurementCovariance * residuals);
242 const double d2chi2da2 = 2. * fullResidualCovariance.Similarity(inverseFullMeasurementCovariance * residualsTimeDerivative);
245 if (d2chi2da2 > 20) {
246 B2DEBUG(200,
"Track with bad second derivative");
249 return {dchi2da, d2chi2da2};
251 B2DEBUG(25,
"Failed time extraction - skipping track");
273 TMatrixDSym& fullCovariance)
275 const auto* kfs =
dynamic_cast<const genfit::KalmanFitStatus*
>(recoTrack.
getTrackFitStatus());
278 B2ERROR(
"Track not fitted with a Kalman fitter.");
282 if (!kfs->isFitConverged()) {
283 B2ERROR(
"Track fit didn't converge.");
287 if (!kfs->isFittedWithReferenceTrack()) {
288 B2ERROR(
"No reference track.");
293 const unsigned int nPoints = hitPoints.size();
295 const int nDim = rep->getDim();
297 fullCovariance.ResizeTo(nPoints * nDim, nPoints * nDim);
298 std::vector<TMatrixD> vFitterGain;
299 vFitterGain.reserve(nPoints);
300 for (
unsigned int i = 0; i < nPoints; ++i) {
301 const genfit::TrackPoint* tp = hitPoints[i];
302 const genfit::KalmanFitterInfo* fi = tp->getKalmanFitterInfo();
304 B2DEBUG(25,
"Missing KalmanFitterInfo - skipping track");
310 const genfit::MeasuredStateOnPlane& mop = fi->getFittedState();
311 setSubOnDiagonal(fullCovariance, i * nDim, mop.getCov());
314 if (i + 1 < nPoints) {
315 const genfit::TrackPoint* tpNext = hitPoints[i + 1];
316 const genfit::KalmanFitterInfo* fiNext = tpNext->getKalmanFitterInfo();
318 B2DEBUG(25,
"Missing next KalmanFitterInfo - skipping track");
323 const genfit::MeasuredStateOnPlane* update = fi->getForwardUpdate();
325 const genfit::ReferenceStateOnPlane* rsop = fiNext->getReferenceState();
327 const genfit::MeasuredStateOnPlane* pred = fiNext->getForwardPrediction();
330 TDecompChol decomp(pred->getCov());
331 TMatrixD F = rsop->getForwardTransportMatrix();
332 decomp.MultiSolve(F);
337 vFitterGain.emplace_back(TMatrixD(update->getCov(),
338 TMatrixD::kMultTranspose, F));
340 B2DEBUG(150,
"No reference state, substituting empty fitter gain matrix.");
341 vFitterGain.emplace_back(TMatrixD(5, 5));
346 TMatrixD offDiag = mop.getCov();
347 for (
int j = i - 1; j >= 0; --j) {
348 offDiag = TMatrixD(vFitterGain[j], TMatrixD::kMult, offDiag);
349 setSubOffDiagonal(fullCovariance, j * nDim, i * nDim, offDiag);
357 const std::vector<int>& vDimMeas,
358 const TMatrixDSym& fullCovariance,
359 TMatrixDSym& fullResidualCovariance,
360 TMatrixDSym& inverseFullMeasurementCovariance)
363 const unsigned int nPoints = hitPoints.size();
365 const int nDim = rep->getDim();
366 int measurementDimensions = std::accumulate(vDimMeas.begin(), vDimMeas.end(), 0);
367 fullResidualCovariance.ResizeTo(measurementDimensions, measurementDimensions);
368 inverseFullMeasurementCovariance.ResizeTo(measurementDimensions, measurementDimensions);
371 std::vector<TMatrixD> HMatrices;
372 HMatrices.reserve(nPoints);
373 for (
unsigned int i = 0, index = 0; i < nPoints; ++i) {
374 const genfit::TrackPoint* tp = hitPoints[i];
375 const genfit::AbsMeasurement* meas = tp->getRawMeasurement(0);
376 std::unique_ptr<const genfit::AbsHMatrix> pH(meas->constructHMatrix(rep));
377 const TMatrixD& H = pH->getMatrix();
378 int nDimMeas = vDimMeas[i];
379 TMatrixDSym cov = fullCovariance.GetSub(i * nDim, (i + 1) * nDim - 1,
380 i * nDim, (i + 1) * nDim - 1);
382 setSubOnDiagonal(fullResidualCovariance, index, cov);
384 int indexOffDiag = index;
385 for (
int j = i - 1; j >= 0; --j) {
386 int nDimMeasJ = HMatrices[j].GetNrows();
387 indexOffDiag -= nDimMeasJ;
389 TMatrixD offDiag(HMatrices[j], TMatrixD::kMult,
390 TMatrixD(fullCovariance.GetSub(nDim * j, nDim * (j + 1) - 1,
391 nDim * i, nDim * (i + 1) - 1),
392 TMatrixD::kMultTranspose, H));
394 setSubOffDiagonal(fullResidualCovariance, indexOffDiag, index, offDiag);
398 HMatrices.push_back(H);
403 fullResidualCovariance *= -1;
404 inverseFullMeasurementCovariance = 0;
405 for (
unsigned int i = 0, index = 0; i < nPoints; ++i) {
406 const genfit::TrackPoint* tp = hitPoints[i];
407 const genfit::KalmanFitterInfo* fi = tp->getKalmanFitterInfo();
408 const genfit::MeasurementOnPlane& mop = fi->getAvgWeightedMeasurementOnPlane();
409 TMatrixDSym cov = mop.getCov();
410 const int dim = cov.GetNrows();
411 setSubOnDiagonal(fullResidualCovariance, index,
412 cov + fullResidualCovariance.GetSub(index, index + dim - 1,
413 index, index + dim - 1));
415 genfit::tools::invertMatrix(cov);
416 setSubOnDiagonal(inverseFullMeasurementCovariance, index, cov);
426 const std::vector<int>& vDimMeas,
428 TVectorD& residualTimeDerivative)
432 int measurementDimensions = std::accumulate(vDimMeas.begin(), vDimMeas.end(), 0);
433 residuals.ResizeTo(measurementDimensions);
434 residualTimeDerivative.ResizeTo(measurementDimensions);
437 const unsigned int nPoints = hitPoints.size();
438 for (
unsigned int i = 0, index = 0; i < nPoints; ++i) {
439 const genfit::TrackPoint* tp = hitPoints[i];
440 const genfit::KalmanFitterInfo* fi = tp->getKalmanFitterInfo();
442 const std::vector<double>& weights = fi->getWeights();
443 TVectorD weightedResidual(vDimMeas[i]);
444 for (
size_t iMeas = 0; iMeas < fi->getNumMeasurements(); ++iMeas) {
445 weightedResidual += weights[iMeas] * fi->getResidual(iMeas).getState();
447 residuals.SetSub(index, weightedResidual);
448 if (
dynamic_cast<const CDCRecoHit*
>(tp->getRawMeasurement(0))) {
450 std::vector<double> deriv = hit->timeDerivativesMeasurementsOnPlane(fi->getFittedState());
452 double weightedDeriv = weights[0] * deriv[0] + weights[1] * deriv[1];
453 residualTimeDerivative[index] = weightedDeriv;
455 index += vDimMeas[i];