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.;
893 for (std::vector<FitMeasurement*>::iterator m = measurements.begin();
894 m != measurements.end(); ++m, ++
index) {
896 if (!(**m).isPositionMeasurement() || (**m).isPseudo())
906 bool preBreak =
false;
907 bool postBreak =
false;
908 double distance = 0.;
914 referencePhi = position.phi();
915 startDirection = referenceDirection;
916 startPosition = referencePosition;
921 distance = referenceDirection.dot(
923 if (((**m).isDrift() && !
previous->isDrift()) ||
924 (!(**m).isDrift() &&
previous->isDrift()) ||
934 if (!(preBreak || postBreak)) {
936 previousDistance = distance;
963 m = measurements.insert(++m, delimiter);
964 while (*m != current)
970 offset = 0.5 * (previousDistance - distance);
974 m = measurements.insert(m, delimiter);
978 previousDistance = 0.;
981 referencePhi = position.phi();
988 const std::vector<const TrackStateOnSurface*>* material,
992 garbage.push_back(std::unique_ptr<const TrackStateOnSurface>(m));
998const std::vector<const TrackStateOnSurface*>*
1000 const ToolHandle<IExtrapolator>& extrapolator,
1004 const EventContext& ctx = Gaudi::Hive::currentContext();
1007 const std::vector<const TrackStateOnSurface*>* TGMaterial =
1008 extrapolator->extrapolateM(ctx, parameters, surface, dir, boundsCheck,
1009 particleHypothesis);
1011 if (!TGMaterial || TGMaterial->empty())
1014 std::vector<const TrackStateOnSurface*>* duplicates =
nullptr;
1015 std::vector<const TrackStateOnSurface*>* material =
1016 new std::vector<const TrackStateOnSurface*>;
1017 material->reserve(TGMaterial->size());
1018 std::vector<const TrackStateOnSurface*>::const_iterator tg =
1019 TGMaterial->begin();
1020 material->push_back(*tg);
1022 for (; tg != TGMaterial->end(); ++tg) {
1024 double separation = 0.;
1027 (**tg).trackParameters()->
position())
1030 if (separation > 0.001 * Gaudi::Units::mm) {
1031 material->push_back(*tg);
1034 std::setiosflags(std::ios::fixed)
1035 <<
" duplicate: RZ" << std::setw(9) << std::setprecision(3)
1036 << (**tg).trackParameters()->position().perp() << std::setw(10)
1037 << std::setprecision(3) << (**tg).trackParameters()->position().z());
1039 duplicates =
new std::vector<const TrackStateOnSurface*>;
1040 duplicates->push_back(*tg);
1051 std::vector<FitMeasurement*>& measurements,
1054 const EventContext& ctx = Gaudi::Hive::currentContext();
1059 10. * Gaudi::Units::mm / startParameters.
momentum().unit().perp();
1062 double endIndetDistance = 0.;
1069 std::unique_ptr<AtaPlane> newParameters;
1071 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1072 if ((**m).isVertex())
1074 for (; m != measurements.end(); ++m) {
1075 if ((**m).isOutlier())
1079 if ((**m).isScatterer()) {
1084 if (!(**m).isPositionMeasurement())
1096 std::optional<TrackSurfaceIntersection>
const newIntersectionSTEP =
1126 newParameters = std::make_unique<AtaPlane>(
1129 parameters = newParameters.get();
1136 const double distance = startDirection.dot(
1138 if (!endIndetMeasurement || distance > endIndetDistance) {
1139 endIndetDistance = distance;
1140 endIndetMeasurement = *m;
1146 if (!endIndetMeasurement) {
1150 ATH_MSG_DEBUG(
" indetMaterial: ALARM no material found on track");
1155 startDirection = (endPosition - startPosition).
unit();
1157 startDirection.dot(endPosition - startPosition) +
tolerance;
1159 << endIndetDistance);
1160 const std::vector<const TrackStateOnSurface*>*
indetMaterial =
1163 false, particleHypothesis, garbage);
1172 std::vector<const Surface*> surfaces;
1174 std::vector<const TrackStateOnSurface*>::const_iterator indetMaterialEnd =
1177 for (std::vector<const TrackStateOnSurface*>::const_iterator s =
1180 if ((**s).trackParameters()) {
1181 if (startDirection.dot((**s).trackParameters()->position() -
1182 startPosition) < endIndetDistance) {
1183 indetMaterialEnd = s;
1188 <<
" trailing TSOS (after last measurement)");
1203 if (
msgLvl(MSG::VERBOSE)) {
1204 double p1 =
indetMaterial->front()->trackParameters()->momentum().mag();
1206 for (std::vector<const TrackStateOnSurface*>::const_iterator s =
1208 s != indetMaterialEnd; ++s) {
1209 if (!(**s).trackParameters())
1211 const double distance = startDirection.dot((**s).trackParameters()->position() -
1214 double thickness = 0.;
1217 (**s).materialEffectsOnTrack());
1218 if ((**s).materialEffectsOnTrack()) {
1219 if (materialEffects)
1221 thickness = (**s).materialEffectsOnTrack()->thicknessInX0();
1223 const double p2 = (**s).trackParameters()->momentum().mag();
1225 std::setiosflags(std::ios::fixed)
1226 <<
" material: RZ" << std::setw(9) << std::setprecision(3)
1227 << (**s).trackParameters()->position().perp() << std::setw(10)
1228 << std::setprecision(3) << (**s).trackParameters()->position().z()
1229 <<
" distance " << std::setw(10) << std::setprecision(3) << distance
1230 <<
" pt " << std::setw(8) << std::setprecision(3)
1231 << (**s).trackParameters()->momentum().perp() / Gaudi::Units::GeV
1232 <<
" X0thickness " << std::setw(8) << std::setprecision(4)
1233 << thickness <<
" deltaE " << std::setw(8) << std::setprecision(4)
1234 << deltaE <<
" diffP " << std::setw(8) << std::setprecision(4)
1245 m = measurements.begin();
1246 std::vector<const TrackStateOnSurface*>::const_iterator s =
1248 for (; m != measurements.end(); ++m) {
1249 if (*m == endIndetMeasurement || s == indetMaterialEnd)
1251 if (!leadingDelimiter && (**m).
isOutlier())
1256 double closestDistance = direction.dot(position - startPosition);
1259 const Surface* materialSurface =
nullptr;
1262 for (; s != indetMaterialEnd; ++s) {
1264 (**s).materialEffectsOnTrack()) ||
1265 !(**s).trackParameters())
1267 nextMomentum = (**s).trackParameters()->momentum();
1268 nextPosition = (**s).trackParameters()->position();
1269 const double distance = direction.dot(nextPosition - position);
1272 if (distance > closestDistance)
1278 if (distance > 0.) {
1280 const double nextDistance = direction.dot(
1281 (**s).trackParameters()->position() - (**m).position());
1283 if (std::abs(nextDistance) < distance && distance >
tolerance) {
1286 materialSurface =
nullptr;
1289 closestDistance = distance;
1291 closestDistance = -distance;
1296 if (!leadingDelimiter && materialSurface)
1297 surfaces.push_back(materialSurface);
1300 (**s).materialEffectsOnTrack());
1301 materialParameters = (**s).trackParameters();
1306 if (!materialSurface)
1310 if (!surfaces.empty() && materialSurface == surfaces.back())
1316 if (!leadingDelimiter) {
1317 position = 0.5 * (materialParameters->
position() + nextPosition);
1318 direction = (materialParameters->
momentum() + nextMomentum).unit();
1321 while (*m != endIndetMeasurement &&
1325 m = measurements.insert(m, leadingDelimiter);
1326 surfaces.push_back(materialSurface);
1335 const std::bitset<MaterialEffectsBase::NumberOfMaterialEffectsTypes>
1337 std::unique_ptr<Trk::EnergyLoss> energyLoss =
nullptr;
1339 energyLoss = std::unique_ptr<Trk::EnergyLoss>(
1344 *(**m).surface(), typePattern);
1346 if (++m == measurements.end())
1348 m = measurements.insert(
1353 (**m).qOverP(materialParameters->parameters()[
Trk::qOverP]);
1354 (**m).setMaterialEffectsOwner();
1355 surfaces.push_back(materialSurface);
1359 m = measurements.begin();
1362 << measurements.size() <<
" surfaces.size() "
1363 << surfaces.size() <<
" indetMaterial->size() "
1365 std::vector<const Surface*>::const_iterator
r = surfaces.begin();
1366 for (s =
indetMaterial->begin(); s != indetMaterialEnd; ++s) {
1367 if (!(**s).trackParameters() || !(**s).materialEffectsOnTrack())
1370 if (
r != surfaces.end() &&
1371 **
r == (**s).trackParameters()->associatedSurface()) {
1376 const double distance =
1377 startDirection.dot((**s).trackParameters()->position() - startPosition);
1380 << startPosition.z());
1382 " (**m).intersection(FittedTrajectory).position() measurement "
1387 " (**s).trackParameters()->position() material surface position "
1389 << (**s).trackParameters()->position().perp() <<
" z "
1390 << (**s).trackParameters()->position().z());
1393 bool endIndet =
false;
1397 if (*m == endIndetMeasurement) {
1398 if (*m != measurements.back()) {
1407 if (*m != measurements.back()) {
1413 <<
" (**m).intersection(FittedTrajectory).position() "
1414 "measurement position r "
1422 " im " << im <<
" distance measurement "
1423 << startDirection.dot(
1427 " (**m).intersection(FittedTrajectory).position() measurement position "
1432 m = measurements.insert(
1435 (**s).trackParameters()->position()));
1437 (**s).trackParameters()->position(),
1438 (**s).trackParameters()->momentum().unit(), 0.);
1440 (**m).qOverP((**s).trackParameters()->parameters()[
Trk::qOverP]);
1446 m = measurements.begin();
1448 for (; m != measurements.end(); ++m) {
1449 if (!leadingDelimiter && (**m).
isOutlier())
1454 ATH_MSG_VERBOSE(
" im " << im <<
" position R " << position.perp() <<
" z "
1464std::pair<FitMeasurement*, FitMeasurement*>
1466 const std::vector<const TrackStateOnSurface*>& material,
1467 std::vector<FitMeasurement*>& ,
1470 ATH_MSG_INFO(
"segment material aggregation " << material.size());
1473 if (material.empty())
1474 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1478 int adjacentScatterers = 0;
1479 std::vector<FitMeasurement*> aggregateScatterers;
1480 bool hasReferencePosition =
false;
1482 bool const haveAggregation =
false;
1485 for (std::vector<const TrackStateOnSurface*>::const_reverse_iterator tsos =
1487 tsos != material.rend(); ++tsos) {
1488 if (!(**tsos).trackParameters() || !(**tsos).materialEffectsOnTrack()){
1491 ++adjacentScatterers;
1492 if (!hasReferencePosition) {
1493 referencePosition =
Amg::Vector3D((**tsos).trackParameters()->position());
1494 hasReferencePosition =
true;
1496 const double distance =
1497 ((**tsos).trackParameters()->position() - referencePosition).mag();
1498 const double weight = (**tsos).materialEffectsOnTrack()->thicknessInX0();
1500 ATH_MSG_INFO(
" material position " << (**tsos).trackParameters()->position()
1501 <<
" distance " << distance
1502 <<
" thickness " << 100. * weight);
1506 if (adjacentScatterers < 3) {
1510 if (haveAggregation) {
1513 return std::pair<FitMeasurement*, FitMeasurement*>(measurement1,
1518 std::vector<FitMeasurement*>& measurements,
double particleMass)
const {
1535 int adjacentScatterers = 0;
1536 std::vector<FitMeasurement*> aggregateScatterers;
1537 bool haveAggregation =
false;
1538 bool makeAggregation =
false;
1539 double maxDistance = 0.;
1542 double totalDistance = 0.;
1543 double totalDistanceSq = 0.;
1544 double totalEnergyDeposit = 0.;
1545 double totalThickness = 0.;
1546 std::vector<FitMeasurement*>::reverse_iterator start;
1547 std::vector<FitMeasurement*>::reverse_iterator
previous =
1548 measurements.rbegin();
1549 for (std::vector<FitMeasurement*>::reverse_iterator m = measurements.rbegin();
1550 m != measurements.rend(); ++m) {
1551 if ((**m).isScatterer())
1552 aggregateScatterers.push_back(*m);
1554 if (!adjacentScatterers)
1556 makeAggregation =
true;
1561 else if (adjacentScatterers) {
1562 if ((**m).isScatterer()) {
1565 const double distance =
1566 std::abs(referenceDirection.dot(position - referencePosition));
1567 if (distance < maxDistance) {
1568 ++adjacentScatterers;
1569 const double weight = (**m).radiationThickness();
1570 totalDistance += weight * distance;
1571 totalDistanceSq += weight * distance * distance;
1572 totalEnergyDeposit += (**m).energyLoss();
1573 totalThickness += weight;
1574 if (*m == measurements.front())
1575 makeAggregation =
true;
1581 }
else if (adjacentScatterers > 1) {
1582 makeAggregation =
true;
1584 adjacentScatterers = 0;
1586 }
else if (!(**m).isMaterialDelimiter()) {
1589 }
else if (adjacentScatterers > 1) {
1590 makeAggregation =
true;
1592 adjacentScatterers = 0;
1596 if (makeAggregation) {
1616 const double meanDistance = totalDistance / totalThickness;
1617 double rmsDistance = 0.;
1618 const double meanSquare =
1619 totalDistanceSq / totalThickness - meanDistance * meanDistance;
1620 if (meanSquare > 0.)
1621 rmsDistance = std::sqrt(meanSquare);
1622 const double gap = 2. * rmsDistance;
1624 const double distance1 = meanDistance - rmsDistance;
1625 double distance2 = meanDistance + rmsDistance;
1627 distance2 = meanDistance;
1630 const double distance =
1631 std::abs(referenceDirection.dot(position - referencePosition));
1642 if (distance2 > distance || distance1 < 0.) {
1648 double previousDistance = 0.;
1649 haveAggregation =
true;
1651 for (std::vector<Trk::FitMeasurement*>::reverse_iterator s = start;
1652 s != measurements.rend(); ++s) {
1653 if (!(**s).isScatterer())
1657 const double distance =
1658 std::abs(referenceDirection.dot(position - referencePosition));
1659 if (!measurement1 && distance > distance1 &&
1662 const double separation = distance - previousDistance;
1663 const double fractionAfter =
1664 (distance1 - previousDistance) / separation;
1665 const double fractionBefore = (distance - distance1) / separation;
1675 position = fractionBefore *
1684 const double qOverP = fractionBefore * before->
qOverP() +
1685 fractionAfter * after->
qOverP();
1687 0.5 * totalThickness, -0.5 * totalEnergyDeposit, particleMass,
1688 position, direction,
qOverP);
1691 if (distance > distance2) {
1693 const double separation = distance - previousDistance;
1694 const double fractionAfter =
1695 (distance2 - previousDistance) / separation;
1696 const double fractionBefore = (distance - distance2) / separation;
1706 position = fractionBefore *
1715 const double qOverP = fractionBefore * before->
qOverP() +
1716 fractionAfter * after->
qOverP();
1719 0.5 * totalThickness, -0.5 * totalEnergyDeposit,
1720 particleMass, position, direction,
qOverP);
1723 totalThickness, -totalEnergyDeposit, particleMass, position,
1726 bool keepCurrentMeas =
false;
1727 if ((**m).isScatterer() && *m != measurements.front()) {
1728 keepCurrentMeas =
true;
1729 aggregateScatterers.pop_back();
1731 while (adjacentScatterers--) {
1732 aggregateScatterers.back()->setOutlier();
1733 aggregateScatterers.pop_back();
1736 aggregateScatterers.push_back(measurement1);
1738 aggregateScatterers.push_back(measurement2);
1739 if (keepCurrentMeas)
1740 aggregateScatterers.push_back(*m);
1741 measurement1 =
nullptr;
1742 measurement2 =
nullptr;
1746 previousDistance = distance;
1750 adjacentScatterers = 0;
1751 makeAggregation =
false;
1755 if ((**m).isScatterer() && !adjacentScatterers &&
1757 adjacentScatterers = 1;
1758 const double weight = (**m).radiationThickness();
1761 referenceDirection =
1764 const double distance =
1765 std::abs(referenceDirection.dot(position - referencePosition));
1766 maxDistance = distance + 2. * Gaudi::Units::meter;
1768 totalDistance = weight * distance;
1769 totalDistanceSq = weight * distance * distance;
1770 totalEnergyDeposit = (**m).energyLoss();
1771 totalThickness = weight;
1782 delete measurement1;
1787 if (haveAggregation) {
1790 referenceDirection =
1791 (referencePosition -
1794 std::vector<Trk::FitMeasurement*>::reverse_iterator s =
1795 aggregateScatterers.rbegin();
1798 double scattererDistance =
1799 std::abs(referenceDirection.dot(scattererPosition - referencePosition));
1800 for (std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1801 m != measurements.end(); ) {
1804 const double distance =
1805 std::abs(referenceDirection.dot(position - referencePosition));
1806 while (distance <= scattererDistance && s != aggregateScatterers.rend()) {
1807 m = measurements.insert(m, *s);
1809 if (++s != aggregateScatterers.rend()) {
1811 scattererDistance = std::abs(
1812 referenceDirection.dot(scattererPosition - referencePosition));
1815 if ((**m).isScatterer()) {
1817 if ((**m).isOutlier())
1820 m = measurements.erase(m);
1829 if (
msgLvl(MSG::VERBOSE)) {
1836 for (
auto* measurement : measurements) {
1839 const double distance = std::abs(startDirection.dot(position - startPosition));
1840 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed) << std::setw(5)
1841 << ++n << std::setw(10) << std::setprecision(3)
1842 << distance <<
" " << (*measurement).type();
1843 if ((*measurement).isOutlier()) {
1844 msg() <<
" outlier ";
1845 }
else if ((*measurement).materialEffects()) {
1846 msg() << std::setw(8) << std::setprecision(3)
1847 << (*measurement).materialEffects()->thicknessInX0() <<
" ";
1851 if (!(*measurement).isMaterialDelimiter()) {
1852 msg() << std::setw(10) << std::setprecision(1)
1853 << (*measurement).position().perp() << std::setw(9)
1854 << std::setprecision(4) << (*measurement).position().phi()
1855 << std::setw(10) << std::setprecision(1)
1856 << (*measurement).position().z();
1863 bool energyGain =
false;
1864 for (
auto& measurement : measurements) {
1865 if ((*measurement).materialEffects() && (*measurement).numberDoF() &&
1866 (*measurement).energyLoss() < 0.)
1871 for (
auto& measurement : measurements) {
1872 if ((*measurement).materialEffects())
1873 (*measurement).setEnergyGain();
1880 double particleMass) {
1888 double qOverP = 1. / outgoingEnergy;
1892 return new FitMeasurement(thicknessInX0, deltaE, particleMass, position,
1897 std::vector<FitMeasurement*>& measurements)
const {
1899 "measurements and material: distance X0 deltaE E "
1901 <<
" R phi Z DoF phi theta");
1903 if (measurements.empty())
1906 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
1907 while (m != measurements.end() && !(**m).isPositionMeasurement())
1909 if (m == measurements.end())
1910 m = measurements.begin();
1915 int leadingMaterial = 0;
1916 double leadingX0 = 0.;
1918 double leadingELoss = 0.;
1919 double sumELoss = 0.;
1921 for (
auto& measurement : measurements) {
1922 const double distance =
1925 msg(MSG::VERBOSE) << std::setiosflags(std::ios::fixed) << std::setw(5)
1926 << ++n <<
" " << (*measurement).type() << std::setw(11)
1927 << std::setprecision(3) << distance;
1928 if ((*measurement).isOutlier()) {
1929 msg() <<
" outlier " << std::setw(44);
1930 }
else if ((*measurement).materialEffects()) {
1934 (*measurement).materialEffects());
1935 if (materialEffects && materialEffects->
energyLoss())
1937 if ((*measurement).isEnergyDeposit())
1939 msg() << std::setw(10) << std::setprecision(3)
1940 << (*measurement).materialEffects()->thicknessInX0() << std::setw(9)
1941 << std::setprecision(1) << deltaE <<
" ";
1942 if (distance > 0.) {
1944 sumX0 += (*measurement).materialEffects()->thicknessInX0();
1948 leadingX0 += (*measurement).materialEffects()->thicknessInX0();
1949 leadingELoss -= deltaE;
1952 if ((*measurement).qOverP()) {
1953 msg() << std::setw(11) << std::setprecision(4)
1954 << 1. / std::abs((*measurement).qOverP() * Gaudi::Units::GeV)
1955 << std::setw(10) << std::setprecision(3)
1960 ((*measurement).qOverP() * Gaudi::Units::GeV)
1964 msg() << std::setw(54);
1966 if ((*measurement).isMaterialDelimiter()) {
1967 msg() << std::setprecision(1)
1969 << std::setw(9) << std::setprecision(4)
1971 << std::setw(10) << std::setprecision(1)
1973 << std::setw(14) << std::setprecision(4)
1975 << std::setw(9) << std::setprecision(4)
1979 msg() << std::setprecision(1) << (*measurement).position().perp()
1980 << std::setw(9) << std::setprecision(4)
1981 << (*measurement).position().phi() << std::setw(10)
1982 << std::setprecision(1) << (*measurement).position().z()
1983 << std::setw(5) << (*measurement).numberDoF() <<
endmsg;
1989 scatterers = leadingMaterial;
1990 leadingMaterial = 0;
1995 << scatterers <<
" (" << leadingMaterial
1996 <<
") fitted scattering centres (leading material centres) giving "
1997 << std::setiosflags(std::ios::fixed) << std::setw(8)
1998 << std::setprecision(3) << sumX0 <<
" (" << std::setw(8)
1999 << std::setprecision(3) << leadingX0 <<
")"
2000 <<
" X0 and " << std::setw(8) << std::setprecision(3)
2001 << sumELoss / Gaudi::Units::GeV <<
" (" << std::setw(8)
2002 << std::setprecision(3) << leadingELoss / Gaudi::Units::GeV <<
")"
2007 std::vector<FitMeasurement*>& measurements,
2010 const EventContext& ctx = Gaudi::Hive::currentContext();
2019 bool haveMaterial =
false;
2020 bool haveLeadingMaterial =
false;
2021 bool reorderMS =
false;
2022 bool reorderID =
false;
2023 bool firstMSHit =
false;
2024 double previousDistance = 0.;
2025 double previousDistanceR = 0.;
2026 double previousDistanceZ = 0.;
2027 double minDistanceID = 0.;
2028 double minDistanceMS = 0.;
2029 double minRDistanceMS = 0.;
2030 double minZDistanceMS = 0.;
2031 std::vector<Trk::FitMeasurement*>::iterator m = measurements.begin();
2032 for (; m != measurements.end(); ++m) {
2034 const Amg::Vector3D positionSurf = (**m).surface()->center();
2036 if ((**m).measurementBase())
2037 positionMst = (**m).measurementBase()->globalPosition();
2038 const double distance = startDirection.dot(position - startPosition);
2039 const double distanceR = std::hypot(positionMst.x() - startPosition.x(),
2040 positionMst.y() - startPosition.y());
2041 double distanceZ = (positionMst.z() - startPosition.z());
2042 if (startDirection.z() < 0)
2043 distanceZ = -distanceZ;
2048 if (distance - previousDistance < minDistanceMS) {
2049 minDistanceMS = distance - previousDistance;
2050 minRDistanceMS = distanceR - previousDistanceR;
2051 minZDistanceMS = distanceZ - previousDistanceZ;
2054 if ((**m).isScatterer())
2055 haveMaterial =
true;
2056 if ((**m).measurementBase() && !firstMSHit) {
2059 if ((**m).isScatterer() && !firstMSHit)
2060 haveLeadingMaterial =
true;
2064 if (distance - previousDistance < minDistanceID)
2065 minDistanceID = distance - previousDistance;
2068 previousDistance = distance;
2069 previousDistanceZ = distanceZ;
2070 previousDistanceR = distanceR;
2082 if (reorderMS && fabs(minDistanceMS) > -2.)
2083 ATH_MSG_DEBUG(
" reorder MS part of track with minimum distance "
2084 << minDistanceMS <<
" minRDistanceMS " << minRDistanceMS
2085 <<
" minZDistanceMS " << minZDistanceMS);
2086 if (reorderID && fabs(minDistanceID) > -2.)
2087 ATH_MSG_DEBUG(
" reorder ID part of track with minimum distance "
2091 if (reorderMS || reorderID) {
2096 if (!haveLeadingMaterial && haveMaterial) {
2098 " MS part of track has no leading material in front of first MS hit ");
2109 " spectrometerMaterial: ALARM no material found on track can happen for "
2115 for (m = measurements.begin(); m != measurements.end(); ++m) {
2116 if (!(**m).isPositionMeasurement() || (**m).isOutlier())
2121 if (innerMeasurement) {
2122 outerMeasurement = *m;
2124 innerMeasurement = *m;
2127 if (!outerMeasurement)
2134 if (!spectrometerEntrance)
2139 std::unique_ptr<const TrackParameters> entranceParameters;
2140 MsgStream log(msgSvc(), name());
2142 std::unique_ptr<const TrackParameters> innerParameters(
2144 if (!innerParameters)
2145 innerParameters.reset(startParameters.
clone());
2147 ctx, *innerParameters, *spectrometerEntrance,
anyDirection,
2149 if (entranceParameters) {
2150 startDirection = entranceParameters->momentum().unit();
2151 startPosition = entranceParameters->position();
2153 entranceParameters->position(), entranceParameters->momentum().unit(),
2155 std::vector<Trk::FitMeasurement*>::iterator e = measurements.begin();
2158 for (m = measurements.begin(); m != measurements.end(); ++m) {
2166 e = measurements.insert(++e, entranceDelimiter);
2167 delete entranceIntersection;
2176 std::unique_ptr<const TrackParameters> outerParameters(
2178 if (!outerParameters)
2179 outerParameters.reset(startParameters.
clone());
2180 const Surface& endSurface = *measurements.back()->surface();
2181 std::unique_ptr<const TrackParameters> endParameters(
2185 if (!endParameters) {
2190 if (!endParameters) {
2193 endParameters = std::move(outerParameters);
2198 endParameters->position(), endParameters->momentum().unit(), 0.);
2201 measurements.push_back(endBreak);
2203 const double endSpectrometerDistance = startDirection.dot(
2210 Amg::VectorX parameterVector = endParameters->parameters();
2211 const double Emax = 50000.;
2215 if (std::abs(parameterVector[
Trk::qOverP]) * Emax < 1)
2216 parameterVector[
Trk::qOverP] = endParameters->charge() / Emax;
2222 endParameters->associatedSurface().createUniqueTrackParameters(
2227 if (entranceParameters) {
2228 const Surface& entranceSurface = entranceParameters->associatedSurface();
2243 <<
"using extrapolateM inwards from outermost measurement");
2248 if (!(*ss).trackParameters() || !(*ss).materialEffectsOnTrack())
2250 const double distance = startDirection.dot((*ss).trackParameters()->position() -
2253 const double thickness = (*ss).materialEffectsOnTrack()->thicknessInX0();
2256 (*ss).materialEffectsOnTrack());
2257 if (materialEffects && materialEffects->
energyLoss())
2259 const double p2 = (*ss).trackParameters()->momentum().mag();
2261 std::setiosflags(std::ios::fixed)
2262 <<
" material: RZ" << std::setw(9) << std::setprecision(3)
2263 << (*ss).trackParameters()->position().perp() << std::setw(10)
2264 << std::setprecision(3) << (*ss).trackParameters()->position().z()
2265 <<
" distance " << std::setw(10) << std::setprecision(3) << distance
2266 <<
" pt " << std::setw(8) << std::setprecision(3)
2267 << (*ss).trackParameters()->momentum().perp() / Gaudi::Units::GeV
2268 <<
" X0thickness " << std::setw(8) << std::setprecision(4)
2269 << thickness <<
" deltaE " << std::setw(8) << std::setprecision(4)
2270 << deltaE <<
" diffP " << std::setw(8) << std::setprecision(4)
2284 std::vector<const TrackStateOnSurface*>::const_reverse_iterator s =
2286 std::vector<FitMeasurement*> material;
2289 std::vector<FitMeasurement*>::iterator m = measurements.begin();
2295 double outgoingEnergy = 0.;
2297 outgoingEnergy = (**s).trackParameters()->momentum().mag();
2299 outgoingEnergy = endParameters->momentum().mag();
2308 material.push_back(measurement);
2311 if (distance > endSpectrometerDistance) {
2315 while (m != measurements.end() &&
2316 distance > startDirection.dot(
2321 if (m == measurements.end()) {
2326 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.