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
20 ATH_CHECK(m_keyTgc.initialize(!m_keyTgc.empty()));
21 ATH_CHECK(m_keyRpc.initialize(!m_keyRpc.empty()));
22 ATH_CHECK(m_keyMdt.initialize(!m_keyMdt.empty()));
23 ATH_CHECK(m_keysTgc.initialize(!m_keysTgc.empty()));
24 ATH_CHECK(m_keyMM.initialize(!m_keyMM.empty()));
25 ATH_CHECK(m_readKeys.initialize());
26 ATH_CHECK(m_writeKey.initialize());
27 ATH_CHECK(m_mdtCreator.retrieve());
28 ATH_CHECK(m_clusterCreator.retrieve());
29 ATH_CHECK(m_compClusterCreator.retrieve(EnableTool{!m_keyTgc.empty() || !m_keyRpc.empty()}));
30 ATH_CHECK(m_geoCtxKey.initialize());
31 return StatusCode::SUCCESS;
32 }
33
34 StatusCode TrkSegmentCnvAlg::execute(const EventContext& ctx) const {
35
36 auto translatedSegments = std::make_unique<Trk::SegmentCollection>();
38 const SegmentContainer* translateMe{nullptr};
39 ATH_CHECK(SG::get(translateMe, key, ctx));
40 for (const Segment* segment : *translateMe) {
41 ATH_CHECK(convert(ctx, *segment, *translatedSegments));
42 }
43
44 }
45 ATH_MSG_VERBOSE("Translated in total "<<translatedSegments->size()<<" segments.");
46
47 SG::WriteHandle writeHandle{m_writeKey, ctx};
48 ATH_CHECK(writeHandle.record(std::move(translatedSegments)));
49 return StatusCode::SUCCESS;
50 }
51 template <class PrdType>
52 const PrdType* TrkSegmentCnvAlg::fetchPrd(const Identifier& prdId,
53 const Muon::MuonPrepDataContainerT<PrdType>* prdContainer) const {
54 if (!prdContainer) {
55 ATH_MSG_ERROR("Cannot fetch a prep data object as the container given for "<<
56 m_idHelperSvc->toString(prdId)<<" is a nullptr");
57 return nullptr;
58 }
59 const Muon::MuonPrepDataCollection<PrdType>* coll = prdContainer->indexFindPtr(m_idHelperSvc->moduleHash(prdId));
60 if (!coll) {
61 ATH_MSG_ERROR("No prep data collection where "<<m_idHelperSvc->toString(prdId)<<" can reside in.");
62 return nullptr;
63 }
64 for (const PrdType* prd : *coll) {
65 if (prd->identify() == prdId){
66 return prd;
67 }
68 }
69 ATH_MSG_ERROR("There is no measurement "<<m_idHelperSvc->toString(prdId));
70
71 return nullptr;
72 }
73 template <class PrdType>
75 const CalibratedSpacePoint& spacePoint,
76 const Muon::MuonPrepDataContainerT<PrdType>* prdContainer,
77 std::vector<std::unique_ptr<Trk::RIO_OnTrack>>& convMeasVec) const {
78 bool added{false};
79
80 for (const xAOD::UncalibratedMeasurement* uncalib: {spacePoint.spacePoint()->primaryMeasurement(),
81 spacePoint.spacePoint()->secondaryMeasurement()}){
82 if (!uncalib) continue;
83 added = true;
84
85 const PrdType* prd = fetchPrd(xAOD::identify(uncalib), prdContainer);
86 if (!prd) {
87 ATH_MSG_FATAL("Failed to retrieve segment from "<<m_idHelperSvc->toString(xAOD::identify(uncalib)));
88 return StatusCode::FAILURE;
89 }
90 const Trk::Surface& surf{prd->detectorElement()->surface(prd->identify())};
91 Trk::Intersection isect = surf.straightLineIntersection(segment.position(), segment.direction());
92
93 std::unique_ptr<Trk::RIO_OnTrack> rot{};
94 if constexpr(std::is_same_v<PrdType, Muon::MdtPrepData>) {
95 rot = std::unique_ptr<Trk::RIO_OnTrack>{m_mdtCreator->createRIO_OnTrack(*prd,
96 isect.position,
97 &segment.direction())};
98 } else {
99 rot = std::unique_ptr<Trk::RIO_OnTrack>{m_clusterCreator->createRIO_OnTrack(*prd,
100 isect.position,
101 segment.direction())};
102 if constexpr (std::is_same_v<PrdType, Muon::sTgcPrepData>) {
103 const sTgcIdHelper& idHelper{m_idHelperSvc->stgcIdHelper()};
104 if (!rot && idHelper.channelType(prd->identify()) == sTgcIdHelper::sTgcChannelTypes::Wire) {
105 const Amg::Vector3D locPos = prd->detectorElement()->transform(prd->identify()).inverse() *
106 isect.position;
107 if (prd->detectorElement()->isEtaZero(prd->identify(), locPos.block<2,1>(0,0))){
108 ATH_MSG_WARNING("Hit from inactive region "<<m_idHelperSvc->toString(prd->identify())
109 <<", "<<Amg::toString(locPos)<<" cannot be translated.");
110 continue;
111 }
112 }
113 }
114 }
115 if(!rot && m_idHelperSvc->issTgc(prd->identify())) {
116 ATH_MSG_WARNING("sTGC ROT creation failed for "<<m_idHelperSvc->toString(prd->identify()));
117 continue;
118 }
119
120 if (!rot) {
121 ATH_MSG_ERROR("Failed to create rot from "<<m_idHelperSvc->toString(prd->identify()));
122 return StatusCode::FAILURE;
123 }
124 ATH_MSG_VERBOSE("Created ROT "<<m_printer->print(*rot));
125 convMeasVec.push_back(std::move(rot));
126 }
127 if (!added) {
128 ATH_MSG_ERROR("Could not translate space point "<<m_idHelperSvc->toString(spacePoint.spacePoint()->identify()));
129 return StatusCode::FAILURE;
130 }
131 return StatusCode::SUCCESS;
132 }
133
134 StatusCode TrkSegmentCnvAlg::convert(const EventContext& ctx,
135 const MuonR4::Segment& segment,
136 Trk::SegmentCollection& outContainer) const {
137
138 const Muon::RpcPrepDataContainer* rpcPrds{nullptr};
139 const Muon::MdtPrepDataContainer* mdtPrds{nullptr};
140 const Muon::TgcPrepDataContainer* tgcPrds{nullptr};
141 const Muon::sTgcPrepDataContainer* stgcPrds{nullptr};
142 const Muon::MMPrepDataContainer* mmPrds{nullptr};
143
144 ATH_CHECK(SG::get(mdtPrds, m_keyMdt, ctx));
145 ATH_CHECK(SG::get(rpcPrds, m_keyRpc, ctx));
146 ATH_CHECK(SG::get(tgcPrds, m_keyTgc, ctx));
147 ATH_CHECK(SG::get(stgcPrds, m_keysTgc, ctx));
148 ATH_CHECK(SG::get(mmPrds, m_keyMM, ctx));
149
150 const ActsTrk::GeometryContext* gctx{nullptr};
151 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
152
153 std::vector<std::unique_ptr<Trk::RIO_OnTrack>> rots{};
154 unsigned int nPrec{0};
155 for (const Segment::MeasType& spacePoint : segment.measurements()){
156 if (spacePoint->fitState() != CalibratedSpacePoint::State::Valid) {
157 ATH_MSG_VERBOSE("'Reject invalid measurement'");
158 continue;
159 }
160 switch (spacePoint->type()) {
162 ATH_CHECK(convertMeasurement(segment, *spacePoint, mdtPrds, rots));
163 ++nPrec;
164 break;
165 }
167 ATH_CHECK(convertMeasurement(segment,*spacePoint, rpcPrds, rots));
168 break;
169 }
171 ATH_CHECK(convertMeasurement(segment,*spacePoint, tgcPrds, rots));
172 break;
173 }
175 ATH_CHECK(convertMeasurement(segment,*spacePoint, mmPrds, rots));
176 ++nPrec;
177 break;
178 }
180 ATH_CHECK(convertMeasurement(segment,*spacePoint, stgcPrds, rots));
181 ++nPrec;
182 break;
183 }
185 break;
186 default:
187 ATH_MSG_WARNING("Unsupported measurement type ");
188 }
189 }
190
192 auto makeCompetingROT = [this, &measurements](RotVec& rots) {
193 if (rots.empty()){
194 return;
195 }
196 std::list<const Trk::PrepRawData*> prds{};
197 for (const std::unique_ptr<Trk::RIO_OnTrack>& rot : rots) {
198 prds.push_back(rot->prepRawData());
199 }
200 measurements.push_back(m_compClusterCreator->createBroadCluster(std::move(prds),0.));
201 rots.clear();
202 };
203
204 RotVec etaPrds{}, phiPrds{};
205 for (std::unique_ptr<Trk::RIO_OnTrack>& rot : rots) {
206 const Trk::PrepRawData* prd = rot->prepRawData();
208 std::vector<std::unique_ptr<Trk::RIO_OnTrack>>& pushMe{m_idHelperSvc->measuresPhi(rot->identify())? phiPrds : etaPrds};
209 if (pushMe.size() && pushMe.back()->detectorElement() != rot->detectorElement()){
210 makeCompetingROT(pushMe);
211 } else {
212 pushMe.push_back(std::move(rot));
213 }
214
215 } else {
216 makeCompetingROT(etaPrds);
217 makeCompetingROT(phiPrds);
218 measurements.push_back(std::move(rot));
219 }
220 }
221 makeCompetingROT(etaPrds);
222 makeCompetingROT(phiPrds);
223 if (!nPrec) {
224 ATH_MSG_WARNING("No precision hit on "<<std::endl<<m_printer->print(measurements.stdcont())
225 <<". Do not convert segment due to potential puff.");
226 return StatusCode::SUCCESS;
227 }
228 ATH_MSG_DEBUG("Fetched in total "<<measurements.size()<<" measurements. "<<std::endl<<
229 m_printer->print(measurements.stdcont()));
231 const Amg::Transform3D& locToGlob{segment.msSector()->localToGlobalTrans(*gctx)};
232 auto segSurf = std::make_unique<Trk::PlaneSurface>(Amg::getTransformFromRotTransl(locToGlob.linear(), segment.position()));
233 Trk::LocalDirection segDir{};
234 segSurf->globalToLocalDirection(segment.direction(), segDir);
235 std::vector<Identifier> holes{};
236 auto fitQuality = std::make_unique<Muon::MuonSegmentQuality>(segment.chi2(),
237 static_cast<double>(segment.nDoF()),
238 std::move(holes));
239
240 Amg::MatrixX covMatrix(4, 4);
241 covMatrix.setIdentity();
242 using namespace MuonR4::SegmentFit;
243 covMatrix(Trk::locX, Trk::locX) = segment.covariance()(Acts::toUnderlying(ParamDefs::x0), Acts::toUnderlying(ParamDefs::x0));
244 covMatrix(Trk::locY, Trk::locY) = segment.covariance()(Acts::toUnderlying(ParamDefs::y0), Acts::toUnderlying(ParamDefs::y0));
245
246 covMatrix(Trk::phi0, Trk::phi0) = segment.covariance()(Acts::toUnderlying(ParamDefs::phi), Acts::toUnderlying(ParamDefs::phi));
247 covMatrix(Trk::theta, Trk::theta) = segment.covariance()(Acts::toUnderlying(ParamDefs::theta), Acts::toUnderlying(ParamDefs::theta));
248
249 auto legacySeg = std::make_unique<Muon::MuonSegment>(Amg::Vector2D::Zero(), std::move(segDir),
250 std::move(covMatrix), segSurf.release(),
251 std::move(measurements), fitQuality.release());
252
253 ATH_MSG_VERBOSE(m_printer->print(*legacySeg)<<", pos: "<<Amg::toString(legacySeg->globalPosition())<<" "
254 <<Amg::toString(legacySeg->globalDirection())<<std::endl<<m_printer->print(legacySeg->containedMeasurements()));
255 outContainer.push_back(std::move(legacySeg));
256 return StatusCode::SUCCESS;
257 }
258}
#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)
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 & localToGlobalTrans(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.
std::unique_ptr< 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.
const xAOD::UncalibratedMeasurement * secondaryMeasurement() const
const Identifier & identify() const
: Identifier of the primary measurement
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
SG::WriteHandleKey< Trk::SegmentCollection > m_writeKey
ToolHandle< Muon::IMuonClusterOnTrackCreator > m_clusterCreator
StatusCode convertMeasurement(const MuonR4::Segment &segment, const CalibratedSpacePoint &spacePoint, const Muon::MuonPrepDataContainerT< PrdType > *prdContainer, RotVec &convMeasVec) const
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
const PrdType * fetchPrd(const Identifier &prdId, const Muon::MuonPrepDataContainerT< PrdType > *prdContainer) const
SG::ReadHandleKeyArray< SegmentContainer > m_readKeys
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
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.
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.
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
int channelType(const Identifier &id) const
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
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
Amg::Vector3D position