ATLAS Offline Software
Loading...
Searching...
No Matches
TrkSegmentCnvAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4#include "TrkSegmentCnvAlg.h"
6
13
14
15namespace MuonR4{
16
18 ATH_CHECK(m_idHelperSvc.retrieve());
19 ATH_CHECK(m_keyTgc.initialize(!m_keyTgc.empty()));
20 ATH_CHECK(m_keyRpc.initialize(!m_keyRpc.empty()));
21 ATH_CHECK(m_keyMdt.initialize(!m_keyMdt.empty()));
22 ATH_CHECK(m_keysTgc.initialize(!m_keysTgc.empty()));
23 ATH_CHECK(m_keyMM.initialize(!m_keyMM.empty()));
24 ATH_CHECK(m_readKeys.initialize());
25 ATH_CHECK(m_writeKey.initialize());
26 ATH_CHECK(m_mdtCreator.retrieve());
27 ATH_CHECK(m_clusterCreator.retrieve());
28 ATH_CHECK(m_compClusterCreator.retrieve(EnableTool{!m_keyTgc.empty() || !m_keyRpc.empty()}));
29 ATH_CHECK(m_geoCtxKey.initialize());
30 return StatusCode::SUCCESS;
31 }
32
33 StatusCode TrkSegmentCnvAlg::execute(const EventContext& ctx) const {
34
35 auto translatedSegments = std::make_unique<Trk::SegmentCollection>();
37 const SegmentContainer* translateMe{nullptr};
38 ATH_CHECK(SG::get(translateMe, key, ctx));
39 for (const Segment* segment : *translateMe) {
40 ATH_CHECK(convert(ctx, *segment, *translatedSegments));
41 }
42 }
43 ATH_MSG_VERBOSE("Translated in total "<<translatedSegments->size()<<" segments.");
44
45 SG::WriteHandle writeHandle{m_writeKey, ctx};
46 ATH_CHECK(writeHandle.record(std::move(translatedSegments)));
47 return StatusCode::SUCCESS;
48 }
49 template <class PrdType>
50 const PrdType* TrkSegmentCnvAlg::fetchPrd(const Identifier& prdId,
51 const Muon::MuonPrepDataContainerT<PrdType>* prdContainer) const {
52 if (!prdContainer) {
53 ATH_MSG_ERROR("Cannot fetch a prep data object as the container given for "<<
54 m_idHelperSvc->toString(prdId)<<" is a nullptr");
55 return nullptr;
56 }
57 const Muon::MuonPrepDataCollection<PrdType>* coll = prdContainer->indexFindPtr(m_idHelperSvc->moduleHash(prdId));
58 if (!coll) {
59 ATH_MSG_ERROR("No prep data collection where "<<m_idHelperSvc->toString(prdId)<<" can reside in.");
60 return nullptr;
61 }
62 for (const PrdType* prd : *coll) {
63 if (prd->identify() == prdId){
64 return prd;
65 }
66 }
67 ATH_MSG_ERROR("There is no measurement "<<m_idHelperSvc->toString(prdId));
68
69 return nullptr;
70 }
71 template <class PrdType>
73 const std::string& accName) const {
75 SG::ConstAccessor<Link_t> acc{accName};
76 if (!acc.isAvailable(meas) || !acc(meas).isValid()) {
77 ATH_MSG_WARNING(__func__<<"() "<<__LINE__<<" - No link decoration "<<accName<<" for measurement "
78 <<m_idHelperSvc->toString(meas.identify()));
79 return nullptr;
80 }
81 return *acc(meas);
82 }
83 template <class PrdType>
85 const CalibratedSpacePoint& spacePoint,
86 const Muon::MuonPrepDataContainerT<PrdType>* prdContainer,
87 std::vector<std::unique_ptr<Trk::RIO_OnTrack>>& convMeasVec,
88 const std::string& accName) const {
89 bool added{false};
90
91 for (const xAOD::MuonMeasurement* uncalib: {spacePoint.spacePoint()->primaryMeasurement(),
92 spacePoint.spacePoint()->secondaryMeasurement()}){
93 if (!uncalib) {
94 continue;
95 }
96 added = true;
97
98 const PrdType* prd{nullptr};
99 if (!accName.empty()) {
100 prd = fetchPrd<PrdType>(*uncalib, accName);
101 }
102 if (!prd) {
103 prd = fetchPrd(uncalib->identify(), prdContainer);
104 }
105 if (!prd) {
106 ATH_MSG_FATAL("Failed to retrieve segment from "<<m_idHelperSvc->toString(uncalib->identify()));
107 return StatusCode::FAILURE;
108 }
109 const Trk::Surface& surf{prd->detectorElement()->surface(prd->identify())};
110 Trk::Intersection isect = surf.straightLineIntersection(segment.position(), segment.direction());
111
112 std::unique_ptr<Trk::RIO_OnTrack> rot{};
113 if constexpr(std::is_same_v<PrdType, Muon::MdtPrepData>) {
114 rot = std::unique_ptr<Trk::RIO_OnTrack>{m_mdtCreator->createRIO_OnTrack(*prd,
115 isect.position,
116 &segment.direction())};
117 } else {
118 rot = std::unique_ptr<Trk::RIO_OnTrack>{m_clusterCreator->createRIO_OnTrack(*prd,
119 isect.position,
120 segment.direction())};
121 if constexpr (std::is_same_v<PrdType, Muon::sTgcPrepData>) {
122 const sTgcIdHelper& idHelper{m_idHelperSvc->stgcIdHelper()};
123 if (!rot && idHelper.channelType(prd->identify()) == sTgcIdHelper::sTgcChannelTypes::Wire) {
124 const Amg::Vector3D locPos = prd->detectorElement()->transform(prd->identify()).inverse() *
125 isect.position;
126 if (prd->detectorElement()->isEtaZero(prd->identify(), locPos.block<2,1>(0,0))){
127 ATH_MSG_WARNING("Hit from inactive region "<<m_idHelperSvc->toString(prd->identify())
128 <<", "<<Amg::toString(locPos)<<" cannot be translated.");
129 continue;
130 }
131 }
132 }
133 }
134 if(!rot && m_idHelperSvc->issTgc(prd->identify())) {
135 ATH_MSG_WARNING("sTGC ROT creation failed for "<<m_idHelperSvc->toString(prd->identify()));
136 continue;
137 }
138
139 if (!rot) {
140 ATH_MSG_ERROR("Failed to create rot from "<<m_idHelperSvc->toString(prd->identify()));
141 return StatusCode::FAILURE;
142 }
143 ATH_MSG_VERBOSE("Created ROT "<<m_printer->print(*rot));
144 convMeasVec.push_back(std::move(rot));
145 }
146 if (!added) {
147 ATH_MSG_ERROR("Could not translate space point "<<spacePoint);
148 return StatusCode::FAILURE;
149 }
150 return StatusCode::SUCCESS;
151 }
152 StatusCode TrkSegmentCnvAlg::convert(const EventContext& ctx,
153 const MuonR4::Segment& segment,
154 Trk::SegmentCollection& outContainer) const {
155
156 const Muon::RpcPrepDataContainer* rpcPrds{nullptr};
157 const Muon::MdtPrepDataContainer* mdtPrds{nullptr};
158 const Muon::TgcPrepDataContainer* tgcPrds{nullptr};
159 const Muon::sTgcPrepDataContainer* stgcPrds{nullptr};
160 const Muon::MMPrepDataContainer* mmPrds{nullptr};
161
162 ATH_CHECK(SG::get(mdtPrds, m_keyMdt, ctx));
163 ATH_CHECK(SG::get(rpcPrds, m_keyRpc, ctx));
164 ATH_CHECK(SG::get(tgcPrds, m_keyTgc, ctx));
165 ATH_CHECK(SG::get(stgcPrds, m_keysTgc, ctx));
166 ATH_CHECK(SG::get(mmPrds, m_keyMM, ctx));
167
168 const ActsTrk::GeometryContext* gctx{nullptr};
169 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
170
171 std::vector<std::unique_ptr<Trk::RIO_OnTrack>> rots{};
172 unsigned int nPrec{0};
173 for (const Segment::MeasType& spacePoint : segment.measurements()){
174 if (spacePoint->fitState() != CalibratedSpacePoint::State::Valid) {
175 ATH_MSG_VERBOSE("'Reject invalid measurement'");
176 continue;
177 }
178 switch (spacePoint->type()) {
180 ATH_CHECK(convertMeasurement(segment, *spacePoint, mdtPrds, rots, "mdtTrkPrdLink"));
181 ++nPrec;
182 break;
183 }
185 ATH_CHECK(convertMeasurement(segment,*spacePoint, rpcPrds, rots, "rpcTrkPrdLink"));
186 break;
187 }
189 ATH_CHECK(convertMeasurement(segment,*spacePoint, tgcPrds, rots, "tgcTrkPrdLink"));
190 break;
191 }
193 ATH_CHECK(convertMeasurement(segment,*spacePoint, mmPrds, rots));
194 ++nPrec;
195 break;
196 }
198 ATH_CHECK(convertMeasurement(segment,*spacePoint, stgcPrds, rots));
199 ++nPrec;
200 break;
201 }
203 break;
204 default:
205 ATH_MSG_WARNING("Unsupported measurement type ");
206 }
207 }
208
210 auto makeCompetingROT = [this, &measurements](RotVec& rots) {
211 if (rots.empty()){
212 return;
213 }
214 std::list<const Trk::PrepRawData*> prds{};
215 for (const std::unique_ptr<Trk::RIO_OnTrack>& rot : rots) {
216 prds.push_back(rot->prepRawData());
217 }
218 measurements.push_back(m_compClusterCreator->createBroadCluster(std::move(prds),0.));
219 rots.clear();
220 };
221
222 RotVec etaPrds{}, phiPrds{};
223 for (std::unique_ptr<Trk::RIO_OnTrack>& rot : rots) {
224 const Trk::PrepRawData* prd = rot->prepRawData();
226 std::vector<std::unique_ptr<Trk::RIO_OnTrack>>& pushMe{m_idHelperSvc->measuresPhi(rot->identify())? phiPrds : etaPrds};
227 if (pushMe.size() && pushMe.back()->detectorElement() != rot->detectorElement()){
228 makeCompetingROT(pushMe);
229 } else {
230 pushMe.push_back(std::move(rot));
231 }
232
233 } else {
234 makeCompetingROT(etaPrds);
235 makeCompetingROT(phiPrds);
236 measurements.push_back(std::move(rot));
237 }
238 }
239 makeCompetingROT(etaPrds);
240 makeCompetingROT(phiPrds);
241 if (!nPrec) {
242 ATH_MSG_WARNING("No precision hit on "<<std::endl<<m_printer->print(measurements.stdcont())
243 <<". Do not convert segment due to potential puff.");
244 return StatusCode::SUCCESS;
245 }
246 ATH_MSG_DEBUG("Fetched in total "<<measurements.size()<<" measurements. "<<std::endl<<
247 m_printer->print(measurements.stdcont()));
249 const Amg::Transform3D& locToGlob{segment.msSector()->localToGlobalTransform(*gctx)};
250 auto segSurf = std::make_unique<Trk::PlaneSurface>(Amg::getTransformFromRotTransl(locToGlob.linear(), segment.position()));
251 Trk::LocalDirection segDir{};
252 segSurf->globalToLocalDirection(segment.direction(), segDir);
253 std::vector<Identifier> holes{};
254 auto fitQuality = std::make_unique<Muon::MuonSegmentQuality>(segment.chi2(),
255 static_cast<double>(segment.nDoF()),
256 std::move(holes));
257
258 Amg::MatrixX covMatrix(4, 4);
259 covMatrix.setIdentity();
260 using namespace MuonR4::SegmentFit;
261 covMatrix(Trk::locX, Trk::locX) = segment.covariance()(Acts::toUnderlying(ParamDefs::x0), Acts::toUnderlying(ParamDefs::x0));
262 covMatrix(Trk::locY, Trk::locY) = segment.covariance()(Acts::toUnderlying(ParamDefs::y0), Acts::toUnderlying(ParamDefs::y0));
263
264 covMatrix(Trk::phi0, Trk::phi0) = segment.covariance()(Acts::toUnderlying(ParamDefs::phi), Acts::toUnderlying(ParamDefs::phi));
265 covMatrix(Trk::theta, Trk::theta) = segment.covariance()(Acts::toUnderlying(ParamDefs::theta), Acts::toUnderlying(ParamDefs::theta));
266
267 auto legacySeg = std::make_unique<Muon::MuonSegment>(Amg::Vector2D::Zero(), std::move(segDir),
268 std::move(covMatrix), segSurf.release(),
269 std::move(measurements), fitQuality.release());
270
271 ATH_MSG_VERBOSE(m_printer->print(*legacySeg)<<", pos: "<<Amg::toString(legacySeg->globalPosition())<<" "
272 <<Amg::toString(legacySeg->globalDirection())<<std::endl<<m_printer->print(legacySeg->containedMeasurements()));
273 outContainer.push_back(std::move(legacySeg));
274 return StatusCode::SUCCESS;
275 }
276}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
ElementLink< xAOD::TruthParticleContainer > Link_t
Derived DataVector<T>.
Definition DataVector.h:795
value_type push_back(value_type pElem)
Add an element to the end of the collection.
const PtrVector & stdcont() const
Return the underlying std::vector of the container.
size_type size() const noexcept
Returns the number of elements in the collection.
virtual const T * indexFindPtr(IdentifierHash hashId) const override final
return pointer on the found entry or null if out of range using hashed index - fast version,...
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
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.
Placeholder for what will later be the muon segment EDM representation.
unsigned int nDoF() const
Returns the number of degrees of freedom.
const SegmentFit::Covariance & covariance() const
Returns the uncertainties of the defining parameters.
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated MS sector.
Acts::CloneablePtr< CalibratedSpacePoint > MeasType
Calibrated space point type.
const MeasVec & measurements() const
Returns the associated measurements.
const Amg::Vector3D & position() const
Returns the global segment position.
const Amg::Vector3D & direction() const
Returns the global segment direction.
SG::WriteHandleKey< Trk::SegmentCollection > m_writeKey
ToolHandle< Muon::IMuonClusterOnTrackCreator > m_clusterCreator
ActsTrk::GeoContextReadKey_t m_geoCtxKey
StatusCode execute(const EventContext &ctx) const override final
StatusCode convert(const EventContext &ctx, const MuonR4::Segment &segment, Trk::SegmentCollection &outContainer) const
Convert the R4 segment and fill the converted segment into the SegmentCollection.
SG::ReadHandleKey< Muon::RpcPrepDataContainer > m_keyRpc
ToolHandle< Muon::IMdtDriftCircleOnTrackCreator > m_mdtCreator
std::vector< std::unique_ptr< Trk::RIO_OnTrack > > RotVec
StatusCode initialize() override final
StatusCode convertMeasurement(const MuonR4::Segment &segment, const CalibratedSpacePoint &spacePoint, const Muon::MuonPrepDataContainerT< PrdType > *prdContainer, RotVec &convMeasVec, const std::string &accName="") const
Convert the calibrated space point of interest to a Trk::Measurement.
const PrdType * fetchPrd(const Identifier &prdId, const Muon::MuonPrepDataContainerT< PrdType > *prdContainer) const
SG::ReadHandleKeyArray< SegmentContainer > m_readKeys
SG::ReadHandleKey< Muon::MdtPrepDataContainer > m_keyMdt
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
PublicToolHandle< Muon::MuonEDMPrinterTool > m_printer
SG::ReadHandleKey< Muon::TgcPrepDataContainer > m_keyTgc
Prep data container keys.
ToolHandle< Muon::IMuonCompetingClustersOnTrackCreator > m_compClusterCreator
SG::ReadHandleKey< Muon::MMPrepDataContainer > m_keyMM
SG::ReadHandleKey< Muon::sTgcPrepDataContainer > m_keysTgc
Template to hold collections of MuonPrepRawData objects.
Helper class to provide constant type-safe access to aux data.
Property holding a SG store/key/clid from which a ReadHandle is made.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
represents the three-dimensional global direction with respect to a planar surface frame.
virtual bool type(PrepRawDataType type) const
Interface method checking the type.
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
Intersection straightLineIntersection(const T &pars, bool forceDir=false, const Trk::BoundaryCheck &bchk=false) const
fst straight line intersection schema - templated for charged and neutral parameters
Definition Surface.h:352
int channelType(const Identifier &id) const
const Identifier & identify() const
Returns the Athena identifier of the measurement.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Amg::Transform3D getTransformFromRotTransl(Amg::RotationMatrix3D rot, Amg::Vector3D transl_vec)
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
This header ties the generic definitions in this package.
DataVector< Segment > SegmentContainer
MuonPrepDataContainerT< RpcPrepData > RpcPrepDataContainer
MuonPrepDataContainer< MuonPrepDataCollection< PrdType > > MuonPrepDataContainerT
MuonPrepDataContainerT< TgcPrepData > TgcPrepDataContainer
MuonPrepDataContainerT< MdtPrepData > MdtPrepDataContainer
MuonPrepDataContainerT< sTgcPrepData > sTgcPrepDataContainer
MuonPrepDataContainerT< MMPrepData > MMPrepDataContainer
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
DataVector< Trk::Segment > SegmentCollection
@ locY
local cartesian
Definition ParamDefs.h:38
@ locX
Definition ParamDefs.h:37
@ phi0
Definition ParamDefs.h:65
@ theta
Definition ParamDefs.h:66
MuonMeasurement_v1 MuonMeasurement
Amg::Vector3D position