ATLAS Offline Software
Loading...
Searching...
No Matches
xAODSegmentCnvAlg.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 "xAODSegmentCnvAlg.h"
5
9
14
15#include "Acts/Utilities/Enumerate.hpp"
16#include "Acts/Surfaces/StrawSurface.hpp"
17#include "Acts/Surfaces/LineBounds.hpp"
18#include "Acts/Definitions/Units.hpp"
19
20using namespace Acts::UnitLiterals;
21namespace MuonR4{
22 using namespace SegmentFit;
31 using PrdLinkVec_t = std::vector<PrdLink_t>;
33 using SegPars_t = xAOD::MeasVector<Acts::toUnderlying(ParamDefs::nPars)>;
34
36 ATH_CHECK(m_idHelperSvc.retrieve());
37 ATH_CHECK(m_readKeys.initialize());
38 ATH_CHECK(m_geoCtxKey.initialize());
39 ATH_CHECK(m_writeKey.initialize());
40 ATH_CHECK(m_prdLinkKey.initialize());
41 ATH_CHECK(m_localSegParKey.initialize());
42 ATH_CHECK(m_parentSegKey.initialize());
43 ATH_CHECK(m_combMeasKey.initialize());
44 ATH_CHECK(m_prdStateKey.initialize());
46 return StatusCode::SUCCESS;
47 }
48 StatusCode xAODSegmentCnvAlg::execute(const EventContext& ctx) const {
49 const ActsTrk::GeometryContext* gctx{nullptr};
50 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
51
52 SG::WriteHandle outContainer{m_writeKey, ctx};
53 ATH_CHECK(outContainer.record(std::make_unique<xAOD::MuonSegmentContainer>(),
54 std::make_unique<xAOD::MuonSegmentAuxContainer>()));
55
56 SG::WriteHandle prdCombContainer{m_combMeasKey, ctx};
57 ATH_CHECK(prdCombContainer.record(std::make_unique<xAOD::CombinedMuonStripContainer>(),
58 std::make_unique<xAOD::CombinedMuonStripAuxContainer>()));
59
64
66 // Cache all measurements that can be combined to two measurements in a single gas gap
67 std::vector< std::tuple<const xAOD::MuonMeasurement*, State, std::size_t>> combineMap{};
68 std::vector< std::tuple<const xAOD::UncalibratedMeasurement*, State, std::size_t>> linkMap{};
69
70 const xAOD::UncalibratedMeasurement* beamSpotMeas{};
71
72 auto beamSpotMeasCreator = m_auxMeasProv.makeHandle(ctx, gctx->context());
73
80 auto decorateLinks = [&](const Segment& inSegment, xAOD::MuonSegment& outSegment) {
81 PrdLinkVec_t& links = dec_prdLinks(outSegment);
82 std::vector<char>& linkStates = dec_prdStates(outSegment);
83 links.reserve(2*inSegment.measurements().size());
84 linkStates.reserve(2*inSegment.measurements().size());
85
88 auto combine = [this,&prdCombContainer](const xAOD::MuonMeasurement* m1,
89 const xAOD::MuonMeasurement* m2) {
90 auto cmbMeas = prdCombContainer->push_back(std::make_unique<xAOD::CombinedMuonStrip>());
91
92 cmbMeas->setPrimaryStrip(m1);
93 cmbMeas->setSecondaryStrip(m2);
94 const auto [locPos, locCov] = xAOD::positionAndCovariance(m1, m2);
95 cmbMeas->localCovariance<2>() = xAOD::toStorage(locCov);
96 cmbMeas->localPosition<2>() = xAOD::toStorage(locPos);
97 const Identifier id1{m1->identify()}, id2{m2->identify()};
98 ATH_MSG_VERBOSE("Combine "<<m_idHelperSvc->toString(id1)
99 <<" & "<<m_idHelperSvc->toString(id2));
100 if ((m1->type() != xAOD::UncalibMeasType::sTgcStripType ||
101 m_idHelperSvc->stgcIdHelper().channelType(id1) ==
102 m_idHelperSvc->stgcIdHelper().channelType(id2))&&
103 m_idHelperSvc->measuresPhi(id1) == m_idHelperSvc->measuresPhi(id2)) {
104 THROW_EXCEPTION("Cannot combine "<<m_idHelperSvc->toString(id1)
105 <<" & "<<m_idHelperSvc->toString(id2));
106 }
107 return cmbMeas;
108 };
109 // Loop over the measurements
110 for (const auto [segIdx, meas] : Acts::enumerate(inSegment.measurements())) {
111 const SpacePoint* sp = meas->spacePoint();
112 if (!sp) {
113 if (!m_convertBeamSpot) {
114 continue;
115 }
116 // Up to now, there's no variety on the beamspot across the segments
117 if (!beamSpotMeas) {
118 if (!beamSpotMeasCreator.ok()) {
119 ATH_MSG_ERROR("Cannot create a beamspot measurement");
120 return StatusCode::FAILURE;
121 }
122
123 const Amg::Vector3D beamSpot = inSegment.msSector()->localToGlobalTransform(*gctx) *
124 meas->localPosition();
125 AmgSymMatrix(2) covariance{AmgSymMatrix(2)::Identity()};
126 using CovIdx = SpacePoint::CovIdx;
127 using ProjectorType = xAOD::AuxiliaryMeasurement::ProjectorType;
128 covariance(0,0) = meas->covariance()[Acts::toUnderlying(CovIdx::etaCov)];
129 covariance(1,1) = meas->covariance()[Acts::toUnderlying(CovIdx::phiCov)];
131 auto surf = Acts::Surface::makeShared<Acts::StrawSurface>(Amg::getTranslate3D(beamSpot),
132 std::make_shared<Acts::LineBounds>(std::sqrt(covariance(0,0)), 20._m));
133
134 beamSpotMeas = beamSpotMeasCreator->newMeasurement<2>(surf,
135 ProjectorType::e2DimNoTime, covariance);
136 ATH_MSG_DEBUG("Created beamspot measurement "<<(*meas)<<", "
137 <<surf->toString(gctx->context()));
138 }
139 linkMap.emplace_back(beamSpotMeas, meas->fitState(), segIdx);
140 continue;
141 }
142 switch (sp->type()) {
143 using enum xAOD::UncalibMeasType;
144 // Mdt & micromegas are never combined
145 case MdtDriftCircleType:
146 case MMClusterType: {
147 linkMap.emplace_back(sp->primaryMeasurement(), meas->fitState(), segIdx);
148 break;
149 } case RpcStripType:
150 case TgcStripType:
151 case sTgcStripType: {
152 if (sp->primaryMeasurement() && sp->secondaryMeasurement()) {
153 if (sp->primaryMeasurement() != sp->secondaryMeasurement()) {
154 linkMap.emplace_back(combine(sp->primaryMeasurement(),
155 sp->secondaryMeasurement()),
156 meas->fitState(), segIdx);
157 } else { // BI - RPC measurements
158 linkMap.emplace_back(sp->primaryMeasurement(), meas->fitState(), segIdx);
159 }
160 } else {
163 ATH_MSG_VERBOSE("Append for later combination "<<(*meas));
164 combineMap.emplace_back(sp->primaryMeasurement(), meas->fitState(), segIdx);
165 }
166 break;
167 } default:
168 break;
169 }
170 }
171 // Finally we need to check whether there're measurements left to combine
172 for (std::size_t cmbIdx = 0; cmbIdx < combineMap.size(); ++cmbIdx){
173 const xAOD::MuonMeasurement* m1{std::get<0>(combineMap[cmbIdx])};
174 const State s1{std::get<1>(combineMap[cmbIdx])};
175 const std::size_t segIdx1{std::get<2>(combineMap[cmbIdx])};
176 ATH_MSG_VERBOSE("Find another measurement to combine with "
177 <<m_idHelperSvc->toString(m1->identify()));
178 if (cmbIdx +1 < combineMap.size()){
179 const xAOD::MuonMeasurement* m2{std::get<0>(combineMap[cmbIdx +1])};
180 const State s2{std::get<1>(combineMap[cmbIdx+1])};
181 ATH_MSG_VERBOSE("Check whether "<<m_idHelperSvc->toString(m2->identify())
182 <<" is a good candidate");
183 if (m1->type() == m2->type() &&
184 m1->identifierHash() == m2->identifierHash() &&
185 m1->layerHash() == m2->layerHash() &&
186 s1 == s2) {
188 ATH_MSG_VERBOSE("They match");
189 if (m1->measuresPhi()) {
190 linkMap.emplace_back(combine(m2, m1), s2, segIdx1);
191 } else {
192 linkMap.emplace_back(combine(m1, m2), s1, segIdx1);
193 }
194 ++cmbIdx; // skip the next measurement as it's absorbed here
195 continue;
196 }
197 }
198 ATH_MSG_VERBOSE("No match found");
199 linkMap.emplace_back(m1, s1, segIdx1);
200 }
201
202 std::ranges::sort(linkMap, [](const auto& a, const auto& b){
203 return std::get<2>(a) < std::get<2>(b);
204 });
205
206 for (const auto& [prd, state, segIdx]: linkMap) {
207 links.emplace_back(
208 *static_cast<const xAOD::UncalibratedMeasurementContainer*>(prd->container()),
209 prd->index());
210 linkStates.emplace_back(Acts::toUnderlying(state));
211 }
212 linkMap.clear();
213 combineMap.clear();
214 return StatusCode::SUCCESS;
215 };
216
218 const SegmentContainer* segmentContainer{nullptr};
219 ATH_CHECK(SG::get(segmentContainer, key, ctx));
220
222 unsigned recoSegIdx{0};
223 outContainer->reserve(outContainer->size() + segmentContainer->size());
224 for (const Segment* inSegment : *segmentContainer) {
225 const MuonGMR4::SpectrometerSector* sector = inSegment->msSector();
226
227 xAOD::MuonSegment* convertedSeg = outContainer->push_back(std::make_unique<xAOD::MuonSegment>());
228 dec_parentLink(*convertedSeg) = SegLink_t{segmentContainer, recoSegIdx};
229 ++recoSegIdx;
230
231 const Amg::Vector3D& pos{inSegment->position()};
232 const Amg::Vector3D& dir{inSegment->direction()};
233 convertedSeg->setPosition(pos.x(), pos.y(), pos.z());
234 convertedSeg->setDirection(dir.x(), dir.y(), dir.z());
235
236
237 convertedSeg->setIdentifier(sector->sector(), sector->chamberIndex(), sector->side(),
238 xAOD::toTechnologyIndex(inSegment->summary().tech));
239 convertedSeg->setFitQuality(inSegment->chi2(), inSegment->nDoF());
240 convertedSeg->setNHits(inSegment->summary().nPrecHits, inSegment->summary().nPhiHits,
241 inSegment->summary().nEtaTrigHits);
242
243 using enum ParamDefs;
244 convertedSeg->setT0Error(inSegment->segementT0(),
245 Amg::error(inSegment->covariance(), Acts::toUnderlying(t0)));
246
247 SegPars_t& localPars{dec_locPars(*convertedSeg)};
248 const Amg::Transform3D globToLoc{sector->globalToLocalTransform(*gctx)};
249 const Amg::Vector3D locPos{globToLoc * pos};
250 const Amg::Vector3D locDir{globToLoc.linear() * dir};
251
252 localPars[Acts::toUnderlying(x0)] = locPos.x();
253 localPars[Acts::toUnderlying(y0)] = locPos.y();
254 localPars[Acts::toUnderlying(theta)] = locDir.theta();
255 localPars[Acts::toUnderlying(phi)] = locDir.phi();
256 localPars[Acts::toUnderlying(t0)] = inSegment->segementT0();
257 ATH_CHECK(decorateLinks(*inSegment, *convertedSeg));
258 }
259 }
260 return StatusCode::SUCCESS;
261 }
262}
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
static Double_t sp
static Double_t a
static Double_t t0
Handle class for adding a decoration to an object.
Handle class for recording to StoreGate.
Acts::GeometryContext context() const
size_type size() const noexcept
Returns the number of elements in the collection.
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
int8_t side() const
Returns the side of the MS-sector 1 -> A side ; -1 -> C side.
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
int sector() const
Returns the sector of the MS-sector.
Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index scheme.
State
State flag to distinguish different space point states.
Placeholder for what will later be the muon segment EDM representation.
double segementT0() const
Returns the fitted segment time, if there's any.
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.
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.
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
DecorKey_t m_prdStateKey
Decoration to the PrdLink state (I.e.
DecorKey_t m_localSegParKey
Decoration to the local segment parameters.
DecorKey_t m_parentSegKey
Decoration of the original segment.
SG::WriteHandleKey< xAOD::MuonSegmentContainer > m_writeKey
Output segment container key.
SG::WriteHandleKey< xAOD::CombinedMuonStripContainer > m_combMeasKey
Auxiliary container to model two measurements in the same gas gap as a single track state.
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
Alignment container key.
DecorKey_t m_prdLinkKey
Decoration to the links to the associated Uncalibrated measurements.
virtual StatusCode execute(const EventContext &ctx) const override final
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
IdHelperSvc for Identifier printing & manipulation.
virtual StatusCode initialize() override final
Gaudi::Property< bool > m_convertBeamSpot
Flag to convert the beamspot constaint as well.
ActsTrk::AuxiliaryMeasurementHandler m_auxMeasProv
Handler to parse the auxiliary beam spot constaint.
SG::ReadHandleKeyArray< SegmentContainer > m_readKeys
Input segment container key.
Property holding a SG store/key/clid from which a ReadHandle is made.
Handle class for adding a decoration to an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
ActsTrk::detail::MeasurementCalibratorBase::ProjectorType ProjectorType
Use the calibration projector.
void setDirection(float px, float py, float pz)
Sets the direction.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
void setNHits(int nPrecisionHits, int nPhiLayers, int nTrigEtaLayers)
Set the number of hits/layers.
void setT0Error(float t0, float t0Error)
Sets the time error.
void setIdentifier(int sector, ::Muon::MuonStationIndex::ChIndex chamberIndex, int etaIndex, ::Muon::MuonStationIndex::TechnologyIndex technology)
Set the identifier.
void setPosition(float x, float y, float z)
Sets the global position.
Amg::Transform3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
SeedingAux::FitParIndex ParamDefs
Use the same parameter indices as used by the CompSpacePointAuxiliaries.
This header ties the generic definitions in this package.
std::vector< PrdLink_t > PrdLinkVec_t
Abrivation of a collection of Prd links.
CalibratedSpacePoint::State State
ElementLink< MuonR4::SegmentContainer > SegLink_t
Abrivation of the link to the reco segment container.
xAOD::UncalibratedMeasurementContainer PrdCont_t
Abrivation to call an uncalibrated measurement container.
DataVector< Segment > SegmentContainer
ElementLink< PrdCont_t > PrdLink_t
Abrivation to call the link to an element inside an uncalibrated measurement container.
xAOD::MeasVector< Acts::toUnderlying(ParamDefs::nPars)> SegPars_t
Abrivation of the decorated local segment parameters.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
MuonMeasurement_v1 MuonMeasurement
::Muon::MuonStationIndex::TechnologyIndex toTechnologyIndex(const UncalibMeasType aodType)
Transforms the uncalibrated measurement type to a technology index.
MeasVector< N > toStorage(const AmgVector(N)&amgVec)
Converts the double precision of the AmgVector into the floating point storage precision of the MeasV...
UncalibMeasType
Define the type of the uncalibrated measurement.
std::pair< Amg::Vector2D, AmgSymMatrix(2)> positionAndCovariance(const MuonMeasurement *oneDimMeas)
Returns the 1D position of the uncalibrated measurement expressed in the coordinate system of the mea...
UncalibratedMeasurementContainer_v1 UncalibratedMeasurementContainer
Define the version of the uncalibrated measurement container.
MuonSegment_v1 MuonSegment
Reference the current persistent version:
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10