333 {
334
336 if (cache.log->level() > MSG::DEBUG) {
337 cache.debug = false;
338 cache.verbose = false;
339 } else {
340 cache.debug = true;
341 if (cache.log->level() < MSG::DEBUG)
342 cache.verbose = true;
343 *cache.log << MSG::DEBUG << "parameter start values: ";
346 }
347
348
349 const ToolHandle<IIntersector>& intersector =
351
352
353 int fitCode = cache.fitMatrices->setDimensions(measurements, parameters);
354 if (fitCode) {
355 cache.fitQuality = std::make_unique<FitProcedureQuality>(
356 fitCode, cache.fitMatrices->numberDoF());
357 if (cache.debug)
359 return *cache.fitQuality;
360 }
361
362
363 cache.chiSq = 0.;
364 cache.chiSqWorst = 0.;
365 cache.driftSum = 0.;
366 cache.driftSumLast = 0.;
367 cache.fitProbability = 0.;
368 cache.iteration = -1;
369 cache.numberDoF = cache.fitMatrices->numberDoF();
370 cache.numberParameters =
parameters->numberParameters();
371 cache.worstMeasurement = 0;
372 MeasurementProcessor measurementProcessor(
373 asymmetricCaloEnergy, cache.fitMatrices->derivativeMatrix(), intersector,
376
377
378 if (measurements.front()->isPerigee()) {
379 cache.fitMatrices->usePerigee(*measurements.front());
380 }
381
382
383 const double ptInvCut = 1. /
m_minPt;
384 cache.cutStep = true;
385 cache.convergence = false;
386 cache.nearConvergence = false;
387
388
389 double bestChiSq = cache.chiSqCut;
390 std::optional<FitParameters> bestParameters = std::nullopt;
391
392
393 while (!fitCode && !cache.convergence) {
394 bool forceIteration = false;
395 if (cache.iteration >
m_maxIter && bestParameters && !for_iPatTrack) {
397 cache.convergence = true;
398 cache.cutStep = false;
399 if (cache.verbose)
400 *cache.log << MSG::VERBOSE
401 <<
" convergence problem: accept after max iter " <<
endmsg;
402 } else if (!cache.cutStep) {
403
404 if (!cache.iteration) {
405 cache.fitMatrices->refinePointers();
407 cache.fitMatrices->checkPointers(*cache.log);
408 if (cache.verbose)
409 cache.fitMatrices->printDerivativeMatrix();
410 }
411
412 if (!cache.fitMatrices->solveEquations()) {
413 fitCode = 11;
417 if (cache.debug)
418 *cache.log << MSG::DEBUG <<
" extremeMomentum " <<
endmsg;
420 fitCode = cache.fitMatrices->setDimensions(measurements, parameters);
421 bestChiSq = cache.chiSqCut;
422 bestParameters = std::nullopt;
423 forceIteration = true;
424 cache.chiSq = 0.;
425 cache.chiSqWorst = 0.;
426 cache.driftSum = 0.;
427 cache.driftSumLast = 0.;
428 cache.numberParameters =
parameters->numberParameters();
429 }
430 if (cache.verbose && !cache.iteration)
431 cache.fitMatrices->printWeightMatrix();
432 }
433 ++cache.iteration;
434
435
436 if (cache.verbose) {
437 *cache.log << MSG::VERBOSE << " ===== start iteration "
438 << cache.iteration;
439 if (cache.iteration) {
440 if (cache.cutStep)
441 *cache.log << " ====== cutStep";
442 } else {
443 if (for_iPatTrack)
444 *cache.log << " ====== for_iPatTrack ";
445 }
447 }
448
449
450 if (fitCode) {
451
452 }
else if (std::abs(
parameters->ptInv0()) > ptInvCut) {
453 fitCode = 8;
454 }
else if (measurements.front()->isVertex() &&
m_indetVolume &&
456 fitCode = 9;
457 } else if (cache.iteration &&
460 !measurements.front()->isVertex()) {
461 if (std::abs(
parameters->difference(3)) > 1.0) {
462 fitCode = 10;
463 } else {
464 fitCode = 9;
465 }
466 } else if (!fitCode) {
467
468 if (!measurementProcessor.calculateFittedTrajectory(cache.iteration) ||
469 !measurementProcessor.calculateDerivatives()) {
470 fitCode = 5;
471 cache.fitQuality = std::make_unique<FitProcedureQuality>(
472 cache.chiSq, cache.chiSqWorst, cache.fitProbability, fitCode,
473 cache.iteration,
parameters->numberAlignments(),
474 cache.fitMatrices->numberDoF(),
parameters->numberScatterers(),
475 cache.worstMeasurement);
476
477 if (cache.debug) {
478 if (cache.verbose)
481 }
482 return *cache.fitQuality;
483 }
484
485
486 measurementProcessor.calculateResiduals();
487
488
489 if (cache.iteration >
m_maxIter && !cache.cutStep && for_iPatTrack) {
490 fitCode = 6;
491 } else if (cache.iteration == 4 && cache.chiSq > 1000. && for_iPatTrack) {
492 fitCode = 7;
493 } else if (!fitCode) {
495
496
497 if (!forceIteration && !cache.convergence && cache.chRatio1 > 0.9) {
498 double cutStep = 0.;
499 if (cache.iteration > 4 &&
500 cache.driftSum * cache.driftSumLast < -1.) {
501 cache.cutStep = true;
502 cutStep = std::abs(cache.driftSumLast /
503 (cache.driftSum - cache.driftSumLast));
504 if (cutStep < 0.001)
505 cutStep = 0.001;
506 if (cache.verbose)
507 *cache.log
508 << MSG::VERBOSE
509 << " take cutStep following chi2 increase on iteration "
510 << cache.iteration << " chi2Ratio " << cache.chRatio1
511 << " driftSum " << cache.driftSum << " prev "
512 << cache.driftSumLast <<
" " << cutStep <<
endmsg;
513 }
else if (
parameters->numberOscillations() > 2) {
514 cache.cutStep = true;
515 cutStep = 0.5;
516 if (cache.verbose)
517 *cache.log << MSG::VERBOSE
518 << " take cutStep as oscillating, iteration "
519 << cache.iteration << ", numberOscillations "
521 }
522
523
524 if (cache.cutStep) {
525 cache.convergence = false;
527 if (cache.verbose)
529 if (measurementProcessor.calculateFittedTrajectory(
530 cache.iteration)) {
531
532 measurementProcessor.calculateResiduals();
534 if (cache.verbose)
535 *cache.log << " after cutStep: "
536 << " chi2Ratio " << cache.chRatio1 << " driftSum "
537 << cache.driftSum <<
endmsg;
538 }
539 }
540 }
541
542
543 if (!bestParameters || cache.chiSq < bestChiSq) {
544 bestChiSq = cache.chiSq;
547 }
548
549 if (bestParameters &&
550 ((cache.convergence && cache.chiSq > bestChiSq + 0.5) ||
553 if (cache.verbose) {
554 *cache.log << MSG::VERBOSE << " revert to bestParameters ";
556 }
557 if (measurementProcessor.calculateFittedTrajectory(cache.iteration)) {
558 measurementProcessor.calculateDerivatives();
559 measurementProcessor.calculateResiduals();
561 cache.convergence = true;
562 }
563 }
564
565 if (forceIteration)
566 cache.convergence = false;
567 }
568 }
569 if (cache.verbose)
571
572
573 if (fitCode && cache.iteration && bestParameters &&
575 (**(measurements.rbegin())).position().perp() >
m_largeRadius) {
576 if (cache.verbose)
577 *cache.log << MSG::VERBOSE <<
" phi instability " <<
endmsg;
580 cache.cutStep = true;
581 cache.convergence = false;
582 fitCode = 0;
583 cache.iteration = 0;
584 }
585 }
586
587
588 if (!fitCode) {
589
590
593 Amg::MatrixX& finalCovariance = cache.fitMatrices->finalCovariance();
594 if (!for_iPatTrack) {
596 measurementProcessor.fieldIntegralUncertainty(*cache.log,
597 finalCovariance);
598 measurementProcessor.propagationDerivatives();
599 }
601
602
603 if (perigeeQuality) {
604
605 cache.chiSq = perigeeQuality->chiSquared() +
606 cache.chiSq * static_cast<double>(cache.numberDoF);
607 cache.numberDoF += perigeeQuality->numberDoF();
608 cache.chiSq /= static_cast<double>(cache.numberDoF);
609 }
610
611
612 cache.fitProbability = 1.;
613 if (cache.numberDoF > 0 && cache.chiSq > 0.) {
614 if (cache.chiSq < 100.) {
616 cache.chiSq * static_cast<double>(cache.numberDoF);
617 cache.fitProbability -=
618 Genfun::CumulativeChiSquare(cache.numberDoF)(
chiSquared);
619 } else {
620 cache.fitProbability = 0.;
621 }
622 }
623
624 if (cache.verbose) {
625 *cache.log << MSG::VERBOSE << " fit converged";
626 if (cache.chiSqWorst > 6.25)
627 *cache.log << " with possible outlier #" << cache.worstMeasurement
628 << " (residual " << std::sqrt(cache.chiSqWorst) << ")";
630 }
631 } else {
632 fitCode = 11;
633 }
634 }
635
636 cache.fitQuality = std::make_unique<FitProcedureQuality>(
637 cache.chiSq, cache.chiSqWorst, cache.fitProbability, fitCode,
638 cache.iteration,
parameters->numberAlignments(), cache.numberDoF,
639 parameters->numberScatterers(), cache.worstMeasurement);
640 if (cache.debug && (for_iPatTrack || fitCode))
642
643 return *cache.fitQuality;
644}
void calculateChiSq(FitProcedure::Cache &cache, std::vector< FitMeasurement * > &measurements) const
const ToolHandle< IIntersector > & chooseIntersector(std::vector< FitMeasurement * > &measurements, const FitParameters ¶meters) const
static Amg::MatrixX * fullCovariance()
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.