79 const std::vector<FitMeasurement*>& measurements,
FitParameters& parameters,
93 auto trackStateOnSurfaces = std::make_unique<Trk::TrackStates>();
94 unsigned size = measurements.size() + 1;
96 size += leadingTSOS->
size();
97 trackStateOnSurfaces->reserve(size);
98 std::unique_ptr<AlignmentEffectsOnTrack> alignmentEffects{};
101 std::unique_ptr<MaterialEffectsBase> materialEffects{};
102 std::unique_ptr<MeasurementBase> measurementBase{};
103 const Surface* surface =
nullptr;
104 std::unique_ptr<TrackParameters> trackParameters{};
105 std::bitset<TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
106 const defaultPattern;
107 std::bitset<TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes>
108 typePattern = defaultPattern;
111 unsigned scatter = 0;
113 std::unique_ptr<Perigee> perigee(parameters.perigee());
116 fitQoS, std::move(measurementBase), std::move(perigee),
117 std::move(materialEffects), typePattern, std::move(alignmentEffects)));
122 for (
const auto* t : *leadingTSOS) {
124 trackStateOnSurfaces->push_back((*t).clone());
131 for (
auto* m : measurements) {
132 if (m->isMaterialDelimiter())
136 if (m->surface() != surface || alignmentEffects || m->alignmentEffects()) {
138 if (typePattern == defaultPattern) {
140 *cache.
log << MSG::DEBUG <<
" skip empty TSOS# " << tsos + 1;
141 if (m->materialEffects())
142 *cache.
log <<
" with material";
143 m->print(*cache.
log);
148 bool const withCovariance =
true;
149 trackParameters.reset(parameters.trackParameters(
150 *cache.
log, *fitMeasurement, withCovariance));
152 if (!trackParameters) {
155 <<
" fail track with incomplete return TSOS: no trackParameters"
161 fitQoS, std::move(measurementBase), std::move(trackParameters),
162 std::move(materialEffects), typePattern,
163 std::move(alignmentEffects)));
168 surface = m->surface();
169 measurementBase.reset();
170 materialEffects.reset();
171 typePattern = defaultPattern;
172 alignmentEffects.reset();
176 *cache.
log << MSG::VERBOSE <<
" tsos# " << tsos <<
" shared surface"
181 if (m->measurementBase()) {
184 if (measurementBase) {
186 bool const withCovariance =
true;
187 trackParameters.reset(parameters.trackParameters(
188 *cache.
log, *fitMeasurement, withCovariance));
189 if (!trackParameters) {
192 <<
" fail track with incomplete return TSOS: no trackParameters"
198 fitQoS, std::move(measurementBase), std::move(trackParameters),
199 std::move(materialEffects), typePattern,
200 std::move(alignmentEffects)));
203 materialEffects.reset();
204 typePattern = defaultPattern;
205 alignmentEffects.reset();
208 measurementBase = m->measurementBase()->uniqueClone();
215 if (m->materialEffects()) {
218 if (m->isEnergyDeposit()) {
219 materialEffects = m->materialEffects()->uniqueClone();
221 }
else if (m->isScatterer()) {
223 std::bitset<MaterialEffectsBase::NumberOfMaterialEffectsTypes>
235 materialEffects = std::make_unique<MaterialEffectsOnTrack>(
236 m->materialEffects()->thicknessInX0(),
237 parameters.scatteringAngles(*m, scatter), std::move(energyLoss),
238 m->materialEffects()->associatedSurface(), typeMaterial);
242 materialEffects = std::make_unique<MaterialEffectsOnTrack>(
243 m->materialEffects()->thicknessInX0(),
244 parameters.scatteringAngles(*m), std::move(energyLoss),
245 m->materialEffects()->associatedSurface(), typeMaterial);
251 materialEffects = std::make_unique<MaterialEffectsOnTrack>(
252 m->materialEffects()->thicknessInX0(),
253 parameters.scatteringAngles(*m, scatter),
254 m->materialEffects()->associatedSurface(), typeMaterial);
258 materialEffects = std::make_unique<MaterialEffectsOnTrack>(
259 m->materialEffects()->thicknessInX0(),
260 parameters.scatteringAngles(*m),
261 m->materialEffects()->associatedSurface(), typeMaterial);
267 *cache.
log << MSG::WARNING
268 <<
" deprecated TrackStateOnSurface::InertMaterial"
270 materialEffects = m->materialEffects()->uniqueClone();
276 if (m->isPerigee()) {
281 else if (m->alignmentEffects()) {
283 unsigned const align = m->alignmentParameter() - 1;
285 *cache.
log << MSG::VERBOSE <<
" Fitprocedure AEOT input deltaTranslation "
288 << parameters.alignmentOffset(align) <<
" deltaAngle "
289 << parameters.alignmentAngle(align) <<
endmsg;
290 alignmentEffects = std::make_unique<Trk::AlignmentEffectsOnTrack>(
298 else if (m->isPassive()) {
299 if (m->type() ==
hole)
305 bool const withCovariance =
true;
306 trackParameters.reset(
307 parameters.trackParameters(*cache.
log, *fitMeasurement, withCovariance));
308 if (!trackParameters) {
309 *cache.
log << MSG::WARNING
310 <<
" fail track with incomplete return TSOS: no trackParameters"
316 fitQoS, std::move(measurementBase), std::move(trackParameters),
317 std::move(materialEffects), typePattern, std::move(alignmentEffects)));
321 const double chiSquared = cache.
chiSq *
static_cast<double>(cache.
numberDoF);
323 std::make_unique<FitQuality>(chiSquared, cache.
numberDoF));
326 *cache.
log << MSG::VERBOSE <<
" track with " << tsos <<
" TSOS " <<
endmsg;
332 std::vector<FitMeasurement*>& measurements,
FitParameters*& parameters,
333 const FitQuality* perigeeQuality,
bool for_iPatTrack)
const {
336 if (cache.
log->level() > MSG::DEBUG) {
341 if (cache.
log->level() < MSG::DEBUG)
343 *cache.
log << MSG::DEBUG <<
"parameter start values: ";
344 parameters->print(*cache.
log);
349 const ToolHandle<IIntersector>& intersector =
353 int fitCode = cache.
fitMatrices->setDimensions(measurements, parameters);
355 cache.
fitQuality = std::make_unique<FitProcedureQuality>(
373 asymmetricCaloEnergy, cache.
fitMatrices->derivativeMatrix(), intersector,
378 if (measurements.front()->isPerigee()) {
379 cache.
fitMatrices->usePerigee(*measurements.front());
383 const double ptInvCut = 1. /
m_minPt;
390 std::optional<FitParameters> bestParameters = std::nullopt;
394 bool forceIteration =
false;
396 parameters->reset(*bestParameters);
400 *cache.
log << MSG::VERBOSE
401 <<
" convergence problem: accept after max iter " <<
endmsg;
414 }
else if (parameters->fitEnergyDeposit() &&
415 !parameters->extremeMomentum() &&
418 *cache.
log << MSG::DEBUG <<
" extremeMomentum " <<
endmsg;
419 parameters->extremeMomentum(
true);
420 fitCode = cache.
fitMatrices->setDimensions(measurements, parameters);
422 bestParameters = std::nullopt;
423 forceIteration =
true;
437 *cache.
log << MSG::VERBOSE <<
" ===== start iteration "
441 *cache.
log <<
" ====== cutStep";
444 *cache.
log <<
" ====== for_iPatTrack ";
446 parameters->printVerbose(*cache.
log);
452 }
else if (std::abs(parameters->ptInv0()) > ptInvCut) {
454 }
else if (measurements.front()->isVertex() &&
m_indetVolume &&
458 (std::abs(parameters->difference(3)) > 1.0 ||
460 !measurements.front()->isVertex()) {
461 if (std::abs(parameters->difference(3)) > 1.0) {
466 }
else if (!fitCode) {
471 cache.
fitQuality = std::make_unique<FitProcedureQuality>(
473 cache.
iteration, parameters->numberAlignments(),
474 cache.
fitMatrices->numberDoF(), parameters->numberScatterers(),
491 }
else if (cache.
iteration == 4 && cache.
chiSq > 1000. && for_iPatTrack) {
493 }
else if (!fitCode) {
509 <<
" take cutStep following chi2 increase on iteration "
511 <<
" driftSum " << cache.
driftSum <<
" prev "
513 }
else if (parameters->numberOscillations() > 2) {
517 *cache.
log << MSG::VERBOSE
518 <<
" take cutStep as oscillating, iteration "
519 << cache.
iteration <<
", numberOscillations "
520 << parameters->numberOscillations() <<
endmsg;
526 parameters->performCutStep(cutStep);
528 parameters->printVerbose(*cache.
log);
535 *cache.
log <<
" after cutStep: "
536 <<
" chi2Ratio " << cache.
chRatio1 <<
" driftSum "
543 if (!bestParameters || cache.
chiSq < bestChiSq) {
544 bestChiSq = cache.
chiSq;
545 bestParameters = *parameters;
546 parameters->resetOscillations();
549 if (bestParameters &&
552 parameters->reset(*bestParameters);
554 *cache.
log << MSG::VERBOSE <<
" revert to bestParameters ";
555 parameters->printVerbose(*cache.
log);
573 if (fitCode && cache.
iteration && bestParameters &&
574 !parameters->phiInstability() &&
575 (**(measurements.rbegin())).position().perp() >
m_largeRadius) {
577 *cache.
log << MSG::VERBOSE <<
" phi instability " <<
endmsg;
578 parameters->reset(*bestParameters);
579 parameters->setPhiInstability();
594 if (!for_iPatTrack) {
603 if (perigeeQuality) {
614 if (cache.
chiSq < 100.) {
615 const double chiSquared =
618 Genfun::CumulativeChiSquare(cache.
numberDoF)(chiSquared);
625 *cache.
log << MSG::VERBOSE <<
" fit converged";
628 <<
" (residual " << std::sqrt(cache.
chiSqWorst) <<
")";
636 cache.
fitQuality = std::make_unique<FitProcedureQuality>(
640 if (cache.
debug && (for_iPatTrack || fitCode))
660 std::vector<FitMeasurement*>& measurements)
const {
662 const double dChisqConv = 0.025;
667 double driftResidual = 0.;
669 for (
auto* m : measurements) {
678 double residual = m->residual();
679 double DiffSq = residual * residual;
680 cache.
chiSq += DiffSq;
681 if (m->isPositionMeasurement()) {
683 driftResidual += residual;
684 if (DiffSq > DSqMax) {
690 if (m->is2Dimensional()) {
691 residual = m->residual2();
692 DiffSq = residual * residual;
693 cache.
chiSq += DiffSq;
694 if (m->isPositionMeasurement()) {
695 if (DiffSq > DSqMax) {
716 if (DChiSq > -dChisqConv) {
728 static_cast<double>(cache.
fitMatrices->numberDriftCircles());
734 *cache.
log <<
"----------------------------------" << std::endl
735 << std::setiosflags(std::ios::fixed)
736 <<
" Debugging Info in ChiSquare method" << std::endl
737 <<
" # of track-fit iterations " << std::setw(3)
739 <<
" fit ChiSquared (per degree of freedom) " << std::setw(13)
740 << std::setprecision(3) << cache.
chiSq
741 <<
" # of degrees of freedom "
743 <<
" ChSq Ratio1/2 " << std::setw(9) << std::setprecision(3)
744 << cache.
chRatio1 << std::setw(10) << std::setprecision(3)
746 <<
" driftResidual " << std::setw(9) << std::setprecision(3)
747 << cache.
driftSum <<
" #driftCircles "
748 << cache.
fitMatrices->numberDriftCircles() << std::endl
749 <<
" CutTaken " << cache.
cutTaken << std::endl
750 <<
"----------------------------------" << std::endl
755 for (
auto* m : measurements) {
756 *cache.
log << std::setiosflags(std::ios::fixed) << std::setw(3) << ++n;
757 if (m->isPerigee()) {
758 *cache.
log <<
" perigee ";
759 *cache.
log << std::endl;
761 m->print(*cache.
log);
769 (cache.
chiSq < 0.1 ||
771 (std::abs(DChiSq) < dChisqConv ||
779 *cache.
log << MSG::VERBOSE <<
" near convergence " <<
endmsg;