ATLAS Offline Software
Loading...
Searching...
No Matches
TruthCalibrator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4#include "TruthCalibrator.h"
5
6#include "Acts/Utilities/CalibrationContext.hpp"
7
8
15
17#include "TruthUtils/AtlasPID.h"
18
19#include "Acts/Surfaces/PlaneSurface.hpp"
20#include "Acts/Definitions/Units.hpp"
21
22using namespace Acts::UnitLiterals;
23namespace{
25 inline Acts::BoundTrackParameters makeBoundPars(const ActsTrk::MutableTrackContainer::TrackStateProxy& state) {
26 return Acts::BoundTrackParameters{state.referenceSurface().getSharedPtr(),
27 state.parameters(), state.covariance(),
28 Acts::ParticleHypothesis::muon()};
29 }
30
31 const xAOD::MuonSimHit* getMatchingSimHit(const MuonR4::SpacePoint& sp) {
32 if (const xAOD::MuonSimHit* simHit = MuonR4::getTruthMatchedHit(*sp.primaryMeasurement());
33 simHit != nullptr) {
34 return simHit;
35 }
36 return sp.secondaryMeasurement() ? MuonR4::getTruthMatchedHit(*sp.secondaryMeasurement())
37 : nullptr;
38 }
39
40 Amg::Vector3D closestApproach(const Acts::GeometryContext& tgContext,
41 const Amg::Vector3D& pos,
42 const Amg::Vector3D& dir,
43 const MuonR4::SpacePoint& spacePoint) {
44
45 const xAOD::MuonSimHit* simHit = getMatchingSimHit(spacePoint);
48 if (simHit != nullptr && isMuon(simHit)) {
49 const Acts::Surface& measSurf{xAOD::muonSurface(spacePoint.primaryMeasurement())};
50 const Acts::Surface& secSurf{spacePoint.msSector()->surface()};
51 return secSurf.localToGlobalTransform(tgContext) *
52 measSurf.localToGlobalTransform(tgContext).inverse() *
53 xAOD::toEigen(simHit->localPosition());
54 }
56 if (!spacePoint.isStraw()) {
57 using namespace MuonR4::SegmentFit;
58 return SeedingAux::extrapolateToPlane(pos, dir, spacePoint);
59 }
60 using namespace Acts::detail::LineHelper;
62 return lineIntersect(pos, dir, spacePoint.localPosition(),
63 spacePoint.sensorDirection()).position();
64 }
65}
66
67namespace MuonR4 {
70
72 if (m_prdContainers.value().empty()) {
73 ATH_MSG_ERROR("No prd containers configured");
74 return StatusCode::SUCCESS;
75 }
76 ATH_MSG_DEBUG("Scheudle truth depenency on "<<m_prdContainers<<" using "<<m_simLinkDecor);
77 for (const std::string& prdCont : m_prdContainers){
78 m_truthLinks.emplace_back(std::format("{:}.{:}", prdCont, m_simLinkDecor.value()));
79 }
80 ATH_CHECK(m_truthLinks.initialize());
81 ATH_CHECK(m_ctxProvider.initialize());
82 return StatusCode::SUCCESS;
83 }
85 const SpacePoint* spacePoint,
86 const Amg::Vector3D& seedPosInChamb,
87 const Amg::Vector3D& seedDirInChamb,
88 const double /*timeDelay*/) const {
89
90 CalibSpacePointPtr calibSp{std::make_unique<CalibratedSpacePoint>(spacePoint,
91 closestApproach(m_ctxProvider.getGeometryContext(ctx),
92 seedPosInChamb, seedDirInChamb, *spacePoint))};
93
94 const xAOD::MuonSimHit* simHit = getMatchingSimHit(*spacePoint);
95 if (!simHit) {
96 calibSp->setFitState(CalibratedSpacePoint::State::Outlier);
97 }
99 if (spacePoint->isStraw()) {
100 if (!simHit) {
101 using namespace Acts::detail::LineHelper;
102 calibSp->setDriftRadius(signedDistance(seedPosInChamb, seedDirInChamb,
103 spacePoint->localPosition(),
104 spacePoint->sensorDirection()));
105 } else {
106 using namespace SegmentFit;
107 calibSp->setDriftRadius(spacePoint->localPosition().perp() *
108 SeedingAux::strawSign(seedPosInChamb, seedDirInChamb, *calibSp));
109 }
110 }
111 return calibSp;
112 }
113
115 const CalibratedSpacePoint& spacePoint,
116 const Amg::Vector3D& seedPosInChamb,
117 const Amg::Vector3D& seedDirInChamb,
118 const double timeDelay) const {
119 if (!spacePoint.spacePoint()) {
120 CalibSpacePointPtr copy{std::make_unique<CalibratedSpacePoint>(spacePoint)};
121 copy->setFitState(CalibratedSpacePoint::State::Outlier);
122 return copy;
123 }
124 return calibrate(ctx, spacePoint.spacePoint(), seedPosInChamb, seedDirInChamb, timeDelay);
125 }
127 const std::vector<const SpacePoint*>& spacePoints,
128 const Amg::Vector3D& seedPosInChamb,
129 const Amg::Vector3D& seedDirInChamb,
130 const double timeDelay) const {
131 CalibSpacePointVec result{};
132 std::ranges::transform(spacePoints, std::back_inserter(result), [&](const SpacePoint* sp){
133 return calibrate(ctx, sp, seedPosInChamb, seedDirInChamb, timeDelay);
134 });
135 return result;
136 }
137
138 CalibSpacePointVec TruthCalibrator::calibrate(const Acts::CalibrationContext& cctx,
139 const Amg::Vector3D& seedPosInChamb,
140 const Amg::Vector3D& seedDirInChamb,
141 const double timeDelay,
142 const CalibSpacePointVec& spacePoints) const {
143 CalibSpacePointVec result{};
145 std::ranges::transform(spacePoints,std::back_inserter(result), [&](const CalibSpacePointPtr& sp){
146 return calibrate(*cctx.get<const EventContext*>(), *sp,
147 seedPosInChamb, seedDirInChamb, timeDelay);
148 });
149 return result;
150 }
151 double TruthCalibrator::driftVelocity(const Acts::CalibrationContext& /*cctx*/,
152 const CalibratedSpacePoint& /*spacePoint*/) const{
153 ATH_MSG_WARNING(__func__<<"() - Implement me ");
154 return 0.;
155 }
156
157 void TruthCalibrator::calibrateSourceLink(const Acts::GeometryContext& tgContext,
158 const Acts::CalibrationContext& /*cctx*/,
159 const Acts::SourceLink& link,
160 ActsTrk::MutableTrackStateBackend::TrackStateProxy state) const {
161 const auto* uncalib = dynamic_cast<const xAOD::MuonMeasurement*>(ActsTrk::detail::xAODUncalibMeasCalibrator::unpack(link));
162 assert(uncalib != nullptr);
163
164 const xAOD::MuonSimHit* simHit{getTruthMatchedHit(*uncalib)};
165 if (!simHit && uncalib->numDimensions() == 0) {
166 const auto* strip = dynamic_cast<const xAOD::CombinedMuonStrip*>(uncalib);
167 simHit = getTruthMatchedHit(*strip->primaryStrip());
168 if (!simHit) {
169 simHit = getTruthMatchedHit(*strip->secondaryStrip());
170 }
171 }
172 const auto boundPars{makeBoundPars(state)};
173 const Acts::Surface& surface{boundPars.referenceSurface()};
174 assert(surface.geometryId() == xAOD::muonSurface(uncalib).geometryId());
175 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Calibrate muon measurement "
176 <<uncalib->readoutElement()->idHelperSvc()->toString(uncalib->identify())
177 <<", @"<<surface.geometryId()
178 <<", is truth "<<(simHit != nullptr)
179 <<", parameters:\n"<<boundPars
180 <<",\n direction: "<<Amg::toString(boundPars.direction())
181 <<", momentum: "<<boundPars.absoluteMomentum());
183 if (simHit !=nullptr) {
184 const Amg::Vector3D locPos = xAOD::toEigen(simHit->localPosition());
185 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Sim hit position "<<Amg::toString(locPos)
186 <<", angle: "
187 <<Amg::angle(surface.localToGlobalTransform(tgContext).linear()*xAOD::toEigen(simHit->localDirection()),
188 boundPars.direction()) / 1._degree);
189 if (uncalib->type() != xAOD::UncalibMeasType::MdtDriftCircleType) {
190 if (uncalib->numDimensions() == 1) {
191 setState<1>(uncalib->measuresPhi() ?
194 locPos.block<1,1>(uncalib->measuresPhi(),0),
195 uncalib->localCovariance<1>(), link, state);
196 } else {
197 setState<2>(ProjectorType::e2DimNoTime, locPos.block<2,1>(0,0),
198 uncalib->localCovariance<2>(), link, state);
199 }
200 } else {
201 using namespace Acts::detail::LineHelper;
202 const double r = signedDistance(locPos, xAOD::toEigen(simHit->localDirection()),
203 Amg::Vector3D::Zero(),Amg::Vector3D::UnitZ());
204 const double z = simHit->localPosition().z();
205 if (uncalib->numDimensions() == 1) {
206 setState<1>(ProjectorType::e1DimNoTime, Acts::Vector<1>{r},
207 uncalib->localCovariance<1>(), link, state);
208 } else {
209 setState<2>(ProjectorType::e2DimNoTime, Acts::Vector2{r, z},
210 uncalib->localCovariance<2>(), link, state);
211 }
212 }
213 } else {
214 if (uncalib->numDimensions() == 1) {
215 setState<1>(ProjectorType::e1DimNoTime, state.parameters().block<1,1>(0,0),
216 uncalib->localCovariance<1>(), link, state);
217 } else {
218 setState<2>(ProjectorType::e2DimNoTime, state.parameters().block<2,1>(0,0),
219 uncalib->localCovariance<2>(), link, state);
220 }
221 }
222 }
223
225 const Amg::Vector3D& /*trackDir*/,
226 CalibSpacePointVec& /*hitsToCalib*/) const {
228 }
231 }
232
233 double TruthCalibrator::driftRadius(const Acts::CalibrationContext& /*cctx*/,
234 const CalibratedSpacePoint& /*spacePoint*/,
235 const double /*timeDelay*/) const {
236 ATH_MSG_WARNING(__func__<<"() - Implement me ");
237 return 0.;
238 }
239
240 double TruthCalibrator::driftVelocity(const Acts::CalibrationContext& /*cctx*/,
241 const CalibratedSpacePoint& /*spacePoint*/,
242 const double /*timeDelay*/) const {
243 ATH_MSG_WARNING(__func__<<"() - Implement me ");
244 return 0.;
245 }
246 double TruthCalibrator::driftAcceleration(const Acts::CalibrationContext& /*cctx*/,
247 const CalibratedSpacePoint& /*spacePoint*/,
248 const double /*timeDelay*/) const {
249 ATH_MSG_WARNING(__func__<<"() - Implement me ");
250 return 0.;
251 }
252
253 double TruthCalibrator::driftAcceleration(const Acts::CalibrationContext& /*cctx*/,
254 const CalibratedSpacePoint& /*spacePoint*/) const {
255 ATH_MSG_WARNING(__func__<<"() - Implement me ");
256 return 0.;
257 }
258}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
bool isMuon(const T &p)
Definition AtlasPID.h:211
static Double_t sp
#define z
ProjectorType
Enum encoding the possible projectors used in ATLAS.
@ e2DimNoTime
Project out solely the locY - Complementary projector if the strip plane is rotated (Applies to Itk e...
@ e1DimRotNoTime
Project out solely the locX (Applies to Itk strips, Rpc, Tgc, sTgc, Mm).
void setState(const ProjectorType projector, const pos_t &locpos, const cov_t &cov, Acts::SourceLink link, proxy_t &trackState) const
Copy the local position & covariance into the Acts track state proxy.
static const xAOD::UncalibratedMeasurement * unpack(const Acts::SourceLink &sl)
Helper method to unpack an Acts source link to an uncalibrated measurement.
const Acts::PlaneSurface & surface() const
Returns the associated surface.
The calibrated Space point is created during the calibration process.
const SpacePoint * spacePoint() const
The pointer to the space point out of which this space point has been built.
Acts::CloneablePtr< CalibratedSpacePoint > CalibSpacePointPtr
std::vector< CalibSpacePointPtr > CalibSpacePointVec
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
bool isStraw() const
Returns whether the measurement is a Mdt.
virtual double driftRadius(const Acts::CalibrationContext &cctx, const CalibratedSpacePoint &spacePoint, const double timeDelay) const override final
Returns the drift radius for a given drift-circle space point and time delay.
ActsTrk::ContextUtility m_ctxProvider
Context utility object to retrieve the geometry context.
virtual double driftAcceleration(const Acts::CalibrationContext &cctx, const CalibratedSpacePoint &spacePoint, const double timeDelay) const override final
Returns the drift acceleration (in ACTS units) for a given drift-circle space point.
virtual StatusCode initialize() override final
virtual void updateSigns(const Amg::Vector3D &trackPos, const Amg::Vector3D &trackDir, CalibSpacePointVec &hitsToCalib) const override final
Update the signs of the drift radii for a given straight line track to fix the left <-> right ambigui...
SG::ReadDecorHandleKeyArray< xAOD::UncalibratedMeasurementContainer > m_truthLinks
Dependencies on the truth matching of the uncalibrated measurement containers.
virtual CalibSpacePointPtr calibrate(const EventContext &ctx, const SpacePoint *spacePoint, const Amg::Vector3D &seedPosInChamb, const Amg::Vector3D &seedDirInChamb, const double timeDelay) const override final
Calibrates a single space point.
Gaudi::Property< std::vector< std::string > > m_prdContainers
Container names of the muon prd containers.
virtual void stampSignsOnMeasurements(const xAOD::MuonSegment &segment) const override final
Stamps the signs of the drift radii w.r.t.
virtual double driftVelocity(const Acts::CalibrationContext &cctx, const CalibratedSpacePoint &spacePoint) const override final
Returns the drift velocity (in ACTS units) for a given drift-circle space point.
Gaudi::Property< std::string > m_simLinkDecor
Decoration of the truth link.
virtual void calibrateSourceLink(const Acts::GeometryContext &geoctx, const Acts::CalibrationContext &cctx, const Acts::SourceLink &link, ActsTrk::MutableTrackStateBackend::TrackStateProxy state) const override final
Function that's hooked to the calibration delegate of the implemented Acts fitters.
ConstVectorMap< 3 > localDirection() const
Returns the local direction of the traversing particle.
ConstVectorMap< 3 > localPosition() const
Returns the local postion of the traversing particle.
int r
Definition globals.cxx:22
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
double angle(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
calculates the opening angle between two vectors
Eigen::Matrix< double, 3, 1 > Vector3D
This header ties the generic definitions in this package.
ISpacePointCalibrator::CalibSpacePointVec CalibSpacePointVec
const xAOD::MuonSimHit * getTruthMatchedHit(const xAOD::MuonMeasurement &prdHit)
Returns the MuonSimHit, if there's any, matched to the uncalibrated muon measurement.
ISpacePointCalibrator::CalibSpacePointPtr CalibSpacePointPtr
MuonMeasurement_v1 MuonMeasurement
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12
MuonSegment_v1 MuonSegment
Reference the current persistent version:
const Acts::Surface & muonSurface(const UncalibratedMeasurement *meas)
Returns the associated Acts surface to the measurement.
CombinedMuonStrip_v1 CombinedMuonStrip