15#include "GaudiKernel/SystemOfUnits.h"
36 const std::string& name,
37 const IInterface* parent)
54 declareInterface<IMaterialAllocator>(
this);
68 "Maximum number of permitted WARNING messages per message type.");
76 "leadingSpectrometerTSOS: missing TrackingGeometrySvc - no leading "
77 "material will be added");
79 1,
"indetMaterial: extrapolateM finds no material on track");
82 "spectrometerMaterial: missing TrackingGeometrySvc - no spectrometer "
85 "spectrometerMaterial: did not find MS entrance "
86 "surface - no MS material taken into account");
87 m_messageHelper->setMessage(4,
"spectrometerMaterial: failed extrapolation");
89 5,
"spectrometerMaterial: extrapolateM finds no material on track");
121 return StatusCode::SUCCESS;
127 return StatusCode::SUCCESS;
131 std::vector<FitMeasurement*>& measurements,
134 const EventContext& ctx = Gaudi::Hive::currentContext();
136 if (measurements.front()->isVertex()) {
156 bool energyGain =
false;
157 bool haveDelimiter =
false;
158 std::optional<TrackSurfaceIntersection>
intersection = std::nullopt;
159 int leadingScatterers = 0;
161 for (
auto* measurement : measurements) {
162 if ((*measurement).isMaterialDelimiter()) {
163 haveDelimiter =
true;
164 }
else if ((*measurement).isScatterer()) {
166 if (!(*measurement).numberDoF()) {
168 leadingScatterer = measurement;
170 if (std::abs(1. / (*measurement).qOverP()) > p)
178 if (haveDelimiter && !leadingScatterers) {
180 haveDelimiter =
false;
182 const Surface* firstMeasurementSurface =
nullptr;
184 std::vector<Trk::FitMeasurement*> leadingOutliers;
185 const Surface* surface =
nullptr;
186 for (
auto* measurement : measurements) {
187 if ((*measurement).isMaterialDelimiter()) {
188 haveDelimiter =
true;
189 endPosition = (*measurement).position();
190 surface = (*measurement).surface();
191 }
else if ((*measurement).isPositionMeasurement()) {
192 if ((*measurement).isOutlier()) {
193 if (!firstMeasurementSurface)
194 leadingOutliers.push_back(measurement);
197 firstMeasurementSurface = (*measurement).surface();
205 }
else if ((*measurement).isScatterer()) {
209 if (std::abs(1. / (*measurement).qOverP()) > p)
221 bool haveMaterial =
false;
222 const std::vector<const TrackStateOnSurface*>*
indetMaterial =
nullptr;
226 if (
msgLvl(MSG::VERBOSE)) {
230 " addLeadingMaterial: using extrapolateM from distance "
231 << direction.dot(fitParameters.
position() - startPosition));
237 particleHypothesis, garbage);
241 std::vector<const TrackStateOnSurface*>::const_reverse_iterator
r =
245 if (!(**r).trackParameters() || !(**r).materialEffectsOnTrack() ||
247 (**r).trackParameters()->position() - endPosition) > 0.)
254 haveDelimiter =
false;
258 if (haveDelimiter && !haveMaterial) {
261 " no leading material found with forward extrapolation"
262 <<
", try again with back extrapolation ");
268 std::vector<const TrackStateOnSurface*>* indetMaterialF =
nullptr;
269 const std::vector<const TrackStateOnSurface*>* indetMaterialR =
nullptr;
283 if (indetMaterialR && !indetMaterialR->empty()) {
284 indetMaterialF =
new std::vector<const TrackStateOnSurface*>;
285 indetMaterialF->reserve(indetMaterialR->size());
287 std::vector<const TrackStateOnSurface*>::const_reverse_iterator
r =
288 indetMaterialR->rbegin();
289 for (;
r != indetMaterialR->rend(); ++
r) {
290 indetMaterialF->push_back(*
r);
293 for (
r = indetMaterialF->rbegin();
r != indetMaterialF->rend(); ++
r) {
295 if (!(**r).trackParameters() || !(**r).materialEffectsOnTrack() ||
297 (**r).trackParameters()->position() - endPosition) > 0.)
303 indetMaterialF =
nullptr;
306 delete indetMaterialR;
313 std::vector<const TrackStateOnSurface*>::const_reverse_iterator
r =
317 if (!(**r).trackParameters() || !(**r).materialEffectsOnTrack() ||
318 intersection->direction().dot((**r).trackParameters()->position() -
326 (**r).materialEffectsOnTrack());
327 if (materialEffects) {
333 if (leadingScatterers++ || !firstMeasurementSurface) {
335 std::optional<TrackSurfaceIntersection>
const newIntersectionSTEP =
337 ctx, (**r).trackParameters()->associatedSurface(),
341 (**r).trackParameters()->associatedSurface(), *
intersection,
347 ctx, (**r).trackParameters()->associatedSurface(),
350 (**r).trackParameters()->associatedSurface(),
367 for (std::vector<Trk::FitMeasurement*>::const_iterator l =
368 leadingOutliers.begin();
369 l != leadingOutliers.end(); ++l) {
370 leadingOutlier = leadingOutliers.back();
372 std::remove(measurements.begin(), measurements.end(), *l),
376 (**r).materialEffectsOnTrack()->thicknessInX0(), -eLoss,
379 firstMeasurementSurface);
380 leadingScatterer = leadingMeas;
387 if (leadingOutlier) {
388 const double radius =
394 leadingOutliers.pop_back();
395 measurements.insert(measurements.begin(), leadingOutlier);
396 if (!leadingOutliers.empty()) {
397 leadingOutlier = leadingOutliers.back();
399 leadingOutlier =
nullptr;
406 measurements.insert(measurements.begin(), leadingMeas);
409 if (materialEffects) {
422 std::optional<TrackSurfaceIntersection>
const newIntersectionSTEP =
447 leadingCovariance.setZero();
448 if (leadingScatterers) {
449 double leadingScattering = 0.;
450 double previousScattering = 0.;
451 double leadingX0Integral = 0.;
452 std::vector<Trk::FitMeasurement*>::reverse_iterator m =
453 measurements.rbegin();
454 while (*m != leadingScatterer)
456 for (; m != measurements.rend(); ++m) {
457 if (!(**m).isScatterer())
461 if (!materialEffects)
465 leadingX0Integral += (**m).materialEffects()->
thicknessInX0();
467 leadingScattering = leadingX0Integral * logTerm * logTerm;
468 const double scatteringAngle =
470 std::sqrt(leadingScattering - previousScattering);
471 previousScattering = leadingScattering;
472 (**m).scatteringAngle(scatteringAngle, leadingX0Integral);
475 double angleSquared = 1. / (**m).weight();
479 const double sinThetaSquared =
481 angleSquared *= angleSquared / sinThetaSquared;
484 leadingCovariance(0, 0) +=
deltaR *
deltaR * angleSquared;
485 leadingCovariance(0, 2) -=
deltaR * angleSquared;
486 leadingCovariance(2, 0) = leadingCovariance(0, 2);
487 leadingCovariance(2, 2) += angleSquared;
490 leadingCovariance(1, 1) +=
492 leadingCovariance(1, 3) +=
deltaR * angleSquared;
493 leadingCovariance(3, 1) = leadingCovariance(1, 3);
494 leadingCovariance(3, 3) += angleSquared * sinThetaSquared;
501 qOverP, leadingCovariance);
506 qOverP, leadingCovariance);
518 std::vector<FitMeasurement*>& measurements,
522 indetMaterial(measurements, particleHypothesis, startParameters, garbage);
525 startParameters, garbage);
528 if (
msgLvl(MSG::VERBOSE)) {
535 std::vector<FitMeasurement*>& measurements)
const {
538 bool integrate =
false;
539 double previousScattering = 0.;
540 double X0Integral = 0.;
542 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
545 while (!(**m).isPositionMeasurement() || (**m).isOutlier())
548 for (; m != measurements.end(); ++m) {
549 if (integrate && (**m).isPositionMeasurement() && !(**m).isOutlier()) {
552 previousScattering = 0.;
555 if ((**m).isScatterer()) {
558 std::vector<Trk::FitMeasurement*>::iterator
next = m;
559 if (++
next != measurements.end() && !(**next).hitOnTrack() &&
560 (**next).isPositionMeasurement() && !(**next).isOutlier()) {
564 .mag() < 1. * Gaudi::Units::mm)
570 previousScattering = 0.;
576 double thicknessInX0 = (**m).materialEffects()->thicknessInX0();
577 if ((**m).materialEffects()->thicknessInX0() < 0.) {
579 << (**m).materialEffects()->thicknessInX0() <<
" "
580 << *(**m).materialEffects());
581 thicknessInX0 = 1e-6;
583 X0Integral += thicknessInX0;
585 if (X0Integral > 0.) {
589 << X0Integral <<
" thicknessInX0 "
590 << (**m).materialEffects()->thicknessInX0() <<
" "
591 << *(**m).materialEffects());
594 const double scattering = X0Integral * logTerm * logTerm;
597 previousScattering = scattering;
599 (**m).scatteringAngle(
angle, X0Integral);
604std::vector<const TrackStateOnSurface*>*
607 const EventContext& ctx = Gaudi::Hive::currentContext();
609 if (!spectrometerEntrance)
615 std::unique_ptr<const TrackParameters>
const entranceParameters(
619 if (!entranceParameters) {
621 std::setiosflags(std::ios::fixed)
622 <<
"leadingSpectrometerTSOS: no material found from RZ" << std::setw(9)
623 << std::setprecision(3) << spectrometerParameters.
position().perp()
624 << std::setw(10) << std::setprecision(3)
625 << spectrometerParameters.
position().z() <<
" with p " << std::setw(8)
626 << std::setprecision(3)
627 << spectrometerParameters.
momentum().mag() / Gaudi::Units::GeV);
631 const Surface& entranceSurface = entranceParameters->associatedSurface();
632 std::unique_ptr<const std::vector<const TrackStateOnSurface*>>
637 if (!extrapolatedTSOS || extrapolatedTSOS->empty() ||
638 !extrapolatedTSOS->front()->trackParameters()) {
640 std::setiosflags(std::ios::fixed)
641 <<
"leadingSpectrometerTSOS: no material found from RZ" << std::setw(9)
642 << std::setprecision(3) << spectrometerParameters.
position().perp()
643 << std::setw(10) << std::setprecision(3)
644 << spectrometerParameters.
position().z() <<
" with p " << std::setw(8)
645 << std::setprecision(3)
646 << spectrometerParameters.
momentum().mag() / Gaudi::Units::GeV);
650 std::vector<std::unique_ptr<FitMeasurement>> leadingMeasurements;
651 std::unique_ptr<std::vector<const TrackStateOnSurface*>> leadingTSOS =
652 std::make_unique<std::vector<const TrackStateOnSurface*>>();
653 leadingTSOS->reserve(extrapolatedTSOS->size());
654 double outgoingEnergy = spectrometerParameters.
momentum().mag();
656 for (
const auto* s : *extrapolatedTSOS) {
657 if (!(*s).trackParameters())
659 std::unique_ptr<FitMeasurement> measurement(
661 outgoingEnergy = (*s).trackParameters()->momentum().mag();
664 leadingMeasurements.emplace(leadingMeasurements.begin(),
665 std::move(measurement));
667 leadingTSOS->push_back((*s).clone());
672 for (
const auto& m : leadingMeasurements)
674 nullptr,
nullptr, m->materialEffects()->uniqueClone()));
679 if (
msgLvl(MSG::VERBOSE) && !leadingTSOS->empty()) {
681 std::setiosflags(std::ios::fixed)
682 <<
"leadingSpectrometerTSOS: from RZ" << std::setw(9)
683 << std::setprecision(3) << spectrometerParameters.
position().perp()
684 << std::setw(10) << std::setprecision(3)
685 << spectrometerParameters.
position().z() <<
" with p " << std::setw(8)
686 << std::setprecision(3)
687 << spectrometerParameters.
momentum().mag() / Gaudi::Units::GeV);
690 return leadingTSOS.release();
694 std::vector<FitMeasurement*>& measurements,
Amg::Vector3D startDirection,
698 << startDirection.phi() <<
" theta "
699 << startDirection.theta());
704 std::vector<std::pair<double, FitMeasurement*>> measurementOrder;
705 std::vector<std::pair<double, FitMeasurement*>> originalOrder;
706 for (
auto* measurement : measurements) {
707 double distance = startDirection.dot(
710 if (distance < previousDistance)
713 measurementOrder.emplace_back(distance, measurement);
714 originalOrder.emplace_back(distance, measurement);
716 std::sort(measurementOrder.begin(), measurementOrder.end(),
719 originalOrder.begin();
720 bool shouldReorder =
false;
722 measurements.erase(measurements.begin(), measurements.end());
724 for (std::vector<std::pair<double, FitMeasurement*>>
::const_iterator order =
725 measurementOrder.begin();
726 order != measurementOrder.end(); ++order, ++orig) {
728 measurements.push_back((*order).second);
733 if ((*order).second == (*orig).second ||
736 shouldReorder =
true;
744 ATH_MSG_DEBUG(
" measurement reordering would improve the track fit ");
750 std::vector<FitMeasurement*>& measurements,
FitParameters& parameters,
755 for (
auto& measurement : measurements) {
756 if (!(*measurement).isMaterialDelimiter())
759 const double distance =
761 (*measurement).position())
764 std::setiosflags(std::ios::fixed)
765 << std::setw(5) << ++n << std::setw(10) << std::setprecision(3)
766 << distance <<
" " << (*measurement).type() << std::setw(10)
767 << std::setprecision(1)
769 << std::setw(9) << std::setprecision(4)
771 << std::setw(10) << std::setprecision(1)
779 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
780 for (; m != measurements.end(); ++m) {
783 if ((**m).materialEffects())
785 if ((**m).isMaterialDelimiter())
789 if ((**m).isMaterialDelimiter())
797 MsgStream log(msgSvc(), name());
799 parameters.trackParameters(log, *measurements.back());
802 Amg::VectorX parameterVector = trackParameters->parameters();
803 const double Emax = 50000.;
807 if (std::abs(parameterVector[
Trk::qOverP]) * Emax < 1)
815 .createUniqueTrackParameters(
821 for (std::vector<Trk::FitMeasurement*>::reverse_iterator
r =
822 measurements.rbegin();
823 r != measurements.rend(); ++
r) {
824 if (!(**r).isMaterialDelimiter())
842 std::pair<FitMeasurement*, FitMeasurement*>
const fms =
853 delete trackParameters;
855 MsgStream log(msgSvc(), name());
856 trackParameters = parameters.trackParameters(log, **
r);
859 delete trackParameters;
862 for (m = measurements.begin(); m != measurements.end(); ++m) {
863 if (!(**m).isMaterialDelimiter())
866 std::vector<Trk::FitMeasurement*>::iterator
const n = m;
868 measurements.erase(n);
875 std::vector<FitMeasurement*>& measurements)
const {
885 double previousDistance = 0.;
891 double referencePhi = 0.;
892 for (std::vector<FitMeasurement*>::iterator m = measurements.begin();
893 m != measurements.end(); ++m) {
895 if (!(**m).isPositionMeasurement() || (**m).isPseudo())
905 bool preBreak =
false;
906 bool postBreak =
false;
907 double distance = 0.;
913 referencePhi = position.phi();
914 startDirection = referenceDirection;
915 startPosition = referencePosition;
920 distance = referenceDirection.dot(
922 if (((**m).isDrift() && !
previous->isDrift()) ||
923 (!(**m).isDrift() &&
previous->isDrift()) ||
933 if (!(preBreak || postBreak)) {
935 previousDistance = distance;
946 m = measurements.insert(++m, delimiter);
947 while (*m != current)
953 offset = 0.5 * (previousDistance - distance);
957 m = measurements.insert(m, delimiter);
961 previousDistance = 0.;
964 referencePhi = position.phi();
971 const std::vector<const TrackStateOnSurface*>* material,
975 garbage.push_back(std::unique_ptr<const TrackStateOnSurface>(m));
981const std::vector<const TrackStateOnSurface*>*
983 const ToolHandle<IExtrapolator>& extrapolator,
987 const EventContext& ctx = Gaudi::Hive::currentContext();
990 const std::vector<const TrackStateOnSurface*>* TGMaterial =
991 extrapolator->extrapolateM(ctx, parameters, surface, dir, boundsCheck,
994 if (!TGMaterial || TGMaterial->empty())
997 std::vector<const TrackStateOnSurface*>* duplicates =
nullptr;
998 std::vector<const TrackStateOnSurface*>* material =
999 new std::vector<const TrackStateOnSurface*>;
1000 material->reserve(TGMaterial->size());
1001 std::vector<const TrackStateOnSurface*>::const_iterator tg =
1002 TGMaterial->begin();
1003 material->push_back(*tg);
1005 for (; tg != TGMaterial->end(); ++tg) {
1007 double separation = 0.;
1010 (**tg).trackParameters()->
position())
1013 if (separation > 0.001 * Gaudi::Units::mm) {
1014 material->push_back(*tg);
1017 std::setiosflags(std::ios::fixed)
1018 <<
" duplicate: RZ" << std::setw(9) << std::setprecision(3)
1019 << (**tg).trackParameters()->position().perp() << std::setw(10)
1020 << std::setprecision(3) << (**tg).trackParameters()->position().z());
1022 duplicates =
new std::vector<const TrackStateOnSurface*>;
1023 duplicates->push_back(*tg);
1034 std::vector<FitMeasurement*>& measurements,
1037 const EventContext& ctx = Gaudi::Hive::currentContext();
1042 10. * Gaudi::Units::mm / startParameters.
momentum().unit().perp();
1045 double endIndetDistance = 0.;
1052 std::unique_ptr<AtaPlane> newParameters;
1054 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1055 if ((**m).isVertex())
1057 for (; m != measurements.end(); ++m) {
1058 if ((**m).isOutlier())
1062 if ((**m).isScatterer()) {
1067 if (!(**m).isPositionMeasurement())
1079 std::optional<TrackSurfaceIntersection>
const newIntersectionSTEP =
1109 newParameters = std::make_unique<AtaPlane>(
1112 parameters = newParameters.get();
1119 const double distance = startDirection.dot(
1121 if (!endIndetMeasurement || distance > endIndetDistance) {
1122 endIndetDistance = distance;
1123 endIndetMeasurement = *m;
1129 if (!endIndetMeasurement) {
1133 ATH_MSG_DEBUG(
" indetMaterial: ALARM no material found on track");
1138 startDirection = (endPosition - startPosition).
unit();
1140 startDirection.dot(endPosition - startPosition) +
tolerance;
1142 << endIndetDistance);
1143 const std::vector<const TrackStateOnSurface*>*
indetMaterial =
1146 false, particleHypothesis, garbage);
1155 std::vector<const Surface*> surfaces;
1157 std::vector<const TrackStateOnSurface*>::const_iterator indetMaterialEnd =
1160 for (std::vector<const TrackStateOnSurface*>::const_iterator s =
1163 if ((**s).trackParameters()) {
1164 if (startDirection.dot((**s).trackParameters()->position() -
1165 startPosition) < endIndetDistance) {
1166 indetMaterialEnd = s;
1171 <<
" trailing TSOS (after last measurement)");
1186 if (
msgLvl(MSG::VERBOSE)) {
1187 double p1 =
indetMaterial->front()->trackParameters()->momentum().mag();
1189 for (std::vector<const TrackStateOnSurface*>::const_iterator s =
1191 s != indetMaterialEnd; ++s) {
1192 if (!(**s).trackParameters())
1194 const double distance = startDirection.dot((**s).trackParameters()->position() -
1197 double thickness = 0.;
1200 (**s).materialEffectsOnTrack());
1201 if ((**s).materialEffectsOnTrack()) {
1202 if (materialEffects)
1204 thickness = (**s).materialEffectsOnTrack()->thicknessInX0();
1206 const double p2 = (**s).trackParameters()->momentum().mag();
1208 std::setiosflags(std::ios::fixed)
1209 <<
" material: RZ" << std::setw(9) << std::setprecision(3)
1210 << (**s).trackParameters()->position().perp() << std::setw(10)
1211 << std::setprecision(3) << (**s).trackParameters()->position().z()
1212 <<
" distance " << std::setw(10) << std::setprecision(3) << distance
1213 <<
" pt " << std::setw(8) << std::setprecision(3)
1214 << (**s).trackParameters()->momentum().perp() / Gaudi::Units::GeV
1215 <<
" X0thickness " << std::setw(8) << std::setprecision(4)
1216 << thickness <<
" deltaE " << std::setw(8) << std::setprecision(4)
1217 << deltaE <<
" diffP " << std::setw(8) << std::setprecision(4)
1228 m = measurements.begin();
1229 std::vector<const TrackStateOnSurface*>::const_iterator s =
1231 for (; m != measurements.end(); ++m) {
1232 if (*m == endIndetMeasurement || s == indetMaterialEnd)
1234 if (!leadingDelimiter && (**m).
isOutlier())
1239 double closestDistance = direction.dot(position - startPosition);
1242 const Surface* materialSurface =
nullptr;
1245 for (; s != indetMaterialEnd; ++s) {
1247 (**s).materialEffectsOnTrack()) ||
1248 !(**s).trackParameters())
1250 nextMomentum = (**s).trackParameters()->momentum();
1251 nextPosition = (**s).trackParameters()->position();
1252 const double distance = direction.dot(nextPosition - position);
1255 if (distance > closestDistance)
1261 if (distance > 0.) {
1263 const double nextDistance = direction.dot(
1264 (**s).trackParameters()->position() - (**m).position());
1266 if (std::abs(nextDistance) < distance && distance >
tolerance) {
1269 materialSurface =
nullptr;
1272 closestDistance = distance;
1274 closestDistance = -distance;
1279 if (!leadingDelimiter && materialSurface)
1280 surfaces.push_back(materialSurface);
1283 (**s).materialEffectsOnTrack());
1284 materialParameters = (**s).trackParameters();
1289 if (!materialSurface)
1293 if (!surfaces.empty() && materialSurface == surfaces.back())
1299 if (!leadingDelimiter) {
1300 position = 0.5 * (materialParameters->
position() + nextPosition);
1301 direction = (materialParameters->
momentum() + nextMomentum).unit();
1304 while (*m != endIndetMeasurement &&
1308 m = measurements.insert(m, leadingDelimiter);
1309 surfaces.push_back(materialSurface);
1318 const std::bitset<MaterialEffectsBase::NumberOfMaterialEffectsTypes>
1320 std::unique_ptr<Trk::EnergyLoss> energyLoss =
nullptr;
1322 energyLoss = std::unique_ptr<Trk::EnergyLoss>(
1327 *(**m).surface(), typePattern);
1329 if (++m == measurements.end())
1331 m = measurements.insert(
1336 (**m).qOverP(materialParameters->parameters()[
Trk::qOverP]);
1337 (**m).setMaterialEffectsOwner();
1338 surfaces.push_back(materialSurface);
1342 m = measurements.begin();
1345 << measurements.size() <<
" surfaces.size() "
1346 << surfaces.size() <<
" indetMaterial->size() "
1348 std::vector<const Surface*>::const_iterator
r = surfaces.begin();
1349 for (s =
indetMaterial->begin(); s != indetMaterialEnd; ++s) {
1350 if (!(**s).trackParameters() || !(**s).materialEffectsOnTrack())
1353 if (
r != surfaces.end() &&
1354 **
r == (**s).trackParameters()->associatedSurface()) {
1359 const double distance =
1360 startDirection.dot((**s).trackParameters()->position() - startPosition);
1363 << startPosition.z());
1365 " (**m).intersection(FittedTrajectory).position() measurement "
1370 " (**s).trackParameters()->position() material surface position "
1372 << (**s).trackParameters()->position().perp() <<
" z "
1373 << (**s).trackParameters()->position().z());
1376 bool endIndet =
false;
1380 if (*m == endIndetMeasurement) {
1381 if (*m != measurements.back()) {
1390 if (*m != measurements.back()) {
1396 <<
" (**m).intersection(FittedTrajectory).position() "
1397 "measurement position r "
1405 " im " << im <<
" distance measurement "
1406 << startDirection.dot(
1410 " (**m).intersection(FittedTrajectory).position() measurement position "
1415 m = measurements.insert(
1418 (**s).trackParameters()->position()));
1420 (**s).trackParameters()->position(),
1421 (**s).trackParameters()->momentum().unit(), 0.);
1423 (**m).qOverP((**s).trackParameters()->parameters()[
Trk::qOverP]);
1429 m = measurements.begin();
1431 for (; m != measurements.end(); ++m) {
1432 if (!leadingDelimiter && (**m).
isOutlier())
1437 ATH_MSG_VERBOSE(
" im " << im <<
" position R " << position.perp() <<
" z "
1447std::pair<FitMeasurement*, FitMeasurement*>
1449 const std::vector<const TrackStateOnSurface*>& material,
1450 std::vector<FitMeasurement*>& ,
1453 ATH_MSG_INFO(
"segment material aggregation " << material.size());
1456 if (material.empty())
1457 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1461 int adjacentScatterers = 0;
1462 std::vector<FitMeasurement*> aggregateScatterers;
1463 bool hasReferencePosition =
false;
1465 bool const haveAggregation =
false;
1468 for (std::vector<const TrackStateOnSurface*>::const_reverse_iterator tsos =
1470 tsos != material.rend(); ++tsos) {
1471 if (!(**tsos).trackParameters() || !(**tsos).materialEffectsOnTrack()){
1474 ++adjacentScatterers;
1475 if (!hasReferencePosition) {
1476 referencePosition =
Amg::Vector3D((**tsos).trackParameters()->position());
1477 hasReferencePosition =
true;
1479 const double distance =
1480 ((**tsos).trackParameters()->position() - referencePosition).mag();
1481 const double weight = (**tsos).materialEffectsOnTrack()->thicknessInX0();
1483 ATH_MSG_INFO(
" material position " << (**tsos).trackParameters()->position()
1484 <<
" distance " << distance
1485 <<
" thickness " << 100. * weight);
1489 if (adjacentScatterers < 3) {
1493 if (haveAggregation) {
1496 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1501 std::vector<FitMeasurement*>& measurements,
double particleMass)
const {
1518 int adjacentScatterers = 0;
1519 std::vector<FitMeasurement*> aggregateScatterers;
1520 bool haveAggregation =
false;
1521 bool makeAggregation =
false;
1522 double maxDistance = 0.;
1525 double totalDistance = 0.;
1526 double totalDistanceSq = 0.;
1527 double totalEnergyDeposit = 0.;
1528 double totalThickness = 0.;
1529 std::vector<FitMeasurement*>::reverse_iterator start;
1530 std::vector<FitMeasurement*>::reverse_iterator
previous =
1531 measurements.rbegin();
1532 for (std::vector<FitMeasurement*>::reverse_iterator m = measurements.rbegin();
1533 m != measurements.rend(); ++m) {
1534 if ((**m).isScatterer())
1535 aggregateScatterers.push_back(*m);
1537 if (!adjacentScatterers)
1539 makeAggregation =
true;
1544 else if (adjacentScatterers) {
1545 if ((**m).isScatterer()) {
1548 const double distance =
1549 std::abs(referenceDirection.dot(position - referencePosition));
1550 if (distance < maxDistance) {
1551 ++adjacentScatterers;
1552 const double weight = (**m).radiationThickness();
1553 totalDistance += weight * distance;
1554 totalDistanceSq += weight * distance * distance;
1555 totalEnergyDeposit += (**m).energyLoss();
1556 totalThickness += weight;
1557 if (*m == measurements.front())
1558 makeAggregation =
true;
1564 }
else if (adjacentScatterers > 1) {
1565 makeAggregation =
true;
1567 adjacentScatterers = 0;
1569 }
else if (!(**m).isMaterialDelimiter()) {
1572 }
else if (adjacentScatterers > 1) {
1573 makeAggregation =
true;
1575 adjacentScatterers = 0;
1579 if (makeAggregation) {
1599 const double meanDistance = totalDistance / totalThickness;
1600 double rmsDistance = 0.;
1601 const double meanSquare =
1602 totalDistanceSq / totalThickness - meanDistance * meanDistance;
1603 if (meanSquare > 0.)
1604 rmsDistance = std::sqrt(meanSquare);
1605 const double gap = 2. * rmsDistance;
1607 const double distance1 = meanDistance - rmsDistance;
1608 double distance2 = meanDistance + rmsDistance;
1610 distance2 = meanDistance;
1613 const double distance =
1614 std::abs(referenceDirection.dot(position - referencePosition));
1625 if (distance2 > distance || distance1 < 0.) {
1631 double previousDistance = 0.;
1632 haveAggregation =
true;
1634 for (std::vector<Trk::FitMeasurement*>::reverse_iterator s = start;
1635 s != measurements.rend(); ++s) {
1636 if (!(**s).isScatterer())
1640 const double distance =
1641 std::abs(referenceDirection.dot(position - referencePosition));
1642 if (!measurement1 && distance > distance1 &&
1645 const double separation = distance - previousDistance;
1646 const double fractionAfter =
1647 (distance1 - previousDistance) / separation;
1648 const double fractionBefore = (distance - distance1) / separation;
1658 position = fractionBefore *
1667 const double qOverP = fractionBefore * before->
qOverP() +
1668 fractionAfter * after->
qOverP();
1670 0.5 * totalThickness, -0.5 * totalEnergyDeposit, particleMass,
1671 position, direction,
qOverP);
1674 if (distance > distance2) {
1676 const double separation = distance - previousDistance;
1677 const double fractionAfter =
1678 (distance2 - previousDistance) / separation;
1679 const double fractionBefore = (distance - distance2) / separation;
1689 position = fractionBefore *
1698 const double qOverP = fractionBefore * before->
qOverP() +
1699 fractionAfter * after->
qOverP();
1702 0.5 * totalThickness, -0.5 * totalEnergyDeposit,
1703 particleMass, position, direction,
qOverP);
1706 totalThickness, -totalEnergyDeposit, particleMass, position,
1709 bool keepCurrentMeas =
false;
1710 if ((**m).isScatterer() && *m != measurements.front()) {
1711 keepCurrentMeas =
true;
1712 aggregateScatterers.pop_back();
1714 while (adjacentScatterers--) {
1715 aggregateScatterers.back()->setOutlier();
1716 aggregateScatterers.pop_back();
1719 aggregateScatterers.push_back(measurement1);
1721 aggregateScatterers.push_back(measurement2);
1722 if (keepCurrentMeas)
1723 aggregateScatterers.push_back(*m);
1724 measurement1 =
nullptr;
1725 measurement2 =
nullptr;
1729 previousDistance = distance;
1733 adjacentScatterers = 0;
1734 makeAggregation =
false;
1738 if ((**m).isScatterer() && !adjacentScatterers &&
1740 adjacentScatterers = 1;
1741 const double weight = (**m).radiationThickness();
1744 referenceDirection =
1747 const double distance =
1748 std::abs(referenceDirection.dot(position - referencePosition));
1749 maxDistance = distance + 2. * Gaudi::Units::meter;
1751 totalDistance = weight * distance;
1752 totalDistanceSq = weight * distance * distance;
1753 totalEnergyDeposit = (**m).energyLoss();
1754 totalThickness = weight;
1765 delete measurement1;
1770 if (haveAggregation) {
1773 referenceDirection =
1774 (referencePosition -
1777 std::vector<Trk::FitMeasurement*>::reverse_iterator s =
1778 aggregateScatterers.rbegin();
1781 double scattererDistance =
1782 std::abs(referenceDirection.dot(scattererPosition - referencePosition));
1783 for (std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1784 m != measurements.end(); ) {
1787 const double distance =
1788 std::abs(referenceDirection.dot(position - referencePosition));
1789 while (distance <= scattererDistance && s != aggregateScatterers.rend()) {
1790 m = measurements.insert(m, *s);
1792 if (++s != aggregateScatterers.rend()) {
1794 scattererDistance = std::abs(
1795 referenceDirection.dot(scattererPosition - referencePosition));
1798 if ((**m).isScatterer()) {
1800 if ((**m).isOutlier())
1803 m = measurements.erase(m);
1812 if (
msgLvl(MSG::VERBOSE)) {
1819 for (
auto* measurement : measurements) {
1822 const double distance = std::abs(startDirection.dot(position - startPosition));
1823 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed) << std::setw(5)
1824 << ++n << std::setw(10) << std::setprecision(3)
1825 << distance <<
" " << (*measurement).type();
1826 if ((*measurement).isOutlier()) {
1827 msg() <<
" outlier ";
1828 }
else if ((*measurement).materialEffects()) {
1829 msg() << std::setw(8) << std::setprecision(3)
1830 << (*measurement).materialEffects()->thicknessInX0() <<
" ";
1834 if (!(*measurement).isMaterialDelimiter()) {
1835 msg() << std::setw(10) << std::setprecision(1)
1836 << (*measurement).position().perp() << std::setw(9)
1837 << std::setprecision(4) << (*measurement).position().phi()
1838 << std::setw(10) << std::setprecision(1)
1839 << (*measurement).position().z();
1846 bool energyGain =
false;
1847 for (
auto& measurement : measurements) {
1848 if ((*measurement).materialEffects() && (*measurement).numberDoF() &&
1849 (*measurement).energyLoss() < 0.)
1854 for (
auto& measurement : measurements) {
1855 if ((*measurement).materialEffects())
1856 (*measurement).setEnergyGain();
1863 double particleMass) {
1871 double qOverP = 1. / outgoingEnergy;
1875 return new FitMeasurement(thicknessInX0, deltaE, particleMass, position,
1880 std::vector<FitMeasurement*>& measurements)
const {
1882 "measurements and material: distance X0 deltaE E "
1884 <<
" R phi Z DoF phi theta");
1886 if (measurements.empty())
1889 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1890 while (m != measurements.end() && !(**m).isPositionMeasurement())
1892 if (m == measurements.end())
1893 m = measurements.begin();
1898 int leadingMaterial = 0;
1899 double leadingX0 = 0.;
1901 double leadingELoss = 0.;
1902 double sumELoss = 0.;
1904 for (
auto& measurement : measurements) {
1905 const double distance =
1908 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed) << std::setw(5)
1909 << ++n <<
" " << (*measurement).type() << std::setw(11)
1910 << std::setprecision(3) << distance;
1911 if ((*measurement).isOutlier()) {
1912 msg() <<
" outlier " << std::setw(44);
1913 }
else if ((*measurement).materialEffects()) {
1917 (*measurement).materialEffects());
1918 if (materialEffects && materialEffects->
energyLoss())
1920 if ((*measurement).isEnergyDeposit())
1922 msg() << std::setw(10) << std::setprecision(3)
1923 << (*measurement).materialEffects()->thicknessInX0() << std::setw(9)
1924 << std::setprecision(1) << deltaE <<
" ";
1925 if (distance > 0.) {
1927 sumX0 += (*measurement).materialEffects()->thicknessInX0();
1931 leadingX0 += (*measurement).materialEffects()->thicknessInX0();
1932 leadingELoss -= deltaE;
1935 if ((*measurement).qOverP()) {
1936 msg() << std::setw(11) << std::setprecision(4)
1937 << 1. / std::abs((*measurement).qOverP() * Gaudi::Units::GeV)
1938 << std::setw(10) << std::setprecision(3)
1943 ((*measurement).qOverP() * Gaudi::Units::GeV)
1947 msg() << std::setw(54);
1949 if ((*measurement).isMaterialDelimiter()) {
1950 msg() << std::setprecision(1)
1952 << std::setw(9) << std::setprecision(4)
1954 << std::setw(10) << std::setprecision(1)
1956 << std::setw(14) << std::setprecision(4)
1958 << std::setw(9) << std::setprecision(4)
1962 msg() << std::setprecision(1) << (*measurement).position().perp()
1963 << std::setw(9) << std::setprecision(4)
1964 << (*measurement).position().phi() << std::setw(10)
1965 << std::setprecision(1) << (*measurement).position().z()
1966 << std::setw(5) << (*measurement).numberDoF() <<
endmsg;
1972 scatterers = leadingMaterial;
1973 leadingMaterial = 0;
1978 << scatterers <<
" (" << leadingMaterial
1979 <<
") fitted scattering centres (leading material centres) giving "
1980 << std::setiosflags(std::ios::fixed) << std::setw(8)
1981 << std::setprecision(3) << sumX0 <<
" (" << std::setw(8)
1982 << std::setprecision(3) << leadingX0 <<
")"
1983 <<
" X0 and " << std::setw(8) << std::setprecision(3)
1984 << sumELoss / Gaudi::Units::GeV <<
" (" << std::setw(8)
1985 << std::setprecision(3) << leadingELoss / Gaudi::Units::GeV <<
")"
1990 std::vector<FitMeasurement*>& measurements,
1993 const EventContext& ctx = Gaudi::Hive::currentContext();
2002 bool haveMaterial =
false;
2003 bool haveLeadingMaterial =
false;
2004 bool reorderMS =
false;
2005 bool reorderID =
false;
2006 bool firstMSHit =
false;
2007 double previousDistance = 0.;
2008 double previousDistanceR = 0.;
2009 double previousDistanceZ = 0.;
2010 double minDistanceID = 0.;
2011 double minDistanceMS = 0.;
2012 double minRDistanceMS = 0.;
2013 double minZDistanceMS = 0.;
2014 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
2015 for (; m != measurements.end(); ++m) {
2017 const Amg::Vector3D positionSurf = (**m).surface()->center();
2019 if ((**m).measurementBase())
2020 positionMst = (**m).measurementBase()->globalPosition();
2021 const double distance = startDirection.dot(position - startPosition);
2022 const double distanceR = std::hypot(positionMst.x() - startPosition.x(),
2023 positionMst.y() - startPosition.y());
2024 double distanceZ = (positionMst.z() - startPosition.z());
2025 if (startDirection.z() < 0)
2026 distanceZ = -distanceZ;
2031 if (distance - previousDistance < minDistanceMS) {
2032 minDistanceMS = distance - previousDistance;
2033 minRDistanceMS = distanceR - previousDistanceR;
2034 minZDistanceMS = distanceZ - previousDistanceZ;
2037 if ((**m).isScatterer())
2038 haveMaterial =
true;
2039 if ((**m).measurementBase() && !firstMSHit) {
2042 if ((**m).isScatterer() && !firstMSHit)
2043 haveLeadingMaterial =
true;
2047 if (distance - previousDistance < minDistanceID)
2048 minDistanceID = distance - previousDistance;
2051 previousDistance = distance;
2052 previousDistanceZ = distanceZ;
2053 previousDistanceR = distanceR;
2065 if (reorderMS && fabs(minDistanceMS) > -2.)
2066 ATH_MSG_DEBUG(
" reorder MS part of track with minimum distance "
2067 << minDistanceMS <<
" minRDistanceMS " << minRDistanceMS
2068 <<
" minZDistanceMS " << minZDistanceMS);
2069 if (reorderID && fabs(minDistanceID) > -2.)
2070 ATH_MSG_DEBUG(
" reorder ID part of track with minimum distance "
2074 if (reorderMS || reorderID) {
2079 if (!haveLeadingMaterial && haveMaterial) {
2081 " MS part of track has no leading material in front of first MS hit ");
2092 " spectrometerMaterial: ALARM no material found on track can happen for "
2098 for (m = measurements.begin(); m != measurements.end(); ++m) {
2099 if (!(**m).isPositionMeasurement() || (**m).isOutlier())
2104 if (innerMeasurement) {
2105 outerMeasurement = *m;
2107 innerMeasurement = *m;
2110 if (!outerMeasurement)
2117 if (!spectrometerEntrance)
2122 std::unique_ptr<const TrackParameters> entranceParameters;
2123 MsgStream log(msgSvc(), name());
2125 std::unique_ptr<const TrackParameters> innerParameters(
2127 if (!innerParameters)
2128 innerParameters.reset(startParameters.
clone());
2130 ctx, *innerParameters, *spectrometerEntrance,
anyDirection,
2132 if (entranceParameters) {
2133 startDirection = entranceParameters->momentum().unit();
2134 startPosition = entranceParameters->position();
2136 entranceParameters->position(), entranceParameters->momentum().unit(),
2138 std::vector<Trk::FitMeasurement*>::iterator e = measurements.begin();
2141 for (m = measurements.begin(); m != measurements.end(); ++m) {
2149 e = measurements.insert(++e, entranceDelimiter);
2150 delete entranceIntersection;
2159 std::unique_ptr<const TrackParameters> outerParameters(
2161 if (!outerParameters)
2162 outerParameters.reset(startParameters.
clone());
2163 const Surface& endSurface = *measurements.back()->surface();
2164 std::unique_ptr<const TrackParameters> endParameters(
2168 if (!endParameters) {
2173 if (!endParameters) {
2176 endParameters = std::move(outerParameters);
2181 endParameters->position(), endParameters->momentum().unit(), 0.);
2184 measurements.push_back(endBreak);
2186 const double endSpectrometerDistance = startDirection.dot(
2193 Amg::VectorX parameterVector = endParameters->parameters();
2194 const double Emax = 50000.;
2198 if (std::abs(parameterVector[
Trk::qOverP]) * Emax < 1)
2199 parameterVector[
Trk::qOverP] = endParameters->charge() / Emax;
2205 endParameters->associatedSurface().createUniqueTrackParameters(
2210 if (entranceParameters) {
2211 const Surface& entranceSurface = entranceParameters->associatedSurface();
2226 <<
"using extrapolateM inwards from outermost measurement");
2231 if (!(*ss).trackParameters() || !(*ss).materialEffectsOnTrack())
2233 const double distance = startDirection.dot((*ss).trackParameters()->position() -
2236 const double thickness = (*ss).materialEffectsOnTrack()->thicknessInX0();
2239 (*ss).materialEffectsOnTrack());
2240 if (materialEffects && materialEffects->
energyLoss())
2242 const double p2 = (*ss).trackParameters()->momentum().mag();
2244 std::setiosflags(std::ios::fixed)
2245 <<
" material: RZ" << std::setw(9) << std::setprecision(3)
2246 << (*ss).trackParameters()->position().perp() << std::setw(10)
2247 << std::setprecision(3) << (*ss).trackParameters()->position().z()
2248 <<
" distance " << std::setw(10) << std::setprecision(3) << distance
2249 <<
" pt " << std::setw(8) << std::setprecision(3)
2250 << (*ss).trackParameters()->momentum().perp() / Gaudi::Units::GeV
2251 <<
" X0thickness " << std::setw(8) << std::setprecision(4)
2252 << thickness <<
" deltaE " << std::setw(8) << std::setprecision(4)
2253 << deltaE <<
" diffP " << std::setw(8) << std::setprecision(4)
2267 std::vector<const TrackStateOnSurface*>::const_reverse_iterator s =
2269 std::vector<FitMeasurement*> material;
2272 std::vector<FitMeasurement*>::iterator m = measurements.begin();
2278 double outgoingEnergy = 0.;
2280 outgoingEnergy = (**s).trackParameters()->momentum().mag();
2282 outgoingEnergy = endParameters->momentum().mag();
2291 material.push_back(measurement);
2294 if (distance > endSpectrometerDistance) {
2298 while (m != measurements.end() &&
2299 distance > startDirection.dot(
2304 if (m == measurements.end()) {
2309 m = measurements.insert(m, material.back());
Scalar deltaR(const MatrixBase< Derived > &vec) const
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
#define AmgSymMatrix(dim)
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
The BoundaryCheck class allows to steer the way surface boundaries are used for inside/outside checks...
simple class that constructs the curvilinear vectors curvU and curvV from a given momentum direction ...
virtual EnergyLoss * clone() const
Virtual constructor.
double deltaE() const
returns the
bool hasIntersection(ExtrapolationType type) const
bool isOutlier(void) const
const TrackSurfaceIntersection & intersection(ExtrapolationType type) const
double qOverP(void) const
const Surface * surface(void) const
Amg::Vector3D direction(void) const
TrackParameters * trackParameters(MsgStream &log, const FitMeasurement &measurement, bool withCovariance=false)
double qOverP(void) const
const Amg::Vector3D & vertex(void) const
const Amg::Vector3D & position(void) const
void update(const Amg::VectorX &differences)
std::vector< std::unique_ptr< const TrackStateOnSurface > > Garbage_t
@ CalorimeterEntryLayer
Tracking Volume which defines the entrance srufaces of the calorimeter.
@ MuonSpectrometerEntryLayer
Tracking Volume which defines the entrance surfaces of the MS.
magnetic field properties to steer the behavior of the extrapolation
void addSpectrometerDelimiters(std::vector< FitMeasurement * > &measurements) const
MaterialAllocator(const std::string &type, const std::string &name, const IInterface *parent)
const Trk::Volume * m_calorimeterVolume
ToolHandle< IPropagator > m_stepPropagator
ToolHandle< IIntersector > m_intersector
virtual void orderMeasurements(std::vector< FitMeasurement * > &measurements, Amg::Vector3D startDirection, Amg::Vector3D startPosition) const override
IMaterialAllocator interface: clear temporary TSOS.
virtual StatusCode initialize() override
double m_orderingTolerance
const Trk::TrackingVolume * getSpectrometerEntrance() const
void spectrometerMaterial(std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, FitParameters &fitParameters, const TrackParameters &startParameters, Garbage_t &garbage) const
Trk::MagneticFieldProperties m_stepField
virtual bool reallocateMaterial(std::vector< FitMeasurement * > &measurements, FitParameters &fitParameters, Garbage_t &garbage) const override
IMaterialAllocator interface: has material been reallocated?
void printMeasurements(std::vector< FitMeasurement * > &measurements) const
ServiceHandle< ITrackingVolumesSvc > m_trackingVolumesSvc
double m_scatteringLogCoeff
const std::vector< const TrackStateOnSurface * > * extrapolatedMaterial(const ToolHandle< IExtrapolator > &extrapolator, const TrackParameters ¶meters, const Surface &surface, PropDirection dir, const BoundaryCheck &boundsCheck, ParticleHypothesis particleHypothesis, Garbage_t &garbage) const
std::pair< FitMeasurement *, FitMeasurement * > materialAggregation(const std::vector< const TrackStateOnSurface * > &material, std::vector< FitMeasurement * > &measurements, double particleMass) const
void indetMaterial(std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, const TrackParameters &startParameters, Garbage_t &garbage) const
virtual StatusCode finalize() override
const Trk::Volume * m_indetVolume
static void deleteMaterial(const std::vector< const TrackStateOnSurface * > *material, Garbage_t &garbage)
static FitMeasurement * measurementFromTSOS(const TrackStateOnSurface &tsos, double outwardsEnergy, double particleMass)
virtual void initializeScattering(std::vector< FitMeasurement * > &measurements) const override
IMaterialAllocator interface: initialize scattering (needs to know X0 integral)
SG::ReadCondHandleKey< TrackingGeometry > m_trackingGeometryReadKey
virtual void addLeadingMaterial(std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, FitParameters &fitParameters, Garbage_t &garbage) const override
IMaterialAllocator interface: add leading material effects to fit measurements and parameters.
ToolHandle< IExtrapolator > m_extrapolator
double m_scatteringConstant
virtual void allocateMaterial(std::vector< FitMeasurement * > &measurements, ParticleHypothesis particleHypothesis, FitParameters &fitParameters, const TrackParameters &startParameters, Garbage_t &garbage) const override
IMaterialAllocator interface: allocate material.
ServiceHandle< ITrackingGeometrySvc > m_trackingGeometrySvc
virtual std::vector< const TrackStateOnSurface * > * leadingSpectrometerTSOS(const TrackParameters &spectrometerParameters, Garbage_t &garbage) const override
IMaterialAllocator interface: material TSOS between spectrometer entrance surface and parameters give...
std::unique_ptr< MessageHelper > m_messageHelper
double thicknessInX0() const
returns the actually traversed material .
represents the full description of deflection and e-loss of a track in material.
const EnergyLoss * energyLoss() const
returns the energy loss object.
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual ParametersBase< DIM, T > * clone() const override=0
clone method for polymorphic deep copy
const Amg::Vector3D & position() const
Access method for the position.
double charge() const
Returns the charge.
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
virtual const S & associatedSurface() const override final
Access to the Surface method.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
Abstract Base Class for tracking surfaces.
represents the track state (measurement, material, fit parameters and quality) at a surface.
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
const MaterialEffectsBase * materialEffectsOnTrack() const
return material effects const overload
An intersection with a Surface is given by.
const Amg::Vector3D & direction() const
Method to retrieve the direction at the Intersection.
const Amg::Vector3D & position() const
Method to retrieve the position of the Intersection.
Full Volume description used in Tracking, it inherits from Volume to get the geometrical structure,...
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
=============================================================================
constexpr double mass[PARTICLEHYPOTHESES]
the array of masses
Ensure that the ATLAS eigen extensions are properly loaded.
PropDirection
PropDirection, enum for direction of the propagation.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ FastField
call the fast field access method of the FieldSvc
@ FullField
Field is set to be realistic, but within a given Volume.
@ loc2
generic first and second local coordinate
ParticleHypothesis
Enumeration for Particle hypothesis respecting the interaction with material.
ParametersBase< TrackParametersDim, Charged > TrackParameters
ParametersT< TrackParametersDim, Charged, PlaneSurface > AtaPlane
DataModel_detail::iterator< DVL > remove(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, const T &value)
Specialization of remove for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.