48 const Acts::GeometryContext tgContext{gctx->
context()};
50 auto extrapolate = [&](
const Acts::BoundTrackParameters& start,
55 Amg::Vector3D::Zero(),
56 Amg::Vector3D::Zero());
59 trf.linear() *
sp.sensorDirection(),
60 start.position(tgContext),
64 n.dot(target.center(tgContext)));
68 <<
Amg::toString(start.direction())<<
" onto surface: "<<target.toString(tgContext)
70 <<
" geoId: "<<target.geometryId()<<
", "<<( lambda.value_or(0.) > 0 ?
"forward" :
"backward"));
73 ? Acts::Direction::Forward()
74 : Acts::Direction::Backward(), 100._m);
77 StatusCode retCode = StatusCode::SUCCESS;
79 SeedingAux::Config cfg{};
80 cfg.parsToUse.clear();
83 SeedingAux::Line_t line{};
96 Acts::ObjVisualization3D visualHelper{};
100 Acts::ViewConfig{.color = {220, 0, 0}});
104 if (
msgLvl(MSG::VERBOSE)) {
105 std::stringstream sstr{};
108 <<
", chi2/nDoF: "<<segment->chiSquared() / segment->numberDoF()
109 <<
", nDoF: "<<segment->numberDoF()<<
", "
110 <<segment->nPrecisionHits()<<
", "<<segment->nPhiLayers()<<std::endl;
112 sstr<<
" **** "<<(*meas)<<
", chi2: "<<SeedingAux::chi2Term(line, *meas)
113 <<
", sign: "<<(meas->isStraw() ?
114 (SeedingAux::strawSign(line, *meas) == 1 ?
"R" :
"L") :
"-")
117 : Acts::GeometryIdentifier{})
123 if (!meas->spacePoint() ||
124 meas->fitState() != MuonR4::CalibratedSpacePoint::State::Valid) {
127 const auto sp = meas->spacePoint();
130 const auto& bounds = targetSurf.bounds();
131 Amg::Vector2D lPos{Amg::Vector2D::Zero()}, mPos{Amg::Vector2D::Zero()};
132 const Amg::Transform3D toSurf = targetSurf.localToGlobalTransform(tgContext).inverse() *
133 sector->
surface().localToGlobalTransform(tgContext);
134 if (targetSurf.type() == Acts::Surface::SurfaceType::Plane) {
135 lPos = (toSurf * SeedingAux::extrapolateToPlane(line, *meas)).block<2,1>(0,0);
136 if (!bounds.inside(lPos, Acts::BoundaryTolerance::AbsoluteEuclidean(-2._mm))){
138 <<
" is outside the trapezoid "<<bounds
142 mPos = (toSurf * meas->localPosition()).block<2,1>(0,0);
143 }
else if (targetSurf.type() == Acts::Surface::SurfaceType::Straw) {
144 const auto cIsect = lineIntersect<3>(meas->localPosition(), meas->sensorDirection(),
145 line.position(), line.direction());
146 const auto cIsectPos = cIsect.position();
148 lPos[0] = Acts::copySign(closePos.perp(), SeedingAux::strawSign(line, *meas));
149 lPos[1] = closePos.z();
150 mPos[0] = Acts::copySign(meas->driftRadius(), lPos[0]);
151 if (meas->measuresPhi()) {
152 mPos[1] = meas->localPosition().x();
154 const auto& lBounds =
static_cast<const Acts::LineBounds&
>(bounds);
155 if (std::abs(closePos.z()) > lBounds.get(Acts::LineBounds::eHalfLengthZ) - 2._cm ||
156 closePos.perp() >lBounds.get(Acts::LineBounds::eR) - 0.2_mm) {
163 auto extpPars = extrapolate(startPars, *
sp);
164 if (!extpPars.ok()) {
166 <<
",\n lPos: "<<
Amg::toString(toSurf * meas->localPosition())
167 <<
", expected: "<<
Amg::toString(lPos)<<
", "<<targetSurf.bounds());
168 retCode = StatusCode::FAILURE;
174 Acts::ViewConfig{.color = {0, 0, 220}}, 6._cm);
177 if (targetSurf.type() == Acts::Surface::SurfaceType::Plane) {
181 const Amg::Vector2D dPos = (*extpPars).localPosition() - lPos;
182 if (dPos.mag() > 0.1_mm) {
185 retCode = StatusCode::FAILURE;
187 }
else if (targetSurf.type() == Acts::Surface::SurfaceType::Straw) {
188 const double dist = lPos[0];
189 const double extDist = (*extpPars).parameters()[Acts::eBoundLoc0];
190 const double extLocZ = (*extpPars).parameters()[Acts::eBoundLoc1];
191 const double cov = meas->covariance()[Acts::toUnderlying(AxisDefs::etaCov)];
193 <<
" straight: "<<dist<<
", extrapolated: "<<extDist
194 <<
"--> "<<(extDist - dist ) / std::sqrt(cov)
195 <<
", along the tube: "<<lPos[1]<<
", extrapolated: "<<extLocZ);
196 if (std::abs(dist - extDist) / std::sqrt(cov) > 0.05 ||
197 std::abs(lPos[1] - extLocZ) > 0.1_mm) {
199 <<
", "<<
Amg::toString(lPos)<<
" vs. ("<<extDist<<
", "<<extLocZ<<
")"
200 <<
", deviate R: "<<(std::abs(dist -extDist) / std::sqrt(cov))
201 <<
", deviate Z: "<<std::abs(lPos[1] - extLocZ));
202 retCode = StatusCode::FAILURE;
206 pullCalculator.updateSpatialResidual(line, *meas);
209 cov(0,0) = 1./meas->covariance()[1];
210 cov(1,1) = 1./meas->covariance()[0];
212 <<
" / "<<targetSurf.geometryId()<<
" --- measurement: "<<
Amg::toString(mPos)<<
", extraploated: "
214 <<
Amg::toString(pullCalculator.residual())<<
", chi2: "<<pullCalculator.chi2Term(line, *meas)
215 <<
" vs. "<<
res.dot(cov*
res));
218 visualHelper.write(std::format(
"ExtTpTest_{:}_{:}_{:}.obj",
219 ctx.eventID().event_number(), segment->index(),
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
Dependency on the geometry alignment.
Gaudi::Property< bool > m_drawEvent
Option to draw every extrapolation asan obj file.
const MuonGMR4::MuonDetectorManager * m_detMgr
Detector manager to fetch the sector surfaces.
SG::ReadHandleKey< xAOD::MuonSegmentContainer > m_readKey
Declare the data dependency on the standard Mdt+Rpc+Tgc segment container.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
IdHelperSvc to decode the Identifiers.