ATLAS Offline Software
Loading...
Searching...
No Matches
BucketDumperAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "BucketDumperAlg.h"
6
15#include <fstream>
17#include "CLHEP/Random/RandFlat.h"
18
19namespace {
20 struct LocalSegSorter{
21 bool operator()(const xAOD::MuonSegment* a, const xAOD::MuonSegment* b) const {
22 if(a == b) {
23 return false;
24 }
25 if (a->chamberIndex() != b->chamberIndex()) {
26 return a->chamberIndex() < b->chamberIndex();
27 }
28 if (a->sector() != b->sector()) {
29 return a->sector() < b->sector();
30 }
31 if (a->etaIndex() != b->etaIndex()) {
32 return a->etaIndex() < b->etaIndex();
33 }
34 using namespace MuonR4::SegmentFit;
35 auto locParsA = localSegmentPars(*a);
36 auto locParsB = localSegmentPars(*b);
37 return locParsA < locParsB;
38 }
39 };
40}
41
42namespace MuonR4{
44 ATH_CHECK(m_spacePointKeys.initialize());
45 ATH_CHECK(m_inSegmentKeys.initialize());
46 if (m_isMC) {
47 for (const auto& key : m_inSegmentKeys) {
48 m_truthDecorKeys.emplace_back(key, "truthParticleLink");
49 }
50 }
51 ATH_CHECK(m_truthDecorKeys.initialize());
52 ATH_CHECK(m_idHelperSvc.retrieve());
53 ATH_CHECK(m_geoCtxKey.initialize());
54 m_tree.addBranch(std::make_shared<MuonVal::EventHashBranch>(m_tree.tree()));
55 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
56 if (m_visionTool.empty()) {
57 m_tree.disableBranch(m_spoint_trueLabel.name());
58 }
59 ATH_CHECK(m_tree.init(this));
60 ATH_CHECK(m_idHelperSvc.retrieve());
61 ATH_MSG_DEBUG("Successfully initialized");
62
63 return StatusCode::SUCCESS;
64 }
65
67 ATH_CHECK(m_tree.write());
68 return StatusCode::SUCCESS;
69 }
70
72 const EventContext& ctx{Gaudi::Hive::currentContext()};
75 for (unsigned keyNum = 0 ; keyNum < m_spacePointKeys.size(); ++keyNum) {
77 keyNum < m_inSegmentKeys.size() ? m_inSegmentKeys[keyNum] : emptyKey ));
78 }
79 return StatusCode::SUCCESS;
80 }
81 StatusCode BucketDumperAlg::dumpContainer(const EventContext& ctx,
82 const SG::ReadHandleKey<SpacePointContainer>& spacePointKey,
84
85 using SegmentsPerBucket_t = std::unordered_map <const SpacePointBucket*,
86 std::set<const xAOD::MuonSegment*, LocalSegSorter>>;
87
88 SegmentsPerBucket_t segmentMap{};
89
90 const xAOD::MuonSegmentContainer* readSegment{nullptr};
91 ATH_CHECK(SG::get(readSegment, segmentKey, ctx));
92 if (readSegment) {
93 for (const xAOD::MuonSegment* segment : *readSegment) {
94 segmentMap[detailedSegment(*segment)->parent()->parentBucket()].insert(segment);
95 }
96 }
97
98 const ActsTrk::GeometryContext* gctx{nullptr};
99 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
100
101 const SpacePointContainer* spContainer{nullptr};
102 ATH_CHECK(SG::get(spContainer, spacePointKey, ctx));
103
104 CLHEP::HepRandomEngine* rndEngine = getRandomEngine(ctx);
105
106 const SpacePointPerLayerSorter layerSorter{};
107
108 for(const SpacePointBucket* bucket : *spContainer) {
110 if (!m_isMC && segmentMap[bucket].empty() && m_fracToKeep < 1. &&
111 CLHEP::RandFlat::shoot(rndEngine,0.,1.) > m_fracToKeep) {
112 ATH_MSG_VERBOSE("Skipping bucket without segment");
113 continue;
114 }
116 m_bucket_sector = bucket->msSector()->sector();
117 m_bucket_chamberIdx = static_cast<uint8_t>(bucket->msSector()->chamberIndex());
118 m_bucket_side = bucket->msSector()->side();
120 m_bucket_min = bucket->coveredMin();
121 m_bucket_max = bucket->coveredMax();
122
124 const Amg::Vector3D bucketPos = bucket->msSector()->localToGlobalTrans(*gctx) *
125 (0.5*(bucket->coveredMin() + bucket->coveredMax()) * Amg::Vector3D::UnitY());
126 m_bucket_posX = bucketPos.x();
127 m_bucket_posY = bucketPos.y();
128 m_bucket_posZ = bucketPos.z();
129
131 m_bucket_truthHit = std::ranges::any_of(*bucket,[this](const SpacePointBucket::value_type & sp){
132 return m_visionTool->isLabeled(*sp);
133 });
134
136 m_bucket_segments = segmentMap[bucket].size();
137
138
139
140 std::unordered_map<const SpacePoint*, std::vector<int16_t>> spacePointToSegment{};
141 std::set<const xAOD::MuonSegment*, LocalSegSorter> truthSegments{};
143 auto match_itr = segmentMap.find(bucket);
144 if (match_itr != segmentMap.end()) {
145 for (const xAOD::MuonSegment* segment : match_itr->second) {
146 for (const auto& meas : detailedSegment(*segment)->measurements()) {
147 if (meas->fitState() == CalibratedSpacePoint::State::Valid) {
148 spacePointToSegment[meas->spacePoint()].push_back(segment->index());
149 }
150 }
151 using namespace SegmentFit;
152 const auto pars = localSegmentPars(*segment);
153 m_segmentLocX += pars[Acts::toUnderlying(ParamDefs::x0)];
154 m_segmentLocY += pars[Acts::toUnderlying(ParamDefs::y0)];
155 m_segmentLocTheta += pars[Acts::toUnderlying(ParamDefs::theta)];
156 m_segmentLocPhi += pars[Acts::toUnderlying(ParamDefs::phi)];
157
159 unsigned truthLink = -1;
160 if (const xAOD::TruthParticle* truthPart = getTruthMatchedParticle(*segment)) {
161 truthLink = truthPart->index();
162 }
164 if (const xAOD::MuonSegment* truthSeg = getMatchedTruthSegment(*segment)) {
165 truthSegments.insert(truthSeg);
166 }
167 m_segmentTruthIdx+=truthLink;
168 m_segmentPos.push_back(segment->position());
169 m_segmentDir.push_back(segment->direction());
170 m_segment_chiSquared.push_back(segment->chiSquared());
171 m_segment_numberDoF.push_back(segment->numberDoF());
172 }
173 }
174
175 std::vector<unsigned int> layNumbers{};
176 std::unordered_map<const SpacePoint*, std::vector<const xAOD::MuonSegment*>> spToTrueSeg{};
177 if (m_isMC) {
178 using SegLinkVec_t = std::vector<ElementLink<xAOD::MuonSegmentContainer>>;
179 static const SG::ConstAccessor<SegLinkVec_t> segAcc{"truthSegmentLinks"};
180 for (const auto& sp : *bucket){
181 for (const auto& link : segAcc(*sp->primaryMeasurement())) {
182 spToTrueSeg[sp.get()].push_back(*link);
183 truthSegments.insert(*link);
184 }
185 }
186 }
187
188 for(const SpacePointBucket::value_type& sp : *bucket) {
190 const unsigned int layNum = layerSorter.sectorLayerNum(*sp);
191 if (std::find(layNumbers.begin(), layNumbers.end(), layNum) == layNumbers.end()) {
192 layNumbers.push_back(layNum);
193 }
194 const unsigned layer = layNumbers.size()-1;
195
196 const Identifier& id = sp->identify();
197
199 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(sp->primaryMeasurement());
200 if (dc->status() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime){
201 continue;
202 }
203 m_spoint_isMdt.push_back(true);
204 m_spoint_isStrip.push_back(false);
205 m_spoint_adc.push_back(dc->adc());
206 m_spoint_tdc.push_back(dc->tdc());
207 } else {
208 // check the technology to fill channel, adc and tdc... pushing back 0 for now
209 m_spoint_adc.push_back(0);
210 m_spoint_tdc.push_back(0);
211 m_spoint_isMdt.push_back(false);
212 m_spoint_isStrip.push_back(true);
213 }
214
215 m_spoint_id.push_back(id);
216
217
218 const std::vector<int16_t>& segIdxs = spacePointToSegment[sp.get()];
219 m_spoint_mat[m_spoint_mat.size()] = segIdxs;
220 auto& trueSegLinks = m_spoint_trueSeg[m_spoint_trueSeg.size()];
221 for (const xAOD::MuonSegment* matchedSeg : spToTrueSeg[sp.get()]) {
222 trueSegLinks.push_back(std::distance(truthSegments.begin(), truthSegments.find(matchedSeg)));
223 }
224 m_spoint_nSegments.push_back(segIdxs.size());
225
226 m_bucket_spacePoints = bucket->size();
227 m_spoint_localPosition.push_back(sp->localPosition());
229 m_spoint_covX.push_back(sp->covariance()[Acts::toUnderlying(CovIdx::phiCov)]);
230 m_spoint_covY.push_back(sp->covariance()[Acts::toUnderlying(CovIdx::etaCov)]);
231 m_spoint_driftR.push_back(sp->driftRadius());
232 m_spoint_measuresEta.push_back(sp->measuresEta());
233 m_spoint_measuresPhi.push_back(sp->measuresPhi());
234 m_spoint_nEtaInstances.push_back(sp->nEtaInstanceCounts());
235 m_spoint_nPhiInstances.push_back(sp->nPhiInstanceCounts());
236 m_spoint_dimension.push_back(sp->dimension());
237 m_spoint_layer.push_back(layer);
238 if (m_visionTool.isEnabled()) {
239 m_spoint_trueLabel.push_back(m_visionTool->isLabeled(*sp));
240 }
241
242 Amg::Vector3D globalPos = sp->msSector()->localToGlobalTrans(*gctx) * sp->localPosition();
243 m_spoint_globalPosition.push_back( globalPos );
244 }
245
246 for (const xAOD::MuonSegment* truthSeg: truthSegments) {
247 using namespace SegmentFit;
248 const auto truthPars = localSegmentPars(*truthSeg);
249 m_truthSegLocX += truthPars[Acts::toUnderlying(ParamDefs::x0)];
250 m_truthSegLocY += truthPars[Acts::toUnderlying(ParamDefs::y0)];
251 m_truthSegLocTheta += truthPars[Acts::toUnderlying(ParamDefs::theta)];
252 m_truthSegLocPhi += truthPars[Acts::toUnderlying(ParamDefs::phi)];
253 }
254
255 m_bucket_layers = layNumbers.size();
256
257 if (!m_tree.fill(ctx)) {
258 return StatusCode::FAILURE;
259 }
260 }
261
262 return StatusCode::SUCCESS;
263
264 }
265
266 CLHEP::HepRandomEngine* BucketDumperAlg::getRandomEngine(const EventContext&ctx) const {
267 ATHRNG::RNGWrapper* rngWrapper = m_rndmSvc->getEngine(this, m_streamName);
268 std::string rngName = m_streamName;
269 rngWrapper->setSeed(rngName, ctx);
270 return rngWrapper->getEngine(ctx);
271 }
272
273}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
static Double_t sp
static Double_t a
Handle class for reading from StoreGate.
static const Attributes_t empty
A wrapper class for event-slot-local random engines.
Definition RNGWrapper.h:56
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Definition RNGWrapper.h:169
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
Definition RNGWrapper.h:134
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
MuonVal::ScalarBranch< Char_t > & m_bucket_side
MuonVal::ThreeVectorBranch m_spoint_localPosition
MuonVal::VectorBranch< unsigned short > & m_spoint_measuresEta
MuonVal::ScalarBranch< uint8_t > & m_bucket_sector
MuonVal::VectorBranch< float > & m_truthSegLocTheta
MuonVal::VectorBranch< float > & m_segment_numberDoF
SG::ReadHandleKeyArray< SpacePointContainer > m_spacePointKeys
StatusCode dumpContainer(const EventContext &ctx, const SG::ReadHandleKey< SpacePointContainer > &spacePointKey, const SG::ReadHandleKey< xAOD::MuonSegmentContainer > &segmentKey)
Dumps the space point container with the associated muon segment container.
MuonVal::ScalarBranch< float > & m_bucket_min
MuonVal::VectorBranch< uint16_t > & m_spoint_layer
MuonVal::ThreeVectorBranch m_segmentPos
MuonVal::VectorBranch< float > & m_spoint_covX
MuonVal::VectorBranch< float > & m_segmentLocTheta
MuonVal::VectorBranch< float > & m_truthSegLocY
MuonVal::VectorBranch< float > & m_segment_chiSquared
CLHEP::HepRandomEngine * getRandomEngine(const EventContext &ctx) const
MuonVal::MatrixBranch< int16_t > & m_spoint_mat
MuonVal::ScalarBranch< float > & m_bucket_posZ
MuonVal::ScalarBranch< uint16_t > & m_bucket_layers
MuonVal::VectorBranch< float > & m_truthSegLocPhi
MuonVal::VectorBranch< float > & m_segmentLocY
MuonVal::VectorBranch< uint16_t > & m_segmentTruthIdx
virtual StatusCode initialize() override final
MuonVal::MuonTesterTree m_tree
MuonVal::VectorBranch< float > & m_segmentLocX
Gaudi::Property< double > m_fracToKeep
MuonVal::ScalarBranch< float > & m_bucket_max
virtual StatusCode execute() override final
MuonVal::VectorBranch< uint16_t > & m_spoint_nSegments
SG::ReadDecorHandleKeyArray< xAOD::MuonSegmentContainer > m_truthDecorKeys
Gaudi::Property< bool > m_isMC
MuonVal::VectorBranch< unsigned int > & m_spoint_nPhiInstances
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
MuonVal::ScalarBranch< uint8_t > & m_bucket_truthHit
Gaudi::Property< std::string > m_streamName
MuonVal::ThreeVectorBranch m_segmentDir
MuonVal::VectorBranch< uint16_t > & m_spoint_tdc
MuonVal::VectorBranch< float > & m_spoint_driftR
MuonVal::ScalarBranch< float > & m_bucket_posY
MuonVal::VectorBranch< float > & m_segmentLocPhi
MuonVal::ScalarBranch< float > & m_bucket_posX
MuonVal::VectorBranch< uint16_t > & m_spoint_adc
MuonVal::MuonIdentifierBranch m_spoint_id
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
MuonVal::ScalarBranch< uint16_t > & m_bucket_segments
MuonVal::VectorBranch< unsigned int > & m_spoint_dimension
SG::ReadHandleKeyArray< xAOD::MuonSegmentContainer > m_inSegmentKeys
MuonVal::ScalarBranch< uint8_t > & m_bucket_chamberIdx
MuonVal::VectorBranch< float > & m_spoint_covY
MuonVal::MatrixBranch< int16_t > & m_spoint_trueSeg
MuonVal::VectorBranch< unsigned short > & m_spoint_isStrip
MuonVal::VectorBranch< unsigned int > & m_spoint_nEtaInstances
MuonVal::VectorBranch< float > & m_truthSegLocX
MuonVal::VectorBranch< unsigned short > & m_spoint_trueLabel
ServiceHandle< IAthRNGSvc > m_rndmSvc
MuonVal::ScalarBranch< uint16_t > & m_bucket_spacePoints
MuonVal::VectorBranch< unsigned short > & m_spoint_isMdt
virtual StatusCode finalize() override final
MuonVal::ThreeVectorBranch m_spoint_globalPosition
MuonVal::VectorBranch< unsigned short > & m_spoint_measuresPhi
const SpacePointBucket * parentBucket() const
Returns the bucket out of which the seed was formed.
const SegmentSeed * parent() const
Returns the seed out of which the segment was built.
const MeasVec & measurements() const
Returns the associated measurements.
: The muon space point bucket represents a collection of points that will bre processed together in t...
The SpacePointPerLayerSorter sort two given space points by their layer Identifier.
unsigned int sectorLayerNum(const SpacePoint &sp) const
method returning the logic layer number
size_t index() const
Return the index of this element within its container.
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 initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
float numberDoF() const
Returns the numberDoF.
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
float chiSquared() const
Amg::Vector3D position() const
Returns the position as Amg::Vector.
Eigen::Matrix< double, 3, 1 > Vector3D
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
This header ties the generic definitions in this package.
const xAOD::TruthParticle * getTruthMatchedParticle(const xAOD::MuonSegment &segment)
Returns the particle truth-matched to the segment.
const xAOD::MuonSegment * getMatchedTruthSegment(const xAOD::MuonSegment &segment)
Returns the truth-matched segment.
std::vector< SegLink_t > SegLinkVec_t
SpacePoint::CovIdx CovIdx
########################################## SpacePointMakerAlg #######################################...
DataVector< SpacePointBucket > SpacePointContainer
Abrivation of the space point container type.
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
MdtDriftCircle_v1 MdtDriftCircle
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
TruthParticle_v1 TruthParticle
Typedef to implementation.
MuonSegment_v1 MuonSegment
Reference the current persistent version: