ATLAS Offline Software
Loading...
Searching...
No Matches
xAODSegmentCnvAlg.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 "xAODSegmentCnvAlg.h"
5
8
13
14
15
16namespace MuonR4{
17 using namespace SegmentFit;
26 using PrdLinkVec_t = std::vector<PrdLink_t>;
28 using SegPars_t = xAOD::MeasVector<Acts::toUnderlying(ParamDefs::nPars)>;
29
31
32 constexpr TechIdx_t toTechIdx(const xAOD::UncalibMeasType aodType){
33 switch (aodType){
35 return TechIdx_t::MDT;
37 return TechIdx_t::RPC;
39 return TechIdx_t::TGC;
41 return TechIdx_t::MM;
43 return TechIdx_t::STGC;
44 default:
45 return TechIdx_t::TechnologyUnknown;
46 }
47 }
48
50 ATH_CHECK(m_idHelperSvc.retrieve());
51 ATH_CHECK(m_readKeys.initialize());
52 ATH_CHECK(m_geoCtxKey.initialize());
53 ATH_CHECK(m_writeKey.initialize());
54 ATH_CHECK(m_prdLinkKey.initialize());
55 ATH_CHECK(m_localSegParKey.initialize());
56 ATH_CHECK(m_parentSegKey.initialize());
57 ATH_CHECK(m_combMeasKey.initialize());
58 ATH_CHECK(m_prdStateKey.initialize());
59 return StatusCode::SUCCESS;
60 }
61 StatusCode xAODSegmentCnvAlg::execute(const EventContext& ctx) const {
62 const ActsTrk::GeometryContext* gctx{nullptr};
63 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
64
65 SG::WriteHandle outContainer{m_writeKey, ctx};
66 ATH_CHECK(outContainer.record(std::make_unique<xAOD::MuonSegmentContainer>(),
67 std::make_unique<xAOD::MuonSegmentAuxContainer>()));
68
69 SG::WriteHandle prdCombContainer{m_combMeasKey, ctx};
70 ATH_CHECK(prdCombContainer.record(std::make_unique<xAOD::CombinedMuonStripContainer>(),
71 std::make_unique<xAOD::CombinedMuonStripAuxContainer>()));
72
77 static std::atomic<unsigned> sTgcWarnings{0};
78 bool printWarning{sTgcWarnings < 100};
80 std::vector<std::tuple<const xAOD::UncalibratedMeasurement*, State>> combineMap{};
81 combineMap.reserve(10);
88 auto decorateLinks = [this, &dec_prdLinks, &prdCombContainer, &printWarning,
89 &combineMap, & dec_prdStates](const Segment& inSegment, xAOD::MuonSegment& outSegment) {
90 PrdLinkVec_t& links = dec_prdLinks(outSegment);
91 std::vector<char>& linkStates = dec_prdStates(outSegment);
92 links.reserve(2*inSegment.measurements().size());
93 linkStates.reserve(2*inSegment.measurements().size());
96
97 auto appendLink = [&links, &linkStates](const xAOD::UncalibratedMeasurement* prd, const State st) {
98 if (!prd) {
99 return;
100 }
101 linkStates.emplace_back(Acts::toUnderlying(st));
102 links.emplace_back(*static_cast<const xAOD::UncalibratedMeasurementContainer*>(prd->container()),
103 prd->index());
104 };
107 auto combine = [this,&prdCombContainer,&appendLink](const xAOD::UncalibratedMeasurement* m1,
109 const State st) {
110 auto cmbMeas = prdCombContainer->push_back(std::make_unique<xAOD::CombinedMuonStrip>());
111
112 cmbMeas->setPrimaryStrip(m1);
113 cmbMeas->setSecondaryStrip(m2);
114 ATH_MSG_VERBOSE("Combine "<<m_idHelperSvc->toString(xAOD::identify(m1))
115 <<" & "<<m_idHelperSvc->toString(xAOD::identify(m2)));
116 if (m_idHelperSvc->measuresPhi(xAOD::identify(m1)) ==
117 m_idHelperSvc->measuresPhi(xAOD::identify(m2))) {
118 THROW_EXCEPTION("Cannot combine "<<m_idHelperSvc->toString(xAOD::identify(m1))
119 <<" & "<<m_idHelperSvc->toString(xAOD::identify(m2))
121 }
122 appendLink(cmbMeas, st);
123 };
124 for (const auto& meas : inSegment.measurements()) {
125 const SpacePoint* sp = meas->spacePoint();
126 if (!sp) {
127 continue;
128 }
129 switch (sp->type()) {
130 using enum xAOD::UncalibMeasType;
131 // Mdt & micromegas are never combined
132 case MdtDriftCircleType:
133 case MMClusterType: {
134 appendLink(sp->primaryMeasurement(), meas->fitState());
135 break;
136 } case RpcStripType:
137 case TgcStripType: {
138 if (sp->primaryMeasurement() && sp->secondaryMeasurement()) {
139 if (sp->primaryMeasurement() != sp->secondaryMeasurement()) {
140 combine(sp->primaryMeasurement(), sp->secondaryMeasurement(), meas->fitState());
141 } else { // BI - RPC measurements
142 appendLink(sp->primaryMeasurement(), meas->fitState());
143 }
144 } else {
147 ATH_MSG_VERBOSE("Append for later combination "<<(*meas));
148 combineMap.emplace_back(sp->primaryMeasurement(), meas->fitState());
149 }
150 break;
151 } case sTgcStripType:{
153 appendLink(sp->primaryMeasurement(), meas->fitState());
154 appendLink(sp->secondaryMeasurement(), meas->fitState());
156 if (printWarning) {
157 ATH_MSG_WARNING(__FILE__<<":"<<__LINE__<<" Please implement a stgc combination schema");
158 printWarning = false;
159 }
160 } default:
161 break;
162 }
163 }
164 // Finally we need to check whether there're measurements left to combine
165 for (std::size_t cmbIdx = 0; cmbIdx < combineMap.size(); ++cmbIdx){
166 const xAOD::UncalibratedMeasurement* m1{std::get<0>(combineMap[cmbIdx])};
167 const State s1{std::get<1>(combineMap[cmbIdx])};
168 ATH_MSG_VERBOSE("Find another measurement to combine with "
169 <<m_idHelperSvc->toString(xAOD::identify(m1)));
170 if (cmbIdx +1 < combineMap.size()){
171 const xAOD::UncalibratedMeasurement* m2{std::get<0>(combineMap[cmbIdx +1])};
172 const State s2{std::get<1>(combineMap[cmbIdx+1])};
173 ATH_MSG_VERBOSE("Check whether "<<m_idHelperSvc->toString(xAOD::identify(m2))
174 <<" is a good candidate");
175 if (m1->type() == m2->type() &&
176 m1->identifierHash() == m2->identifierHash() &&
177 xAOD::layerHash(m1) == xAOD::layerHash(m2) &&
178 s1 == s2) {
180 ATH_MSG_VERBOSE("They match");
181 if (m_idHelperSvc->measuresPhi(xAOD::identify(m1))) {
182 combine(m2, m1, s2);
183 } else {
184 combine(m1, m2, s1);
185 }
186 ++cmbIdx; // skip the next measurement as it's absorbed here
187 continue;
188 }
189 }
190 ATH_MSG_VERBOSE("No match found");
191 appendLink(m1, s1);
192 }
193 combineMap.clear();
194 };
195
197 const SegmentContainer* segmentContainer{nullptr};
198 ATH_CHECK(SG::get(segmentContainer, key, ctx));
199
201 unsigned recoSegIdx{0};
202 outContainer->reserve(outContainer->size() + segmentContainer->size());
203 for (const Segment* inSegment : *segmentContainer) {
204 const MuonGMR4::SpectrometerSector* sector = inSegment->msSector();
205
206 xAOD::MuonSegment* convertedSeg = outContainer->push_back(std::make_unique<xAOD::MuonSegment>());
207 dec_parentLink(*convertedSeg) = SegLink_t{segmentContainer, recoSegIdx};
208 ++recoSegIdx;
209
210 const Amg::Vector3D& pos{inSegment->position()};
211 const Amg::Vector3D& dir{inSegment->direction()};
212 convertedSeg->setPosition(pos.x(), pos.y(), pos.z());
213 convertedSeg->setDirection(dir.x(), dir.y(), dir.z());
214
215
216 convertedSeg->setIdentifier(sector->sector(), sector->chamberIndex(), sector->side(),
217 toTechIdx(inSegment->summary().tech));
218 convertedSeg->setFitQuality(inSegment->chi2(), inSegment->nDoF());
219 convertedSeg->setNHits(inSegment->summary().nPrecHits, inSegment->summary().nPhiHits,
220 inSegment->summary().nEtaTrigHits);
221
222 using enum ParamDefs;
223 convertedSeg->setT0Error(inSegment->segementT0(),
224 Amg::error(inSegment->covariance(), Acts::toUnderlying(t0)));
225
226 SegPars_t& localPars{dec_locPars(*convertedSeg)};
227 const Amg::Transform3D globToLoc{sector->globalToLocalTrans(*gctx)};
228 const Amg::Vector3D locPos{globToLoc * pos};
229 const Amg::Vector3D locDir{globToLoc.linear() * dir};
230
231 localPars[Acts::toUnderlying(x0)] = locPos.x();
232 localPars[Acts::toUnderlying(y0)] = locPos.y();
233 localPars[Acts::toUnderlying(theta)] = locDir.theta();
234 localPars[Acts::toUnderlying(phi)] = locDir.phi();
235 localPars[Acts::toUnderlying(t0)] = inSegment->segementT0();
236 decorateLinks(*inSegment, *convertedSeg);
237 }
238 }
239
240 if (!printWarning) {
241 sTgcWarnings = sTgcWarnings + 1;
242 }
243 return StatusCode::SUCCESS;
244 }
245}
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
static Double_t sp
static Double_t t0
Handle class for adding a decoration to an object.
Handle class for recording to StoreGate.
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.
Amg::Transform3D globalToLocalTrans(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.
static std::string toString(const State s)
Converts the state enum into a string.
State
State flag to distinguish different space point states.
Placeholder for what will later be the muon segment EDM representation.
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
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.
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.
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.
constexpr TechIdx_t toTechIdx(const xAOD::UncalibMeasType aodType)
CalibratedSpacePoint::State State
Muon::MuonStationIndex::TechnologyIndex TechIdx_t
ElementLink< MuonR4::SegmentContainer > SegLink_t
Abrivation of the link to the reco segment container.
DataVector< Segment > SegmentContainer
ElementLink< PrdCont_t > PrdLink_t
Abrivation to call the link to an element inside an uncalibrated measurement container.
xAOD::UncalibratedMeasurementContainer PrdCont_t
Abrivation to call an uncalibrated measurement container.
xAOD::MeasVector< Acts::toUnderlying(ParamDefs::nPars)> SegPars_t
Abrivation of the decorated local segment parameters.
TechnologyIndex
enum to classify the different layers in the muon spectrometer
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.
UncalibMeasType
Define the type of the uncalibrated measurement.
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
IdentifierHash layerHash(const UncalibratedMeasurement *meas)
Returns the layer hash from an uncalibrated meaurement.
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