163 const double cotTheta =
165 sinTheta = 1. / std::sqrt(1. + cotTheta * cotTheta);
167 sinTheta * cotTheta);
179 if (m->isCluster()) {
181 }
else if (m->isDrift() || m->isPerigee() ||
188 driftDirection = driftDirection.unit();
189 m->minimizationDirection(driftDirection);
191 }
else if (m->isVertex()) {
196 minimizationDirection = minimizationDirection.unit();
197 m->minimizationDirection(minimizationDirection);
199 m->weight() * (
m_cosPhi0 * m->minimizationDirection().y() -
200 m_sinPhi0 * m->minimizationDirection().x()));
201 if (m->is2Dimensional())
202 m->derivative2(
Z0, m->weight2() * m->sensorDirection().z());
203 }
else if (!m->numberDoF()) {
205 }
else if (m->isScatterer()) {
206 unsigned param = m->lastParameter() - 2;
210 m->derivative2(++param, m->weight());
211 }
else if (m->isAlignment()) {
212 unsigned param = m->firstParameter();
213 m->derivative(param, m->weight());
214 m->derivative2(++param, m->weight2());
215 }
else if (m->isEnergyDeposit()) {
218 const double weight = m->weight();
298 if (!(*m).numberDoF())
302 if (!m->isPositionMeasurement()) {
303 if (m->isScatterer())
305 const double phiResidual =
308 m->residual(phiResidual);
309 const double thetaResidual =
311 (*m).residual2(thetaResidual);
313 }
else if ((*m).isAlignment())
315 (*m).residual(-m->weight() *
318 (*m).residual2(-m->weight2() *
322 }
else if (m->isEnergyDeposit()) {
326 const double residual = m->weight() * (E0 - E1 - m->energyLoss());
327 m->residual(residual);
335 const Amg::Vector3D& minimizationDirection = m->minimizationDirection();
339 double residual = m->weight() * minimizationDirection.dot(offset);
340 if (m->alignmentParameter()) {
342 unsigned param = m->alignmentParameter() - 1;
346 m_parameters->alignmentAngle(param) * m->derivative(deriv) +
347 m_parameters->alignmentOffset(param) * m->derivative(deriv + 1);
349 if (m->alignmentParameter2()) {
351 param = m->alignmentParameter2() - 1;
355 m_parameters->alignmentAngle(param) * m->derivative(deriv) +
356 m_parameters->alignmentOffset(param) * m->derivative(deriv + 1);
359 m->residual(residual);
360 if (!m->is2Dimensional())
362 const double residual2 = m->weight2() * m->sensorDirection().dot(offset);
363 m->residual2(residual2);
364 }
else if (m->isDrift() ||
367 double residual = m->weight() * (minimizationDirection.dot(offset) +
368 m->signedDriftDistance());
369 if (m->alignmentParameter()) {
371 unsigned param = m->alignmentParameter() - 1;
375 m_parameters->alignmentAngle(param) * m->derivative(deriv) +
376 m_parameters->alignmentOffset(param) * m->derivative(deriv + 1);
379 if (m->alignmentParameter2()) {
381 param = m->alignmentParameter2() - 1;
385 m_parameters->alignmentAngle(param) * m->derivative(deriv) +
386 m_parameters->alignmentOffset(param) * m->derivative(deriv + 1);
389 m->residual(residual);
393 }
else if (m->isPseudo())
395 const double residual = m->weight() * minimizationDirection.dot(offset);
396 m->residual(residual);
397 if (!m->is2Dimensional())
399 const double residual2 = m->weight2() * m->sensorDirection().dot(offset);
400 m->residual2(residual2);
401 }
else if (m->isVertex()) {
402 const double residual = m->weight() *
403 (minimizationDirection.x() * offset.x() +
404 minimizationDirection.y() * offset.y()) /
405 minimizationDirection.perp();
406 m->residual(residual);
407 if (!m->is2Dimensional())
409 const double residual2 = m->weight2() * m->sensorDirection().dot(offset);
410 m->residual2(residual2);
441 if (startDirection.z() == 0. || endDirection.z() == 0.)
444 const double deflectionPhi = startDirection.x() * endDirection.y() -
445 startDirection.y() * endDirection.x();
446 const double deflectionTheta = startDirection.perp() * endDirection.z() -
447 startDirection.z() * endDirection.perp();
450 const double shiftPhi0 = std::sqrt(covariance(2, 2));
456 sinTheta = 1. / std::sqrt(1. + cotTheta * cotTheta);
457 startDirection =
Amg::Vector3D(sinTheta * cosPhi, sinTheta * sinPhi,
458 sinTheta * cotTheta);
464 const double deltaPhi = startDirection.x() * endDirection.y() -
465 startDirection.y() * endDirection.x() - deflectionPhi;
466 const double deltaTheta = startDirection.perp() * endDirection.z() -
467 startDirection.z() * endDirection.perp() -
469 covariance(3, 3) += deltaTheta * deltaTheta;
470 if (std::abs(deflectionTheta) > 0.0001) {
471 const double deltaQOverP =
472 (deltaTheta / deflectionTheta) *
m_parameters->qOverP();
473 covariance(4, 4) += deltaQOverP * deltaQOverP;
475 if (log.level() < MSG::DEBUG) {
476 log << MSG::VERBOSE << std::setiosflags(std::ios::fixed)
477 <<
" fieldIntegralUncertainty: "
478 <<
" shiftPhi0 " << std::setw(8) << std::setprecision(3) << shiftPhi0
479 <<
" deflection (phi,theta) " << std::setw(8) << std::setprecision(4)
480 << deflectionPhi << std::setw(8) << std::setprecision(4)
481 << deflectionTheta <<
" diff " << std::setw(8)
482 << std::setprecision(4) <<
deltaPhi << std::setw(8)
483 << std::setprecision(4) << deltaTheta <<
endmsg;
488 double shiftD0 = std::sqrt(covariance(0, 0));
489 double shiftZ0 = std::sqrt(covariance(1, 1));
498 const double dPhi = covariance(0, 2) / shiftD0;
502 sinTheta = 1. / std::sqrt(1. + cotTheta * cotTheta);
503 cotTheta -= covariance(1, 3) / (shiftZ0 * sinTheta * sinTheta);
504 startDirection =
Amg::Vector3D(sinTheta * cosPhi, sinTheta * sinPhi,
505 sinTheta * cotTheta);
511 const double deltaPhi = startDirection.x() * endDirection.y() -
512 startDirection.y() * endDirection.x() - deflectionPhi;
513 const double deltaTheta = startDirection.perp() * endDirection.z() -
514 startDirection.z() * endDirection.perp() -
518 covariance(3, 3) += deltaTheta * deltaTheta;
519 if (std::abs(deflectionTheta) > 0.0001) {
520 const double deltaQOverP =
521 (deltaTheta / deflectionTheta) *
m_parameters->qOverP();
522 covariance(4, 4) += deltaQOverP * deltaQOverP;
525 if (log.level() < MSG::DEBUG) {
526 log << MSG::VERBOSE << std::setiosflags(std::ios::fixed)
527 <<
" fieldIntegralUncertainty: "
528 <<
" shiftD0 " << std::setw(8) << std::setprecision(1) << shiftD0
529 <<
" shiftZ0 " << std::setw(8) << std::setprecision(1) << shiftZ0
530 <<
" deflection (phi,theta) " << std::setw(8) << std::setprecision(4)
531 << deflectionPhi << std::setw(8) << std::setprecision(4)
532 << deflectionTheta <<
" diff " << std::setw(8)
533 << std::setprecision(4) <<
deltaPhi << std::setw(8)
534 << std::setprecision(4) << deltaTheta <<
endmsg;
565 double weight = measurement.
weight();
582 if (derivativeFlag != 0) {
598 weight * sensorDirection.cross(
intersection.direction()) /
614 measurement.
derivative(
Phi0, weight * minimizationDirection.dot(offset) /
624 yDistance * weightedProjection.x());
629 unsigned param =
m_parameters->firstScatteringParameter();
630 std::vector<FitMeasurement*>::const_iterator s =
m_scatterers.begin();
634 const double xDistScat =
635 intersection.position().x() - scatteringCentre.position().x();
636 const double yDistScat =
637 intersection.position().y() - scatteringCentre.position().y();
638 const double rDistScat = -(scatteringCentre.direction().
x() * xDistScat +
639 scatteringCentre.direction().y() * yDistScat) /
640 (scatteringCentre.direction().
perp2() *
641 scatteringCentre.direction().perp());
642 measurement.
derivative(param, xDistScat * weightedProjection.y() -
643 yDistScat * weightedProjection.x());
644 measurement.
derivative(++param, weightedProjection.z() * rDistScat);
661 measurement.
derivative(param, weight * distance);
662 measurement.
derivative(++param, weight * projection);
673 measurement.
derivative(param, weight * distance);
674 measurement.
derivative(++param, weight * projection);
681 if (derivativeFlag == 1)
683 weight = measurement.
weight2();
701 -weight * minimizationDirection.cross(
intersection.direction()) /
726 yDistance * weightedProjection.x());
731 unsigned param =
m_parameters->firstScatteringParameter();
732 std::vector<FitMeasurement*>::const_iterator s =
m_scatterers.begin();
736 const double xDistScat =
737 intersection.position().x() - scatteringCentre.position().x();
738 const double yDistScat =
739 intersection.position().y() - scatteringCentre.position().y();
740 const double rDistScat = -(scatteringCentre.direction().
x() * xDistScat +
741 scatteringCentre.direction().y() * yDistScat) /
742 (scatteringCentre.direction().
perp2() *
743 scatteringCentre.direction().perp());
744 measurement.
derivative2(param, xDistScat * weightedProjection.y() -
745 yDistScat * weightedProjection.x());
746 measurement.
derivative2(++param, weightedProjection.z() * rDistScat);
763 if (derivativeFlag != 0) {
764 const double weight = measurement.
weight();
766 const double xDrift = driftDirection.x();
767 const double yDrift = driftDirection.y();
813 Phi0, weight * (xDistance * yDrift - yDistance * xDrift));
816 measurement.
derivative(
Z0, weight * driftDirection.z());
821 unsigned param =
m_parameters->firstScatteringParameter();
822 std::vector<FitMeasurement*>::const_iterator s =
m_scatterers.begin();
826 const double xDistScat =
827 intersection.position().x() - scatteringCentre.position().x();
828 const double yDistScat =
829 intersection.position().y() - scatteringCentre.position().y();
830 const double rDistScat = -(scatteringCentre.direction().
x() * xDistScat +
831 scatteringCentre.direction().y() * yDistScat) /
832 (scatteringCentre.direction().
perp2() *
833 scatteringCentre.direction().perp());
835 param, weight * (xDistScat * yDrift - yDistScat * xDrift));
836 measurement.
derivative(++param, weight * driftDirection.z() * rDistScat);
851 intersection.position().x() - alignmentCentre.position().x();
853 intersection.position().y() - alignmentCentre.position().y();
854 double rDistance = -(alignmentCentre.direction().
x() * xDistance +
855 alignmentCentre.direction().y() * yDistance) /
856 (alignmentCentre.direction().
perp2() *
857 alignmentCentre.direction().perp());
858 measurement.
derivative(param, weight * driftDirection.z() * rDistance);
862 double projection = 0;
864 if (std::abs(surface.
normal().z()) > 0.5) {
865 projection = (driftDirection.x() * surface.
center().x() +
866 driftDirection.y() * surface.
center().y()) /
869 projection = driftDirection.z();
871 measurement.
derivative(++param, weight * projection);
883 intersection.position().x() - alignmentCentre.position().x();
885 intersection.position().y() - alignmentCentre.position().y();
886 rDistance = -(alignmentCentre.direction().
x() * xDistance +
887 alignmentCentre.direction().y() * yDistance) /
888 (alignmentCentre.direction().
perp2() *
889 alignmentCentre.direction().perp());
890 measurement.
derivative(param, weight * driftDirection.z() * rDistance);
895 if (surface.
normal().dot(surface.
center().unit()) < 0.5) {
896 projection = driftDirection.z();
898 projection = (driftDirection.x() * surface.
center().x() +
899 driftDirection.y() * surface.
center().y()) /
902 measurement.
derivative(++param, weight * projection);
908 if (derivativeFlag == 1)
910 const double weight = measurement.
weight2();
912 const double xWire = wireDirection.x();
913 const double yWire = wireDirection.y();
947 weight * (xDistance * yWire - yDistance * xWire));
955 unsigned param =
m_parameters->firstScatteringParameter();
956 std::vector<FitMeasurement*>::const_iterator s =
m_scatterers.begin();
960 const double xDistScat =
961 intersection.position().x() - scatteringCentre.position().x();
962 const double yDistScat =
963 intersection.position().y() - scatteringCentre.position().y();
964 const double rDistScat = -(scatteringCentre.direction().
x() * xDistScat +
965 scatteringCentre.direction().y() * yDistScat) /
966 (scatteringCentre.direction().
perp2() *
967 scatteringCentre.direction().perp());
969 weight * (xDistScat * yWire - yDistScat * xWire));
970 measurement.
derivative2(++param, weight * wireDirection.z() * rDistScat);
980 const Surface* surface =
nullptr;
981 const EventContext& ctx = Gaudi::Hive::currentContext();
983 std::vector<FitMeasurement*>::iterator m =
m_measurements.begin();
984 if ((**m).isVertex()) {
986 std::optional<TrackSurfaceIntersection> newIntersectionSTEP =
991 if (newIntersectionSTEP)
993 (newIntersectionSTEP->position() -
intersection->position()).mag();
996 if (newIntersectionSTEP) {
999 (newIntersectionSTEP->position() -
intersection->position()).mag();
1000 std::cout <<
" iMeasProc 1 distance STEP and Intersector " << dist
1001 <<
" ex dist " << exdist << std::endl;
1003 std::cout <<
" iMeasProc 1 ALARM distance STEP and Intersector "
1004 << dist <<
" ex dist " << exdist << std::endl;
1007 std::cout <<
" iMeasProc 1 ALARM STEP did not intersect! "
1018 surface = (**m).surface();
1029 if ((**m).afterCalo()) {
1035 if ((**m).numberDoF() && (**m).isScatterer())
1041 if ((**m).surface() != surface) {
1043 std::optional<TrackSurfaceIntersection> newIntersectionSTEP =
1048 if (newIntersectionSTEP)
1049 exdist = (newIntersectionSTEP->position() -
intersection->position())
1054 if (newIntersectionSTEP) {
1055 const double dist = 1000. * (newIntersectionSTEP->position() -
1058 std::cout <<
" iMeasProc 2 distance STEP and Intersector " << dist
1059 <<
" ex dist " << exdist << std::endl;
1061 std::cout <<
" iMeasProc 2 ALARM distance STEP and Intersector "
1062 << dist <<
" ex dist " << exdist << std::endl;
1065 std::cout <<
" iMeasProc 2 ALARM STEP did not intersect! "
1076 surface = (**m).surface();
1085 if ((**m).isEnergyDeposit() || (**m).isScatterer()) {
1087 if ((**m).numberDoF()) {
1088 if ((**m).isEnergyDeposit())
1106 if ((**m).isScatterer())
1109 const double sinDeltaPhi = std::sin(
m_parameters->scattererPhi(nScat));
1110 const double cosDeltaPhi = std::sqrt(1. - sinDeltaPhi * sinDeltaPhi);
1111 const double sinDeltaTheta = std::sin(
m_parameters->scattererTheta(nScat));
1112 double tanDeltaTheta = sinDeltaTheta;
1113 if (std::abs(sinDeltaTheta) < 1.)
1114 tanDeltaTheta /= std::sqrt(1. - sinDeltaTheta * sinDeltaTheta);
1116 trackDirection /= trackDirection.perp();
1117 const double cosPhi = trackDirection.x() * cosDeltaPhi -
1118 trackDirection.y() * sinDeltaPhi;
1119 const double sinPhi = trackDirection.y() * cosDeltaPhi +
1120 trackDirection.x() * sinDeltaPhi;
1121 const double cotTheta = (trackDirection.z() - tanDeltaTheta) /
1122 (1. + trackDirection.z() * tanDeltaTheta);
1124 trackDirection = trackDirection.unit();
1137 const double loss = (**m).energyLoss() * std::abs(
qOverP);
1138 qOverP *= 1. + loss + loss * loss + loss * loss * loss;
1140 double momentum = 1. /
qOverP;
1141 if (momentum > 0.) {
1142 momentum -= (**m).energyLoss();
1144 momentum += (**m).energyLoss();