ATLAS Offline Software
Loading...
Searching...
No Matches
MuonHoughTransformTester.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "GaudiKernel/SystemOfUnits.h"
8
16#include "Acts/Utilities/Enumerate.hpp"
17#include "GaudiKernel/PhysicalConstants.h"
19
22
23
24namespace {
25 constexpr double c_inv = 1. /Gaudi::Units::c_light;
26
27 template <typename SegObj>
28
29 unsigned countMatched(const xAOD::MuonSegment* truthSeg,
30 const SegObj& obj) {
31 return truthSeg != nullptr ?
32 std::ranges::count_if(getMatchingSimHits(obj), [truthSeg](const xAOD::MuonSimHit* hit) {
33 return MuonR4::getMatchedTruthSegment(*hit) == truthSeg;
34 }) : 0;
35 }
36}
37
38
39namespace MuonValR4 {
40 using namespace MuonR4;
41 using namespace MuonVal;
43
44
46 ATH_CHECK(m_geoCtxKey.initialize());
47
48 {
49 int infoOpts = 0;
50 if (m_isMC) infoOpts = EventInfoBranch::isMC;
51 m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, infoOpts));
52 }
53
54 ATH_CHECK(m_recoSegKey.initialize());
55 for (const std::string& recoLink : m_recoSegLinks) {
56 m_truthSegLinkKeys.emplace_back(m_recoSegKey, recoLink);
57 }
58 ATH_CHECK(m_truthSegmentKey.initialize(!m_truthSegmentKey.empty()));
59 for (const std::string& link: m_truthLinks) {
60 m_truthSegLinkKeys.emplace_back(m_truthSegmentKey, link);
61 }
63
65 ATH_CHECK(m_patternSeedKeys.initialize());
68 m_spTester = std::make_unique<SpacePointTesterModule>(m_tree, m_spKeys.front().key(), msgLevel());
69 m_tree.addBranch(m_spTester);
70 } else {
71 m_tree.disableBranch(m_spMatchedToPattern.name());
72 m_tree.disableBranch(m_spMatchedToSegment.name());
73 }
74 ATH_CHECK(m_tree.init(this));
75 ATH_CHECK(m_idHelperSvc.retrieve());
76 ATH_CHECK(detStore()->retrieve(m_detMgr));
77
78 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
79 ATH_MSG_DEBUG("Succesfully initialised");
80 return StatusCode::SUCCESS;
81 }
82
83
85 const xAOD::MuonSegment& truthSeg,
86 const MuonR4::Segment& recoSeg) const{
87 unsigned int same{0};
88 using namespace SegmentFit;
89 const auto[truePos, trueDir] = makeLine(localSegmentPars(truthSeg));
90 const auto[recoPos, recoDir] = makeLine(localSegmentPars(gctx, recoSeg));
91 const std::vector<int> truthSigns = SeedingAux::strawSigns(truePos, trueDir, recoSeg.measurements());
92 const std::vector<int> recoSigns = SeedingAux::strawSigns(recoPos, recoDir, recoSeg.measurements());
93 for (unsigned int s = 0 ; s < truthSigns.size(); ++s) {
94 same += (truthSigns[s] != 0) && truthSigns[s] == recoSigns[s];
95 }
96 return same;
97 }
98 std::vector<ObjectMatching>
100 const MuonR4::SegmentSeedContainer& seedContainer,
101 const xAOD::MuonSegmentContainer& segmentContainer,
102 const xAOD::MuonSegmentContainer* truthSegments) const {
103 std::vector<ObjectMatching> allAssociations{};
104 std::unordered_set<const SegmentSeed*> usedSeeds{};
107 for (const xAOD::MuonSegment* recoSeg : segmentContainer) {
108 const MuonR4::Segment* segment = detailedSegment(*recoSeg);
109 assert(segment != nullptr);
110 std::vector<ObjectMatching>::iterator assoc_itr = allAssociations.end();
111 const xAOD::MuonSegment* truthSeg = getMatchedTruthSegment(*recoSeg);
112 if (truthSeg) {
113 assoc_itr = std::ranges::find_if(allAssociations, [truthSeg](const ObjectMatching& obj){
114 return obj.truthSegment == truthSeg;
115 });
116 }
117 if (assoc_itr == allAssociations.end()) {
118 ObjectMatching & newObj = allAssociations.emplace_back();
119 newObj.chamber = m_detMgr->getSectorEnvelope(recoSeg->chamberIndex(),
120 recoSeg->sector(),
121 recoSeg->etaIndex());
122 newObj.truthSegment = truthSeg;
123 assoc_itr = allAssociations.end() -1;
124 }
125 ObjectMatching& assocObj{*assoc_itr};
126 assocObj.matchedSegments.push_back(segment);
127 if (!truthSeg) {
128 assocObj.matchedSeeds.push_back(segment->parent());
129 }
130 assocObj.matchedSeedFoundSegment.push_back(1);
131 usedSeeds.insert(segment->parent());
132 }
133
134 if (truthSegments) {
135 for (ObjectMatching& assocObj : allAssociations) {
136 if (!assocObj.truthSegment) {
137 continue;
138 }
139 std::ranges::sort(assocObj.matchedSegments,
140 [&](const Segment* a, const Segment* b){
141 return countOnSameSide(gctx,*assocObj.truthSegment, *a) >
142 countOnSameSide(gctx,*assocObj.truthSegment, *b);
143 });
144 std::ranges::transform(assocObj.matchedSegments, std::back_inserter(assocObj.matchedSeeds),
146 }
147
148 }
150 for (const SegmentSeed* seed : seedContainer) {
152 if (usedSeeds.count(seed)) {
153 continue;
154 }
156 std::vector<std::pair<const xAOD::MuonSegment*, std::size_t>> segCounts{};
157 std::unordered_set<const xAOD::MuonSimHit* > matchedHits = getMatchingSimHits(*seed);
158 for (const xAOD::MuonSimHit* hit : matchedHits) {
159 const xAOD::MuonSegment* truthSeg = getMatchedTruthSegment(*hit);
160 if (!truthSeg) {
161 continue;
162 }
163 auto count_itr = std::ranges::find_if(segCounts, [truthSeg](const auto& segCounter){
164 return segCounter.first == truthSeg;
165 });
166 if (count_itr != segCounts.end()) {
167 ++(count_itr->second);
168 } else {
169 segCounts.emplace_back(std::make_pair(truthSeg, 1ul));
170 }
171 }
173 std::ranges::sort(segCounts, [](const auto& a, const auto& b){
174 return a.second > b.second;
175 });
176 // Add a criterion on the number of counts?
177 const xAOD::MuonSegment* truthSeg = segCounts.size()
178 ? segCounts.front().first : nullptr;
179 if (truthSeg) {
180 auto assoc_itr = std::ranges::find_if(allAssociations,
181 [truthSeg](const ObjectMatching& obj){
182 return obj.truthSegment == truthSeg;
183 });
184 if (assoc_itr == allAssociations.end()) {
185 ObjectMatching & newObj = allAssociations.emplace_back();
186 newObj.chamber = seed->msSector();
187 newObj.truthSegment = truthSeg;
188 assoc_itr = allAssociations.end() -1;
189 }
190 assoc_itr->matchedSeeds.push_back(seed);
191 assoc_itr->matchedSeedFoundSegment.push_back(0);
192 } else {
193 ObjectMatching & newObj = allAssociations.emplace_back();
194 newObj.chamber = seed->msSector();
195 newObj.matchedSeeds.push_back(seed);
196 newObj.matchedSeedFoundSegment.push_back(0);
197 }
198 }
200 if (truthSegments) {
201 for (const xAOD::MuonSegment* truthSeg : *truthSegments) {
203 if (std::ranges::any_of(allAssociations, [truthSeg](const auto& assocObj){
204 return assocObj.truthSegment == truthSeg;
205 })) {
206 continue;
207 }
208 ObjectMatching & newObj = allAssociations.emplace_back();
209 newObj.chamber = m_detMgr->getSectorEnvelope(truthSeg->chamberIndex(),
210 truthSeg->sector(),
211 truthSeg->etaIndex());
212 newObj.truthSegment = truthSeg;
213 }
214 }
215 return allAssociations;
216 }
217
219 ATH_CHECK(m_tree.write());
220 return StatusCode::SUCCESS;
221 }
222 StatusCode MuonHoughTransformTester::execute(const EventContext& ctx) {
223
224 const ActsTrk::GeometryContext* gctxPtr{nullptr};
225 ATH_CHECK(SG::get(gctxPtr, m_geoCtxKey, ctx));
226 const ActsTrk::GeometryContext& gctx{*gctxPtr};
227
230 const SegmentSeedContainer* readSegmentSeeds{nullptr};
231 ATH_CHECK(SG::get(readSegmentSeeds, key, ctx));
232 segmentSeeds.insert(segmentSeeds.end(), readSegmentSeeds->begin(), readSegmentSeeds->end());
233 }
234
235 const xAOD::MuonSegmentContainer* truthSegments{nullptr};
236 ATH_CHECK(SG::get(truthSegments, m_truthSegmentKey, ctx));
237
238 const xAOD::MuonSegmentContainer* recoSegments{nullptr};
239 ATH_CHECK(SG::get(recoSegments, m_recoSegKey, ctx));
240
241 ATH_MSG_DEBUG("Succesfully retrieved input collections. Seeds: "<<segmentSeeds.size()
242 <<", segments: "<<recoSegments->size()
243 <<", truth segments: "<<(truthSegments? truthSegments->size() : -1)
244 <<".");
245 std::vector<ObjectMatching> objects = matchWithTruth(gctx, *segmentSeeds.asDataVector(),
246 *recoSegments, truthSegments);
247 for (const ObjectMatching& obj : objects) {
248 fillChamberInfo(obj.chamber);
249 fillSeedInfo(obj);
250 fillSegmentInfo(gctx, obj);
251 if(m_isMC) fillTruthInfo(gctx, obj.truthSegment);
252 ATH_CHECK(m_tree.fill(ctx));
253 }
254 return StatusCode::SUCCESS;
255 }
257 m_out_chamberIndex = Acts::toUnderlying(msSector->chamberIndex());
258 m_out_stationSide = msSector->side();
259 m_out_stationPhi = msSector->stationPhi();
260 }
262 const xAOD::MuonSegment* segment) {
263 if (!segment) {
264 return;
265 }
266 m_out_hasTruth = true;
267
268 const Amg::Vector3D segDir{segment->direction()};
269 static const SG::ConstAccessor<float> acc_pt{"pt"};
270 static const SG::ConstAccessor<float> acc_charge{"charge"};
271 // eta is interpreted as the eta-location
272 m_out_gen_Eta = segDir.eta();
273 m_out_gen_Phi = segDir.phi();
274 m_out_gen_Pt = acc_pt(*segment);
275 m_out_gen_Q = acc_charge(*segment);
276
277 const auto [chamberPos, chamberDir] = SegmentFit::makeLine(SegmentFit::localSegmentPars(*segment));
278 m_out_gen_nHits = segment->nPrecisionHits()+segment->nPhiLayers() + segment->nTrigEtaLayers();
279 using namespace Muon::MuonStationIndex;
280
281 ATH_MSG_DEBUG("Number of precision Hits in the truth segment is "<<segment->nPrecisionHits()<<" and number of phi layers is "<<segment->nPhiLayers()<<" and number of trigger eta layers is "<<segment->nTrigEtaLayers());
282
285 m_out_gen_nTGCHits = (segment->nPhiLayers() + segment->nTrigEtaLayers()) * !isBarrel(segment->chamberIndex());
286 m_out_gen_nRPCHits = (segment->nPhiLayers() + segment->nTrigEtaLayers()) * isBarrel(segment->chamberIndex());
287
288 unsigned nMMHits{0}, nSTGHits{0};
289 for (const xAOD::MuonSimHit* simHit : getMatchingSimHits(*segment)) {
290 const TechnologyIndex simIdx = m_idHelperSvc->technologyIndex(simHit->identify());
291 nMMHits += simIdx == TechnologyIndex::MM;
292 nSTGHits += simIdx == TechnologyIndex::STGC;
293 }
294 m_out_gen_nMmHits = nMMHits;
295 m_out_gen_nSTGCHits = nSTGHits;
296
297 m_out_gen_tantheta = houghTanBeta(chamberDir);
298 m_out_gen_tanphi = houghTanAlpha(chamberDir);
299 m_out_gen_y0 = chamberPos.y();
300 m_out_gen_x0 = chamberPos.x();
301 m_out_gen_time = segment->t0();
302
303 double minYhit = std::numeric_limits<double>::max();
304 double maxYhit = -1 * std::numeric_limits<double>::max();
305 for (const xAOD::MuonSimHit* hit : getMatchingSimHits(*segment)){
306 const Identifier hitId = hit->identify();
307 const MuonGMR4::MuonReadoutElement* RE = m_detMgr->getReadoutElement(hitId);
308 const IdentifierHash hash{m_idHelperSvc->isMdt(hitId) ? RE->measurementHash(hitId)
309 : RE->layerHash(hitId) };
310 const Amg::Transform3D localToChamber = RE->msSector()->globalToLocalTransform(gctx) * RE->localToGlobalTransform(gctx, hash);
311 const Amg::Vector3D chamberPos = localToChamber * xAOD::toEigen(hit->localPosition());
312 minYhit = std::min(chamberPos.y(), minYhit);
313 maxYhit = std::max(chamberPos.y(), maxYhit);
314 }
315 m_out_gen_minYhit = minYhit;
316 m_out_gen_maxYhit = maxYhit;
317
318 ATH_MSG_DEBUG("A true max on chamber index "<<m_out_chamberIndex.getVariable()<<" side "<<m_out_stationSide.getVariable()<<" phi "<<m_out_stationPhi.getVariable()<<" with "
319 <<m_out_gen_nMDTHits.getVariable()<<" MDT and "<<m_out_gen_nRPCHits.getVariable()+m_out_gen_nTGCHits.getVariable()<< " trigger hits is at "
320 <<m_out_gen_tantheta.getVariable()<<" and "<<m_out_gen_y0.getVariable());
321
322 const xAOD::TruthParticle* truthMuon = getTruthMatchedParticle(*segment);
323 if (truthMuon) {
324 using namespace xAOD::TruthHelpers;
327 m_out_gen_truthBeta = truthMuon->p4().Beta();
328 m_out_gen_truthPdgId = truthMuon->pdgId();
329 }
330 }
332 m_out_bucketEnd = bucket.coveredMax();
333 m_out_bucketStart = bucket.coveredMin();
334 m_out_nSpacePoints = bucket.size();
335
336 ATH_MSG_DEBUG("Filling bucket with "<<bucket.size()<<" space points between "<< bucket.coveredMin() <<" and "<< bucket.coveredMax() );
337
338 // Because the space points are first ordered by layers and then local y within the layer we need to resort them to compute the max gap in y between consecutive hits in the bucket
339 std::vector<const MuonR4::SpacePoint*> etaHits{};
340 etaHits.reserve(bucket.size());
341 for (const auto& sp : bucket) {
342 if (sp->measuresEta()) {
343 etaHits.push_back(sp.get());
344 }
345 }
346 std::ranges::sort(etaHits, [](const MuonR4::SpacePoint* a,
347 const MuonR4::SpacePoint* b) {
348 return a->localPosition().y() < b->localPosition().y();
349 });
350
351
352 double maxEtaHitGap{-1.f};
353 for (std::size_t i = 1; i < etaHits.size(); ++i) {
354 maxEtaHitGap = std::max(maxEtaHitGap,
355 std::abs(etaHits[i]->localPosition().y()
356 - etaHits[i - 1]->localPosition().y()));
357 }
358
359 m_out_bucketEtaHitGap = maxEtaHitGap;
360
361
362 m_out_nPrecSpacePoints = std::ranges::count_if(bucket, [](const SpacePointBucket::value_type& sp){
363 return isPrecisionHit(*sp);
364 });
365 m_out_nPhiSpacePoints = std::ranges::count_if(bucket, [](const SpacePointBucket::value_type& sp){
366 return sp->measuresPhi();
367 });
368 if (!m_visionTool.isEnabled()){
369 return;
370 }
371 m_out_nTrueSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
372 return m_visionTool->isLabeled(*sp);
373 });
374 m_out_nTruePrecSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
375 return isPrecisionHit(*sp) && m_visionTool->isLabeled(*sp);
376 });
377 m_out_nTruePhiSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
378 return sp->measuresPhi() && m_visionTool->isLabeled(*sp);
379 });
380 }
382
383 m_out_seed_n = obj.matchedSeeds.size();
384 for (const auto [iseed, seed] : Acts::enumerate(obj.matchedSeeds)){
385 if (iseed ==0) {
386 fillBucketInfo(*seed->parentBucket());
387 }
388 double minYhit = m_out_bucketEnd.getVariable();
389 double maxYhit = m_out_bucketStart.getVariable();
390 for (const SpacePoint* hit : seed->getHitsInMax()){
391 minYhit = std::min(hit->localPosition().y(),minYhit);
392 maxYhit = std::max(hit->localPosition().y(),maxYhit);
393 }
394 m_out_seed_minYhit.push_back(minYhit);
395 m_out_seed_maxYhit.push_back(maxYhit);
396
397 m_out_seed_hasPhiExtension.push_back(seed->hasPhiExtension());
398 m_out_seed_nMatchedHits.push_back(countMatched(obj.truthSegment, *seed));
399 m_out_seed_y0.push_back(seed->interceptY());
400 m_out_seed_tantheta.push_back(seed->tanBeta());
401 if (seed->hasPhiExtension()){
402 m_out_seed_x0.push_back(seed->interceptX());
403 m_out_seed_tanphi.push_back(seed->tanAlpha());
404 } else{
405 m_out_seed_x0.push_back(-999);
406 m_out_seed_tanphi.push_back(-999);
407 }
408
409 m_out_seed_nHits.push_back(seed->getHitsInMax().size());
410 unsigned nMdtSeed{0}, nRpcSeed{0}, nTgcSeed{0}, nMmEtaSeed{0}, nMmStereoSeed{0},
411 nsTgcStripSeed{0}, nsTgcWireSeed{0}, nsTgcPadSeed{0};
412 unsigned nPrecHits{0}, nEtaHits{0}, nPhiHits{0}, nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
413 std::vector<unsigned char> treeIdxs{};
414
415 for (const HoughHitType & houghSP: seed->getHitsInMax()){
417 unsigned treeIdx = m_spTester->push_back(*houghSP);
418 treeIdxs.push_back(treeIdx);
419 }
420 nPrecHits += isPrecisionHit(*houghSP);
421 nPhiHits += houghSP->measuresPhi();
422 nEtaHits += houghSP->measuresEta();
423
424 if (m_visionTool.isEnabled()) {
425 nTrueHits += m_visionTool->isLabeled(*houghSP);
426 nTruePrecHits += m_visionTool->isLabeled(*houghSP) && isPrecisionHit(*houghSP);
427 nTruePhiHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresPhi();
428 nTrueEtaHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresEta();
429 }
430 switch (houghSP->type()) {
432 ++nMdtSeed;
433 break;
435 nRpcSeed+=houghSP->measuresEta();
436 nRpcSeed+=houghSP->measuresPhi();
437 break;
439 nTgcSeed+=houghSP->measuresEta();
440 nTgcSeed+=houghSP->measuresPhi();
441 break;
443 const Identifier sTgc = houghSP->primaryMeasurement()->identify();
444 const Identifier sTgc2 = houghSP->secondaryMeasurement() ?
445 houghSP->secondaryMeasurement()->identify() : Identifier{};
446 const sTgcIdHelper& idHelper{m_idHelperSvc->stgcIdHelper()};
447 const int primType = idHelper.channelType(sTgc);
448 const int secType = idHelper.channelType(sTgc2);
449 nsTgcStripSeed += primType == sTgcIdHelper::sTgcChannelTypes::Strip;
450 nsTgcWireSeed += primType == sTgcIdHelper::sTgcChannelTypes::Wire;
451 nsTgcPadSeed += primType == sTgcIdHelper::sTgcChannelTypes::Pad;
452
453 nsTgcWireSeed += secType == sTgcIdHelper::sTgcChannelTypes::Wire;
454 nsTgcPadSeed += primType != sTgcIdHelper::sTgcChannelTypes::Pad &&
456 break;
458 if (m_idHelperSvc->mmIdHelper().isStereo(houghSP->identify())) {
459 ++nMmEtaSeed;
460 } else {
461 ++nMmStereoSeed;
462 }
463 break;
464 }default:
465 ATH_MSG_WARNING("Technology "<<houghSP->identify() <<" not yet implemented");
466 }
467 }
468 m_out_seed_nMdt.push_back(nMdtSeed);
469 m_out_seed_nRpc.push_back(nRpcSeed);
470 m_out_seed_nTgc.push_back(nTgcSeed);
471
472 m_out_seed_nMmEta.push_back(nMmEtaSeed);
473 m_out_seed_nMmStereo.push_back(nMmStereoSeed);
474
475 m_out_seed_nsTgcStrip.push_back(nsTgcStripSeed);
476 m_out_seed_nsTgcWire.push_back(nsTgcWireSeed);
477 m_out_seed_nsTgcPad.push_back(nsTgcPadSeed);
478
479 m_out_seed_nPrecHits.push_back(nPrecHits);
480 m_out_seed_nEtaHits.push_back(nEtaHits);
481 m_out_seed_nPhiHits.push_back(nPhiHits);
482
483 m_out_seed_nTrueHits.push_back(nTrueHits);
484 m_out_seed_nTruePrecHits.push_back(nTruePrecHits);
485 m_out_seed_nTrueEtaHits.push_back(nTrueEtaHits);
486 m_out_seed_nTruePhiHits.push_back(nTruePhiHits);
487
488 m_out_seed_ledToSegment.push_back(obj.matchedSeedFoundSegment.at(iseed));
489 if (m_writeSpacePoints) {
490 m_spMatchedToPattern[iseed] = std::move(treeIdxs);
491
492 }
493 }
494 }
495
497 const ObjectMatching& obj){
498 using namespace SegmentFit;
499
500 m_out_segment_n = obj.matchedSegments.size();
501 for (const Segment* segment : obj.matchedSegments) {
502 m_out_segment_hasPhi.push_back(std::ranges::any_of(segment->measurements(),
503 [](const auto& meas){ return meas->measuresPhi();}));
504 m_out_segment_fitIter.push_back(segment->nFitIterations());
505 m_out_segment_truthMatchedHits.push_back(countMatched(obj.truthSegment, *segment));
506 m_out_segment_chi2.push_back(segment->chi2());
507 m_out_segment_nDoF.push_back(segment->nDoF());
508 m_out_segment_hasTimeFit.push_back(segment->hasTimeFit());
509
510 m_out_segment_err_x0.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::x0), Acts::toUnderlying(ParamDefs::x0)));
511 m_out_segment_err_y0.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::y0), Acts::toUnderlying(ParamDefs::y0)));
512 m_out_segment_err_tantheta.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::theta), Acts::toUnderlying(ParamDefs::theta)));
513 m_out_segment_err_tanphi.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::phi), Acts::toUnderlying(ParamDefs::phi)));
514 m_out_segment_err_time.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::t0), Acts::toUnderlying(ParamDefs::t0)));
515 const auto [locPos, locDir] = makeLine(localSegmentPars(gctx, *segment));
516 m_out_segment_tanphi.push_back(houghTanAlpha(locDir));
517 m_out_segment_tantheta.push_back(houghTanBeta(locDir));
518 m_out_segment_y0.push_back(locPos.y());
519 m_out_segment_x0.push_back(locPos.x());
520 m_out_segment_time.push_back(segment->segementT0() + segment->position().mag() * c_inv);
521
522 unsigned nMdtHits{0}, nRpcEtaHits{0}, nRpcPhiHits{0}, nTgcEtaHits{0}, nTgcPhiHits{0},
523 nMmEtaHits{0}, nMmStereoHits{0}, nStgcStripHits{0},nStgcWireHits{0}, nStgcPadHits{0};
524 unsigned nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
525
526 double minYhit = std::numeric_limits<double>::max();
527 double maxYhit = -1 * std::numeric_limits<double>::max();
528
529 std::vector<unsigned char> matched;
530 for (const auto & meas : segment->measurements()){
531 // skip dummy measurement from beam spot constraint
532 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Dump "<<(*meas));
533 if (meas->type() == xAOD::UncalibMeasType::Other) {
534 continue;
535 }
536 minYhit = std::min(meas->localPosition().y(),minYhit);
537 maxYhit = std::max(meas->localPosition().y(),maxYhit);
538 if (m_writeSpacePoints) {
539 unsigned treeIdx = m_spTester->push_back(*meas->spacePoint());
540 if (treeIdx >= matched.size()){
541 matched.resize(treeIdx +1);
542 }
543 matched[treeIdx] = true;
544 }
545 if (m_visionTool.isEnabled()) {
546 nTrueHits += m_visionTool->isLabeled(*meas->spacePoint());
547 nTruePrecHits += isPrecisionHit(*meas) && m_visionTool->isLabeled(*meas->spacePoint());
548 nTrueEtaHits += meas->measuresEta() && m_visionTool->isLabeled(*meas->spacePoint());
549 nTruePhiHits += meas->measuresPhi() && m_visionTool->isLabeled(*meas->spacePoint());
550 }
551 switch (meas->type()) {
553 ++nMdtHits;
554 break;
556 nRpcEtaHits += meas->measuresEta();
557 nRpcPhiHits += meas->measuresPhi();
558 break;
560 nTgcEtaHits += meas->measuresEta();
561 nTgcPhiHits += meas->measuresPhi();
562 break;
564 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
565 nMmEtaHits += !idHelper.isStereo(meas->spacePoint()->identify());
566 nMmStereoHits += !idHelper.isStereo(meas->spacePoint()->identify());
567 break;
569 const auto* prd = static_cast<const xAOD::sTgcMeasurement*>(meas->spacePoint()->primaryMeasurement());
570 const int primType = prd->channelType();
571 prd = dynamic_cast<const xAOD::sTgcMeasurement*>(meas->spacePoint()->secondaryMeasurement());
572 const int secType = (prd != nullptr ? prd->channelType() : -1);
573 nStgcStripHits += primType == sTgcIdHelper::sTgcChannelTypes::Strip;
574 nStgcWireHits += primType == sTgcIdHelper::sTgcChannelTypes::Wire;
575 nStgcPadHits += primType == sTgcIdHelper::sTgcChannelTypes::Pad;
576 nStgcWireHits += secType == sTgcIdHelper::sTgcChannelTypes::Wire;
577 nStgcPadHits += primType != secType && secType == sTgcIdHelper::sTgcChannelTypes::Pad;
578 break;
579 } default:
580 break;
581 }
582 }
583 m_out_segment_nMdtHits.push_back(nMdtHits);
584 m_out_segment_nRpcEtaHits.push_back(nRpcEtaHits);
585 m_out_segment_nRpcPhiHits.push_back(nRpcPhiHits);
586 m_out_segment_nTgcEtaHits.push_back(nTgcEtaHits);
587 m_out_segment_nTgcPhiHits.push_back(nTgcPhiHits);
588
589 m_out_segment_nMmEtaHits.push_back(nMmEtaHits);
590 m_out_segment_nMmStereoHits.push_back(nMmStereoHits);
591 m_out_segment_nsTgcStripHits.push_back(nStgcStripHits);
592 m_out_segment_nsTgcWireHits.push_back(nStgcWireHits);
593 m_out_segment_nsTgcPadpHits.push_back(nStgcPadHits);
594
595
596 m_out_segment_nTrueHits.push_back(nTrueHits);
597 m_out_segment_nTruePrecHits.push_back(nTruePrecHits);
598 m_out_segment_nTruePhiHits.push_back(nTruePhiHits);
599 m_out_segment_nTrueEtaHits.push_back(nTrueEtaHits);
600
601 m_out_segment_minYhit.push_back(minYhit);
602 m_out_segment_maxYhit.push_back(maxYhit);
603 if (m_writeSpacePoints) {
604 m_spMatchedToSegment.push_back(std::move(matched));
605 }
606 }
607 }
608} // namespace MuonValR4
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
DataVector adapter that acts like it holds const pointers.
static Double_t sp
static Double_t a
#define y
const ServiceHandle< StoreGateSvc > & detStore() const
hash_t hash(const std::string &histName) const
Method to calculate a 32-bit hash from a string.
DataVector adapter that acts like it holds const pointers.
iterator end() noexcept
Return an iterator pointing past the end of the collection.
iterator insert(iterator position, value_type pElem)
Add a new element to the collection.
const DV * asDataVector() const
Return a pointer to this object, as a const DataVector.
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
This is a "hash" representation of an Identifier.
bool isStereo(const Identifier &id) const
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
const SpectrometerSector * msSector() const
Returns the pointer to the envelope volume enclosing all chambers in the sector.
virtual IdentifierHash measurementHash(const Identifier &measId) const =0
The measurement hash is a continous numbering schema of all readout channels described by the specifi...
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const override final
Returns the transformation from the local coordinate system of the readout element into the global AT...
virtual IdentifierHash layerHash(const Identifier &measId) const =0
The layer hash removes the bits from the IdentifierHash corresponding to the measurement's channel nu...
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 globalToLocalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
int stationPhi() const
: Returns the station phi of the sector
Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index scheme.
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Definition SegmentSeed.h:14
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.
unsigned int nFitIterations() const
Returns how many iterations the fitter needed to make the segment converge.
const SegmentFit::Covariance & covariance() const
Returns the uncertainties of the defining parameters.
const SegmentSeed * parent() const
Returns the seed out of which the segment was built.
const MeasVec & measurements() const
Returns the associated measurements.
const Amg::Vector3D & position() const
Returns the global segment position.
: The muon space point bucket represents a collection of points that will bre processed together in t...
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nMmHits
MuonVal::VectorBranch< unsigned short > & m_out_segment_nMmStereoHits
MuonVal::VectorBranch< unsigned short > & m_out_segment_nRpcPhiHits
MuonVal::ScalarBranch< float > & m_out_gen_Pt
MuonVal::ScalarBranch< unsigned char > & m_out_nTruePhiSpacePoints
Number of phi hits in the bucket.
MuonVal::VectorBranch< float > & m_out_seed_maxYhit
MuonVal::VectorBranch< unsigned short > & m_out_seed_nHits
MuonVal::ScalarBranch< float > & m_out_gen_truthBeta
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
MuonVal::VectorBranch< unsigned short > & m_out_seed_nMmStereo
MuonVal::ScalarBranch< unsigned > & m_out_segment_n
========== Segment block: Filled when we have one or multiple segments =============
MuonVal::VectorBranch< float > & m_out_segment_err_y0
MuonVal::VectorBranch< float > & m_out_segment_err_tantheta
MuonVal::VectorBranch< unsigned char > & m_out_seed_ledToSegment
void fillSegmentInfo(const ActsTrk::GeometryContext &gctx, const ObjectMatching &obj)
Fill the info assciated to the segment.
MuonVal::VectorBranch< unsigned short > & m_out_seed_nTrueEtaHits
const MuonGMR4::MuonDetectorManager * m_detMgr
void fillTruthInfo(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment *truthSegment)
Fill the associated truth information into the tree.
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nHits
Truth - hit count summary.
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
SG::ReadHandleKeyArray< MuonR4::SpacePointContainer > m_spKeys
List of the space point containers in the event legacy + NSW containers.
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nMDTHits
MuonVal::VectorBranch< float > & m_out_seed_x0
MuonVal::ScalarBranch< float > & m_out_bucketEtaHitGap
SG::ReadHandleKey< xAOD::MuonSegmentContainer > m_recoSegKey
Key to the xAOD::MuonSegment container.
MuonVal::VectorBranch< unsigned short > & m_out_segment_truthMatchedHits
MuonVal::VectorBranch< unsigned short > & m_out_seed_nTruePrecHits
SG::ReadHandleKeyArray< MuonR4::SegmentSeedContainer > m_patternSeedKeys
List of the two segment seed containers from which the segments are buiit (Complets the pattern findi...
std::vector< ObjectMatching > matchWithTruth(const ActsTrk::GeometryContext &gctx, const MuonR4::SegmentSeedContainer &seedContainer, const xAOD::MuonSegmentContainer &segmentContainer, const xAOD::MuonSegmentContainer *truthSegments) const
MuonVal::ScalarBranch< bool > & m_out_hasTruth
======= Truth block: Filled if we have a truth match. ============
MuonVal::VectorBranch< float > & m_out_seed_y0
MuonVal::ScalarBranch< unsigned char > & m_out_nPhiSpacePoints
Number of phi hits in the bucket.
MuonVal::VectorBranch< unsigned short > & m_out_seed_hasPhiExtension
MuonVal::MatrixBranch< unsigned char > & m_spMatchedToPattern
Branch indicating which space points in the tree are associated to the i-th pattern.
MuonVal::ScalarBranch< int > & m_out_gen_truthType
MuonVal::VectorBranch< unsigned short > & m_out_segment_nsTgcPadpHits
MuonVal::ScalarBranch< int > & m_out_gen_truthPdgId
MuonVal::VectorBranch< unsigned short > & m_out_segment_nsTgcWireHits
MuonVal::VectorBranch< unsigned short > & m_out_seed_nsTgcWire
MuonVal::ScalarBranch< int > & m_out_stationPhi
phi index of the station
MuonVal::VectorBranch< unsigned short > & m_out_segment_nsTgcStripHits
MuonVal::VectorBranch< unsigned short > & m_out_segment_nTruePrecHits
MuonVal::ScalarBranch< float > & m_out_bucketEnd
MuonVal::ScalarBranch< unsigned char > & m_out_nTrueSpacePoints
Number of all space points in the bucket.
MuonVal::VectorBranch< unsigned short > & m_out_seed_nsTgcStrip
MuonVal::VectorBranch< unsigned short > & m_out_seed_nEtaHits
void fillChamberInfo(const MuonGMR4::SpectrometerSector *chamber)
Fill the current chamber info into the output.
MuonVal::VectorBranch< unsigned short > & m_out_segment_nTgcPhiHits
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nRPCHits
MuonVal::VectorBranch< float > & m_out_segment_time
void fillBucketInfo(const MuonR4::SpacePointBucket &bucket)
Fill the hit summary info of the associated bucket.
MuonVal::ScalarBranch< short > & m_out_gen_Q
MuonVal::MatrixBranch< unsigned char > & m_spMatchedToSegment
Branch indicating which space points in the tree are associated to the i-th segment.
MuonVal::ScalarBranch< float > & m_out_gen_y0
Truth - segment parameters.
MuonVal::ScalarBranch< unsigned char > & m_out_nPrecSpacePoints
Number of precision hits in the bucket.
MuonVal::VectorBranch< bool > & m_out_segment_hasPhi
MuonVal::ScalarBranch< unsigned char > & m_out_nTruePrecSpacePoints
Number of precision hits in the bucket.
MuonVal::VectorBranch< float > & m_out_seed_tanphi
SG::ReadDecorHandleKeyArray< xAOD::MuonSegmentContainer > m_truthSegLinkKeys
Declare the dependencies on the decorations.
MuonVal::VectorBranch< float > & m_out_segment_tanphi
MuonVal::VectorBranch< float > & m_out_segment_err_tanphi
unsigned int countOnSameSide(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &truthSeg, const MuonR4::Segment &recoSeg) const
Calculates how many measurements from the segment fit have the same drift sign as when evaluated with...
MuonVal::ScalarBranch< float > & m_out_gen_tanphi
MuonVal::ScalarBranch< unsigned > & m_out_seed_n
========== Seed block: Filled when we have one or multiple seeds ============= seed count
MuonVal::VectorBranch< float > & m_out_segment_chi2
MuonVal::VectorBranch< unsigned short > & m_out_segment_nTrueHits
Labelled hits from the pattern visualization tool.
MuonVal::VectorBranch< unsigned short > & m_out_seed_nTruePhiHits
SG::ReadHandleKey< xAOD::MuonSegmentContainer > m_truthSegmentKey
Key to the truth segment.
MuonVal::VectorBranch< float > & m_out_segment_tantheta
MuonVal::ScalarBranch< float > & m_out_gen_Phi
MuonVal::VectorBranch< unsigned short > & m_out_seed_nMdt
MuonVal::VectorBranch< float > & m_out_seed_minYhit
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nSTGCHits
ActsTrk::GeoContextReadKey_t m_geoCtxKey
Tracking geometry context.
MuonVal::ScalarBranch< int > & m_out_gen_truthOrigin
MuonVal::VectorBranch< unsigned short > & m_out_seed_nMmEta
MuonVal::VectorBranch< unsigned short > & m_out_seed_nRpc
MuonVal::VectorBranch< unsigned short > & m_out_seed_nPrecHits
MuonVal::ScalarBranch< float > & m_out_gen_maxYhit
MuonVal::ScalarBranch< float > & m_out_gen_minYhit
MuonVal::VectorBranch< float > & m_out_segment_err_time
Gaudi::Property< std::vector< std::string > > m_truthLinks
Name of the decorations for the truth segment.
MuonVal::VectorBranch< float > & m_out_seed_tantheta
MuonVal::ScalarBranch< int > & m_out_chamberIndex
====== Common block: Filled for all entries ===========
MuonVal::ScalarBranch< unsigned char > & m_out_nSpacePoints
Number of all space points in the bucket.
MuonVal::VectorBranch< unsigned short > & m_out_segment_nTruePhiHits
Gaudi::Property< std::vector< std::string > > m_recoSegLinks
name of the truth link decorations for the reco segment container
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nNswHits
virtual StatusCode execute(const EventContext &ctx) override
Execute method.
MuonVal::VectorBranch< float > & m_out_segment_minYhit
void fillSeedInfo(const ObjectMatching &obj)
Fill the info associated to the seed.
MuonVal::VectorBranch< float > & m_out_segment_x0
MuonVal::VectorBranch< unsigned short > & m_out_seed_nsTgcPad
MuonVal::ScalarBranch< float > & m_out_gen_Eta
global particle properties
MuonVal::VectorBranch< bool > & m_out_segment_hasTimeFit
MuonVal::VectorBranch< unsigned short > & m_out_segment_nTgcEtaHits
MuonVal::VectorBranch< unsigned short > & m_out_segment_nMmEtaHits
MuonVal::VectorBranch< float > & m_out_segment_maxYhit
MuonVal::VectorBranch< unsigned short > & m_out_seed_nTrueHits
Labelled hits from the pattern visualization tool.
MuonVal::ScalarBranch< float > & m_out_bucketStart
MuonVal::VectorBranch< unsigned short > & m_out_segment_nMdtHits
MuonVal::VectorBranch< unsigned short > & m_out_seed_nPhiHits
MuonVal::VectorBranch< unsigned short > & m_out_segment_nTrueEtaHits
MuonVal::ScalarBranch< float > & m_out_gen_time
MuonVal::ScalarBranch< float > & m_out_gen_x0
MuonVal::VectorBranch< unsigned short > & m_out_segment_nRpcEtaHits
MuonVal::VectorBranch< float > & m_out_segment_err_x0
MuonVal::ScalarBranch< short > & m_out_stationSide
+1 for A-, -1 of C-side
MuonVal::VectorBranch< unsigned short > & m_out_seed_nMatchedHits
MuonVal::VectorBranch< uint16_t > & m_out_segment_nDoF
MuonVal::VectorBranch< uint16_t > & m_out_segment_fitIter
MuonVal::VectorBranch< float > & m_out_segment_y0
MuonVal::VectorBranch< unsigned short > & m_out_seed_nTgc
std::shared_ptr< SpacePointTesterModule > m_spTester
Branch dumping all the space points from the difference buckets.
MuonVal::ScalarBranch< float > & m_out_gen_tantheta
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nTGCHits
@ isMC
Flag determining whether the branch is simulation.
Helper class to provide constant type-safe access to aux data.
Property holding a SG store/key/clid from which a ReadHandle is made.
int channelType(const Identifier &id) const
float t0() const
int nTrigEtaLayers() const
Returns the number of trigger eta layers.
int nPrecisionHits() const
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
::Muon::MuonStationIndex::TechnologyIndex technology() const
Returns the main technology of the segment.
::Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index.
int nPhiLayers() const
Returns the number of phi layers.
int etaIndex() const
Returns the eta index, which corresponds to stationEta in the offline identifiers (and the ).
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
const xAOD::TruthParticle * getTruthMatchedParticle(const xAOD::MuonSegment &segment)
Returns the particle truth-matched to the segment.
double houghTanBeta(const Amg::Vector3D &v)
Returns the hough tanBeta [y] / [z].
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
const xAOD::MuonSegment * getMatchedTruthSegment(const xAOD::MuonSegment &segment)
Returns the truth-matched segment.
bool isPrecisionHit(const SpacePoint &hit)
Returns whether the uncalibrated spacepoint is a precision hit (Mdt, micromegas, stgc strips).
DataVector< SegmentSeed > SegmentSeedContainer
double houghTanAlpha(const Amg::Vector3D &v)
: Returns the hough tanAlpha [x] / [z]
const SpacePoint * HoughHitType
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
MuonHoughTransformTester::ObjectMatching ObjectMatching
TechnologyIndex
enum to classify the different layers in the muon spectrometer
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Dedicated namespace for the helper functions.
int getParticleTruthType(const xAOD::IParticle &p)
Return the particle's truth type (as defined by the MC Truth Classifier).
int getParticleTruthOrigin(const xAOD::IParticle &p)
Return the particle's truth origin (as defined by the MC Truth Classifier).
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12
TruthParticle_v1 TruthParticle
Typedef to implementation.
sTgcMeasurement_v1 sTgcMeasurement
MuonSegment_v1 MuonSegment
Reference the current persistent version:
const xAOD::MuonSegment * truthSegment
Truth segment for reference.
const MuonGMR4::SpectrometerSector * chamber
Associated chamber.
std::vector< const MuonR4::Segment * > matchedSegments
All segments matched to this object.
std::vector< const MuonR4::SegmentSeed * > matchedSeeds
All seeds matched to this object.