25isTrapped(
const double distance,
26 double& previousDistance,
27 unsigned long long& stepsUntilTrapped)
30 if (distance > previousDistance) {
34 if (stepsUntilTrapped <= 0) {
51 const std::string& name,
52 const IInterface* parent)
53 : base_class (
type, name, parent) {}
75 return StatusCode::SUCCESS;
85 msg(MSG::INFO) << std::setiosflags(std::ios::fixed)
86 <<
" taking an average" << std::setw(7) << std::setprecision(1)
88 <<
" full steps," << std::setw(5) << std::setprecision(2)
90 <<
" step reductions and" << std::setw(5) << std::setprecision(2)
92 <<
" short final steps";
96 return StatusCode::SUCCESS;
100std::optional<Trk::TrackSurfaceIntersection>
103 const double qOverP)
const
112 const auto surfaceType = surface.
type();
115 trackIntersection,
qOverP);
129 trackIntersection,
qOverP);
133 trackIntersection,
qOverP);
141std::optional<Trk::TrackSurfaceIntersection>
144 const double qOverP)
const
149 const double rStart = pos.perp();
150 const double zStart = pos.z();
157 double stepLength = 0;
160 double previousDistance = 1.1*distance;
165 if (isTrapped(distance, previousDistance, stepsUntilTrapped)) {
168 rStart, zStart,
true);
172 step(isect, fieldValue, stepLength,
qOverP, fieldCache);
183std::optional<Trk::TrackSurfaceIntersection>
186 const double qOverP)
const
191 const double rStart = pos.perp();
192 const double zStart = pos.z();
199 double stepLength = 0;
202 double previousDistance = 1.1*distance;
207 if (isTrapped(distance, previousDistance, stepsUntilTrapped)) {
210 rStart, zStart,
true);
214 step(isect, fieldValue, stepLength,
qOverP,fieldCache);
225std::optional<Trk::TrackSurfaceIntersection>
228 const double qOverP)
const
233 const double rStart = pos.perp();
234 const double zStart = pos.z();
242 double rCurrent = offset.perp();
243 double stepLength = 0;
244 double distance =
distanceToCylinder (isect, cylinderRadius,rCurrent,offset, stepLength);
246 double previousDistance = 1.1*distance;
247 bool trapped =
false;
252 if (isTrapped(distance, previousDistance, stepsUntilTrapped)) {
257 double rPrevious= rCurrent;
258 step(isect, fieldValue, stepLength,
qOverP,fieldCache);
260 rCurrent = offset.perp();
261 double deltaR1 = rCurrent - rPrevious;
262 double deltaR2 = cylinderRadius - rCurrent;
264 if (deltaR1 != 0.) scale = deltaR2 / deltaR1;
273 distance = std::abs(stepLength);
292 rStart, zStart,
true);
297std::optional<Trk::TrackSurfaceIntersection>
300 const double qOverP)
const
305 const double rStart = pos.perp();
306 const double zStart = pos.z();
312 double stepLength = 0;
315 double previousDistance = 1.1*distance;
320 if (isTrapped(distance, previousDistance, stepsUntilTrapped)) {
323 rStart, zStart,
true);
327 step(isect, fieldValue, stepLength,
qOverP,fieldCache);
338std::optional<Trk::TrackSurfaceIntersection>
341 const double qOverP)
const
346 const double rStart = pos.perp();
347 const double zStart = pos.z();
353 double stepLength = 0;
356 double previousDistance = 1.1*distance;
361 if (isTrapped(distance, previousDistance, stepsUntilTrapped)) {
364 rStart, zStart,
true);
368 step(isect, fieldValue, stepLength,
qOverP, fieldCache);
383 double& stepLength)
const
386 const double sinTheta = isect.
direction().perp();
391 const double zCurrent = std::abs(pos.z());
392 const double rCurrent = pos.perp();
406 }
else if (zCurrent >
m_inDetZ2 || sinTheta < 0.35) {
412 else if (zCurrent >
m_inDetZ1 && sinTheta < 0.60) {
435 else if (rCurrent < 1000.)
437 if (zCurrent > 700.) {
444 else if (zCurrent > 420. && sinTheta < 0.60) {
449 if (rCurrent > 900.) {
460 if (zCurrent < 3000.)
471 double period =
M_PI / 4.;
472 double phi = pos.phi() + 0.5 * period;
475 int n =
static_cast<int>(
phi / period);
476 phi -=
static_cast<double>(n) * period;
477 if (
phi > 0.5 * period)
483 double radius = rCurrent;
491 }
else if (radius < 5300.) {
499 else if (
phi > 0.04 ||
502 (
phi > 0.028 && radius < 9350.))))
508 }
else if (radius > 5500. && radius < 9350.) {
550 }
else if (zCurrent < m_toroidZ0 || zCurrent >
m_toroidZ1 ||
575 if (std::abs(stepLength) < stepMax)
577 if (stepLength > 0.) {
578 stepLength = stepMax;
580 stepLength = -stepMax;
590 const bool trapped)
const
596 const double sinTheta = isect.direction().perp();
597 if (
qOverP != 0.) pt = sinTheta/(
qOverP*Gaudi::Units::GeV);
599 const double rCurrent = isect.position().perp();
601 MsgStream log(msgSvc(), name());
602 if (rCurrent > rStart)
604 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right)
605 <<
" fail to intersect surface when extrapolating outwards from R,Z"
606 << std::setw(8) << std::setprecision(1) << rStart <<
","
607 << std::setw(7) << std::setprecision(0) << zStart <<
" mm, with pt"
608 << std::setw(7) << std::setprecision(2) << pt <<
" GeV, direction eta"
609 << std::setw(5) << std::setprecision(2) << isect.direction().eta();
613 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right)
614 <<
" fail to intersect surface when extrapolating inwards from R,Z"
615 << std::setw(8) << std::setprecision(1) << rStart <<
","
616 << std::setw(7) << std::setprecision(0) << zStart <<
" mm, with pt"
617 << std::setw(7) << std::setprecision(2) << pt <<
" GeV, direction eta"
618 << std::setw(5) << std::setprecision(2) << isect.direction().eta();
621 log << MSG::DEBUG <<
endmsg;
625 double stepLength = 0;
627 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right) <<
" PlaneSurface"
628 <<
" at R,Z" << std::setw(8) << std::setprecision(1) << surface.
center().perp() <<
","
629 << std::setw(7) << std::setprecision(0) << surface.
center().z()
630 <<
" at line distance " << std::setw(9) << std::setprecision(1) << stepLength;
632 log << MSG::DEBUG <<
endmsg;
638 double rCurrent = offset.perp();
639 double stepLength = 0;
640 double distance =
distanceToCylinder (isect, cylinderRadius,rCurrent,offset, stepLength);
643 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right)
644 <<
" closest approach to CylinderSurface at radius "
645 << std::setw(9) << std::setprecision(4) << rCurrent
646 <<
" mm. Cylinder radius " << std::setw(9) << std::setprecision(4) << cylinderRadius <<
" mm"
651 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right) <<
" CylinderSurface"
652 <<
" radius " << std::setw(6) << std::setprecision(1) << cylinderRadius
653 <<
" rCurrent " << std::setw(6) << std::setprecision(1) << rCurrent
654 <<
" distance " << std::setw(6) << std::setprecision(1) << stepLength;
655 if (trapped) log << MSG::DEBUG <<
" looping in mag field ";
656 log << MSG::DEBUG <<
endmsg;
659 else if (
dynamic_cast<const DiscSurface*
>(&surface))
661 double stepLength = 0;
663 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right) <<
" DiscSurface"
664 <<
" at R,Z" << std::setw(8) << std::setprecision(1) << surface.
center().perp() <<
","
665 << std::setw(7) << std::setprecision(0) << surface.
center().z()
666 <<
" at line distance " << std::setw(9) << std::setprecision(1) << stepLength;
667 if (trapped) log << MSG::DEBUG <<
" looping in mag field ";
668 log << MSG::DEBUG <<
endmsg;
672 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right) <<
" PerigeeSurface "
677 log << MSG::DEBUG << std::setiosflags(std::ios::fixed|std::ios::right) <<
" StraightLineSurface "
680 log << MSG::DEBUG <<
endmsg;
686 const double stepLength,
687 const double qOverP)
const
691 const double cOverP = Gaudi::Units::c_light*
qOverP;
694 double stepOverP = 0.5*stepLength*cOverP;
698 Amg::Vector3D product1 = stepOverP*direction1.cross(fieldValue);
700 Amg::Vector3D product2 = stepOverP*direction2.cross(fieldValue);
702 pos += stepLength*(dir +
m_third*(product0+product1+product2));
704 Amg::Vector3D product3 = stepOverP*direction3.cross(fieldValue);
705 dir +=
m_third*(product0+product3 + 2.*(product1+product2));
719 const double cOverP = Gaudi::Units::c_light*
qOverP;
721 double stepOverP = 0.5*stepLength*cOverP;
725 Amg::Vector3D position1 = pos + 0.5*stepLength*(dir + 0.5*product0);
728 Amg::Vector3D product1 = stepOverP*direction1.cross(fieldValue1);
730 Amg::Vector3D product2 = stepOverP*direction2.cross(fieldValue1);
737 if ((fieldValue1 - 0.5 * (fieldValue + fieldAtEnd)).
mag() > 0.00001 &&
739 if (stepLength > 0.) {
745 stepOverP = 0.5 * stepLength * cOverP;
746 product0 = stepOverP * dir.cross(fieldValue);
749 pos + 0.5 * stepLength * (dir + 0.5 * product0);
752 product1 = stepOverP * direction1p.cross(fieldValue1p);
754 product2 = stepOverP * direction2p.cross(fieldValue1p);
757 stepLength * (dir +
m_third * (product0 + product1 + product2));
758 fieldAtEnd =
field(pos + offsetAtEnd, fieldCache);
762 Amg::Vector3D product3 = stepOverP * direction3.cross(fieldAtEnd);
763 dir +=
m_third * (product0 + product3 + 2. * (product1 + product2));
764 fieldValue = fieldAtEnd;
Scalar mag() const
mag method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x)
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Class for a CylinderSurface in the ATLAS detector.
virtual const Amg::Vector3D & globalReferencePoint() const override final
Returns a global reference point: For the Cylinder this is Where denotes the averagePhi() of the cy...
Class for a DiscSurface in the ATLAS detector.
Class describing the Line to which the Perigee refers to.
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
BooleanProperty m_productionMode
virtual std::optional< TrackSurfaceIntersection > intersectDiscSurface(const DiscSurface &surface, const TrackSurfaceIntersection &trackIntersection, const double qOverP) const override
IIntersector interface method for specific Surface type : DiscSurface.
virtual StatusCode initialize() override
const double m_shortStepMin
std::optional< TrackSurfaceIntersection > newIntersection(TrackSurfaceIntersection &&isect, const Surface &surface, const double qOverP, const double rStart, const double zStart) const
const double m_momentumWarnThreshold
virtual std::optional< TrackSurfaceIntersection > approachPerigeeSurface(const PerigeeSurface &surface, const TrackSurfaceIntersection &trackIntersection, const double qOverP) const override
IIntersector interface method for specific Surface type : PerigeeSurface.
void debugFailure(TrackSurfaceIntersection &&isect, const Surface &surface, const double qOverP, const double rStart, const double zStart, const bool trapped) const
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCacheCondObjInputKey
void step(TrackSurfaceIntersection &isect, Amg::Vector3D &fieldValue, double &stepLength, const double qOverP, MagField::AtlasFieldCache &fieldCache) const
void assignStepLength(const TrackSurfaceIntersection &isect, double &stepLength) const
double distanceToPlane(const TrackSurfaceIntersection &isect, const Amg::Vector3D &planePosition, const Amg::Vector3D &planeNormal, double &stepLength) const
std::atomic< unsigned long long > m_countStepReduction
double distanceToLine(const TrackSurfaceIntersection &isect, const Amg::Vector3D &linePosition, const Amg::Vector3D &lineDirection, double &stepLength) const
std::atomic< unsigned long long > m_countStep
virtual std::optional< TrackSurfaceIntersection > approachStraightLineSurface(const StraightLineSurface &surface, const TrackSurfaceIntersection &trackIntersection, const double qOverP) const override
IIntersector interface method for specific Surface type : StraightLineSurface.
RungeKuttaIntersector(const std::string &type, const std::string &name, const IInterface *parent)
double distanceToCylinder(const TrackSurfaceIntersection &isect, const double cylinderRadius, const double offsetRadius, const Amg::Vector3D &offset, double &stepLength) const
double distanceToDisc(const TrackSurfaceIntersection &isect, const double discZ, double &stepLength) const
std::atomic< unsigned long long > m_countExtrapolations
virtual std::optional< TrackSurfaceIntersection > intersectPlaneSurface(const PlaneSurface &surface, const TrackSurfaceIntersection &trackIntersection, const double qOverP) const override
IIntersector interface method for specific Surface type : PlaneSurface.
virtual std::optional< TrackSurfaceIntersection > intersectSurface(const Surface &surface, const TrackSurfaceIntersection &trackIntersection, const double qOverP) const override
IIntersector interface method for general Surface type.
void initializeFieldCache(MagField::AtlasFieldCache &fieldCache) const
std::atomic< unsigned long long > m_countShortStep
virtual std::optional< TrackSurfaceIntersection > intersectCylinderSurface(const CylinderSurface &surface, const TrackSurfaceIntersection &trackIntersection, const double qOverP) const override
IIntersector interface method for specific Surface type : CylinderSurface.
const double m_momentumThreshold
virtual StatusCode finalize() override
void shortStep(TrackSurfaceIntersection &isect, const Amg::Vector3D &fieldValue, const double stepLength, const double qOverP) const
Amg::Vector3D field(const Amg::Vector3D &point, MagField::AtlasFieldCache &fieldCache) const
Class for a StraightLineSurface in the ATLAS detector to describe dirft tube and straw like detectors...
Abstract Base Class for tracking surfaces.
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
virtual constexpr SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
virtual const Amg::Vector3D & globalReferencePoint() const
Returns a global reference point on the surface, for PlaneSurface, StraightLineSurface,...
const Amg::Vector3D & center() const
Returns the center position of the Surface.
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.
double pathlength() const
Method to retrieve the pathlength propagated till the Intersection.
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.