ATLAS Offline Software
SegmentExtpTest.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "SegmentExtpTest.h"
6 
9 #include "StoreGate/ReadHandle.h"
11 
12 #include "Acts/Definitions/Units.hpp"
13 #include "Acts/Surfaces/LineBounds.hpp"
14 #include "Acts/Surfaces/PlaneSurface.hpp"
15 
19 
21 #include "GaudiKernel/PhysicalConstants.h"
23 
24 #include "Acts/Visualization/ObjVisualization3D.hpp"
25 #include "Acts/Visualization/GeometryView3D.hpp"
27 
28 
29 using namespace Acts::UnitLiterals;
30 using namespace MuonR4::SegmentFit;
31 using namespace Acts::detail::LineHelper;
32 
33 namespace MuonValR4{
35  ATH_CHECK(m_readKey.initialize());
36  ATH_CHECK(m_geoCtxKey.initialize());
37  ATH_CHECK(m_idHelperSvc.retrieve());
38  ATH_CHECK(m_extrapolationTool.retrieve());
39  ATH_CHECK(detStore()->retrieve(m_detMgr));
40  return StatusCode::SUCCESS;
41  }
42  StatusCode SegmentExtpTest::execute(const EventContext& ctx) const {
43  const xAOD::MuonSegmentContainer* segments{nullptr};
44  ATH_CHECK(SG::get(segments, m_readKey, ctx));
45  const ActsTrk::GeometryContext* gctx{nullptr};
46  ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
47  const auto tgContext = gctx->context();
48 
49  auto extrapolate = [&](const Acts::BoundTrackParameters& start,
50  const MuonR4::SpacePoint& sp) {
51  const Amg::Transform3D& trf = sp.msSector()->localToGlobalTrans(*gctx);
52  const Acts::Surface& target = xAOD::muonSurface(sp.primaryMeasurement());
53  const Amg::Vector3D n = target.normal(tgContext,
56 
57  auto lambda = sp.isStraw() ? Amg::intersect<3>(trf * sp.localPosition(),
58  trf.linear() * sp.sensorDirection(),
59  start.position(tgContext),
60  start.direction())
61  : Amg::intersect<3>(start.position(tgContext),
62  start.direction(), n,
63  n.dot(target.center(tgContext)));
64 
65  const auto* detEl = static_cast<const ActsTrk::IDetectorElementBase*>(target.associatedDetectorElement());
66  ATH_MSG_VERBOSE("Propagate "<<Amg::toString(start.position(tgContext))<<" + "
67  <<Amg::toString(start.direction())<<" onto surface: "<<target.toString(tgContext)
68  <<"\n, "<<m_idHelperSvc->toString(detEl->identify())
69  << " geoId: "<<target.geometryId()<<", "<<( lambda.value_or(0.) > 0 ? "forward" : "backward"));
70 
71  return m_extrapolationTool->propagate(ctx, start, target, lambda.value_or(0.) > 0
72  ? Acts::Direction::Forward()
73  : Acts::Direction::Backward(), 100._m);
74 
75  };
76  StatusCode retCode = StatusCode::SUCCESS;
77  for (const xAOD::MuonSegment* segment : *segments) {
78  const MuonR4::Segment* detSeg = MuonR4::detailedSegment(*segment);
79 
80  const auto segPars = localSegmentPars(*segment);
81  const auto [locPos, locDir] = makeLine(segPars);
82 
83  const MuonGMR4::SpectrometerSector* sector = m_detMgr->getSectorEnvelope(segment->chamberIndex(),
84  segment->sector(),
85  segment->etaIndex());
86  auto startPars = boundSegmentPars(*gctx, *detSeg);
87 
88  Acts::ObjVisualization3D visualHelper{};
89  if (m_drawEvent) {
91  drawSegmentLine(*gctx, *segment, visualHelper,
92  Acts::ViewConfig{.color = {220, 0, 0}});
93  drawSegmentMeasurements(*gctx, *segment, visualHelper, Acts::s_viewSurface);
94  }
95 
96  if (msgLvl(MSG::VERBOSE)) {
97 
98  std::stringstream sstr{};
99  sstr<<"pos: "<<Amg::toString(segment->position())<<", dir: "
100  <<Amg::toString(segment->direction())<<", chi2/nDoF: "
101  <<segment->chiSquared() / segment->numberDoF()<<", nDoF: "<<segment->numberDoF()<<", "
102  <<segment->nPrecisionHits()<<", "<<segment->nPhiLayers()<<std::endl;
103  for (const auto& meas : detSeg->measurements()) {
104  sstr<<" **** "<<(*meas)<<", chi2: "<<SeedingAux::chi2Term(locPos, locDir, *meas)
105  <<", sign: "<<(meas->isStraw() ?
106  (SeedingAux::strawSign(locPos,locDir, *meas) == 1 ? "R" : "L") : "-")
107  <<", geoId: "<<(meas->type() != xAOD::UncalibMeasType::Other ?
108  xAOD::muonSurface(meas->spacePoint()->primaryMeasurement()).geometryId()
109  : Acts::GeometryIdentifier{})
110  <<std::endl;
111  }
112  ATH_MSG_VERBOSE("Run propagation test on "<<sector->identString()<<std::endl<<sstr.str());
113  }
114 
115  for (const auto& meas: detSeg->measurements()) {
116  if (!meas->spacePoint() ||
117  meas->fitState() != MuonR4::CalibratedSpacePoint::State::Valid) {
118  continue;
119  }
120  const auto sp = meas->spacePoint();
121  const Acts::Surface& targetSurf{xAOD::muonSurface(sp->primaryMeasurement())};
122 
123  const auto& bounds = targetSurf.bounds();
125  const auto trf = targetSurf.transform(tgContext).inverse() *
126  sector->surface().transform(tgContext);
127  if (targetSurf.type() == Acts::Surface::SurfaceType::Plane) {
128  lPos = (trf * SeedingAux::extrapolateToPlane(locPos, locDir, *meas)).block<2,1>(0,0);
129  if (!bounds.inside(lPos, Acts::BoundaryTolerance::AbsoluteEuclidean(-2._mm))){
130  ATH_MSG_WARNING("The position "<<Amg::toString(lPos)
131  <<" is outside the trapezoid "<<bounds
132  <<" "<<m_idHelperSvc->toString(sp->identify()));
133  continue;
134  }
135  } else if (targetSurf.type() == Acts::Surface::SurfaceType::Straw) {
136  const auto cIsect = lineIntersect<3>(meas->localPosition(),
137  meas->sensorDirection(),
138  locPos, locDir);
139  const auto cIsectPos = cIsect.position();
140  const auto cPos = trf * cIsectPos;
141  lPos[0] = cPos.perp() * SeedingAux::strawSign(locPos, locDir, *meas);
142  lPos[1] = cPos.z();
143  const auto& lBounds = static_cast<const Acts::LineBounds&>(bounds);
144  if (std::abs(cPos.z()) > lBounds.get(Acts::LineBounds::eHalfLengthZ) - 2._cm ||
145  cPos.perp() >lBounds.get(Acts::LineBounds::eR) - 0.2_mm) {
146  ATH_MSG_WARNING("The line is not on measurement "
147  <<m_idHelperSvc->toString(sp->identify())
148  <<" "<<Amg::toString(lPos)<<" vs. "<<bounds<<".");
149  continue;
150  }
151  }
152  auto extpPars = extrapolate(startPars, *sp);
153  if (!extpPars) {
154  ATH_MSG_FATAL("Failed to propagte to "<<(*meas)
155  <<",\n lPos: "<<Amg::toString(trf * meas->localPosition())
156  <<", expected: "<<Amg::toString(lPos)<<", "<<targetSurf.bounds());
157  retCode = StatusCode::FAILURE;
158  continue;
159  }
160  if (m_drawEvent) {
162  drawBoundParameters(*gctx, *extpPars, visualHelper,
163  Acts::ViewConfig{.color = {0, 0, 220}}, 6._cm);
164  }
165 
166  if (targetSurf.type() == Acts::Surface::SurfaceType::Plane) {
167  ATH_MSG_DEBUG("Position on "<<m_idHelperSvc->toString(sp->identify())
168  <<" plane "<<Amg::toString(lPos)<<" vs. "
169  <<Amg::toString((*extpPars).localPosition()));
170  const Amg::Vector2D dPos = (*extpPars).localPosition() - lPos;
171  if (dPos.mag() > 0.1_mm) {
172  ATH_MSG_FATAL("Too large deviation on "<<m_idHelperSvc->toString(sp->identify())
173  <<", "<<Amg::toString(dPos));
174  retCode = StatusCode::FAILURE;
175  }
176  } else if (targetSurf.type() == Acts::Surface::SurfaceType::Straw) {
177  const double dist = lPos[0];
178  const double extDist = (*extpPars).parameters()[Acts::eBoundLoc0];
179  const double extLocZ = (*extpPars).parameters()[Acts::eBoundLoc1];
180  const double cov = meas->covariance()[Acts::toUnderlying(AxisDefs::etaCov)];
181  ATH_MSG_DEBUG("Distance on surface "<<m_idHelperSvc->toString(sp->identify())
182  <<" straight: "<<dist<<", extrapolated: "<<extDist
183  <<"--> "<<(extDist - dist ) / std::sqrt(cov)
184  <<", along the tube: "<<lPos[1]<<", extrapolated: "<<extLocZ);
185  if (std::abs(dist - extDist) / std::sqrt(cov) > 0.05 ||
186  std::abs(lPos[1] - extLocZ) > 0.1_mm) {
187  ATH_MSG_FATAL("Too large deviation on "<<m_idHelperSvc->toString(sp->identify())
188  <<", "<<Amg::toString(lPos)<<" vs. ("<<extDist<<", "<<extLocZ<<")"
189  <<", deviate R: "<<(std::abs(dist -extDist) / std::sqrt(cov))
190  <<", deviate Z: "<<std::abs(lPos[1] - extLocZ));
191  retCode = StatusCode::FAILURE;
192  }
193  }
194  }
195  if (m_drawEvent) {
196  visualHelper.write(std::format("ExtTpTest_{:}_{:}_{:}.obj",
197  ctx.eventID().event_number(), segment->index(),
198  MuonR4::printID(*segment)));
199  }
200  }
201 
202  return retCode;
203  }
204 
205 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
MuonR4::printID
std::string printID(const xAOD::MuonSegment &seg)
Print the chamber ID of a segment, e.g.
Definition: TrackingHelpers.cxx:17
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
UtilFunctions.h
MuonR4::SegmentFit
Definition: MuonHoughDefs.h:34
MuonGMR4::SpectrometerSector
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
Definition: SpectrometerSector.h:40
vtune_athena.format
format
Definition: vtune_athena.py:14
MuonR4::CalibratedSpacePoint::State::Valid
@ Valid
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
initialize
void initialize()
Definition: run_EoverP.cxx:894
mergePhysValFiles.start
start
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:13
MuonR4::Segment
Placeholder for what will later be the muon segment EDM representation.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:19
MuonR4::Segment::measurements
const MeasVec & measurements() const
Returns the associated measurements.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:49
MuonR4::SegmentFit::boundSegmentPars
Acts::BoundTrackParameters boundSegmentPars(const MuonGMR4::MuonDetectorManager &detMgr, const xAOD::MuonSegment &segment, std::optional< Acts::BoundMatrix > cov=std::nullopt, Acts::ParticleHypothesis hypot=Acts::ParticleHypothesis::muon())
Returns the segment parameters as boundTrackParameters.
Definition: SegmentFitterEventData.cxx:85
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:200
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SpectrometerSector.h
MuonR4::SegmentFit::makeLine
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
Definition: SegmentFitterEventData.cxx:35
MuonGMR4::SpectrometerSector::identString
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
Definition: SpectrometerSector.cxx:66
MuonValR4::drawSegmentLine
void drawSegmentLine(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine, const double standardLength=1.*Gaudi::Units::m)
Draw a segment line inside the obj file.
Definition: ObjVisualizationHelpers.cxx:46
MuonR4::detailedSegment
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Definition: TrackingHelpers.cxx:24
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
ActsTrk::IDetectorElementBase
base class interface providing the bare minimal interface extension.
Definition: IDetectorElement.h:32
SG::get
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition: ReadCondHandle.h:283
beamspotman.n
n
Definition: beamspotman.py:727
UnitConverters.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
ObjVisualizationHelpers.h
xAOD::Other
@ Other
MuonGMR4::SpectrometerSector::surface
const Acts::PlaneSurface & surface() const
Returns the associated surface.
Definition: SpectrometerSector.cxx:72
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrk::GeometryContext
Definition: GeometryContext.h:28
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
MdtDriftCircle.h
MuonR4::SpacePoint
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/MuonSpacePoint/SpacePoint.h:24
MuonValR4
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
Definition: IPatternVisualizationTool.h:23
AthReentrantAlgorithm.h
TrackingHelpers.h
TgcStrip.h
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
xAOD::Straw
@ Straw
Definition: TrackingPrimitives.h:558
MuonValR4::drawSegmentMeasurements
void drawSegmentMeasurements(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw all uncalibrated measurements associated to the segment.
Definition: ObjVisualizationHelpers.cxx:81
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
xAOD::muonSurface
const Acts::Surface & muonSurface(const UncalibratedMeasurement *meas)
Returns the associated Acts surface to the measurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:68
python.copyTCTOutput.locDir
locDir
Definition: copyTCTOutput.py:110
MuonValR4::drawBoundParameters
void drawBoundParameters(const ActsTrk::GeometryContext &gctx, const Acts::BoundTrackParameters &pars, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine, const double standardLength=3.*Gaudi::Units::cm)
Draw a line representing the bound track parameters.
Definition: ObjVisualizationHelpers.cxx:175
SegmentFitterEventData.h
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
copySelective.target
string target
Definition: copySelective.py:36
MuonR4::SegmentFit::localSegmentPars
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
Definition: SegmentFitterEventData.cxx:42
MuonHough::extrapolate
float extrapolate(const MuonLayerHough::Maximum &ref, const MuonLayerHough::Maximum &ex, bool doparabolic=false)
Definition: MuonLayerHough.cxx:521
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
CaloLCW_tf.trf
trf
Definition: CaloLCW_tf.py:20
ReadHandle.h
Handle class for reading from StoreGate.
xAOD::Plane
@ Plane
Definition: TrackingPrimitives.h:557
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
SegmentExtpTest.h