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 }
223
224 const EventContext & ctx = Gaudi::Hive::currentContext();
225
226 const ActsTrk::GeometryContext* gctxPtr{nullptr};
227 ATH_CHECK(SG::get(gctxPtr, m_geoCtxKey, ctx));
228 const ActsTrk::GeometryContext& gctx{*gctxPtr};
229
232 const SegmentSeedContainer* readSegmentSeeds{nullptr};
233 ATH_CHECK(SG::get(readSegmentSeeds, key, ctx));
234 segmentSeeds.insert(segmentSeeds.end(), readSegmentSeeds->begin(), readSegmentSeeds->end());
235 }
236
237 const xAOD::MuonSegmentContainer* truthSegments{nullptr};
238 ATH_CHECK(SG::get(truthSegments, m_truthSegmentKey, ctx));
239
240 const xAOD::MuonSegmentContainer* recoSegments{nullptr};
241 ATH_CHECK(SG::get(recoSegments, m_recoSegKey, ctx));
242
243 ATH_MSG_DEBUG("Succesfully retrieved input collections. Seeds: "<<segmentSeeds.size()
244 <<", segments: "<<recoSegments->size()
245 <<", truth segments: "<<(truthSegments? truthSegments->size() : -1)
246 <<".");
247 std::vector<ObjectMatching> objects = matchWithTruth(gctx, *segmentSeeds.asDataVector(),
248 *recoSegments, truthSegments);
249 for (const ObjectMatching& obj : objects) {
250 fillChamberInfo(obj.chamber);
251 fillSeedInfo(obj);
252 fillSegmentInfo(gctx, obj);
253 if(m_isMC) fillTruthInfo(gctx, obj.truthSegment);
254 ATH_CHECK(m_tree.fill(ctx));
255 }
256 return StatusCode::SUCCESS;
257 }
259 m_out_chamberIndex = Acts::toUnderlying(msSector->chamberIndex());
260 m_out_stationSide = msSector->side();
261 m_out_stationPhi = msSector->stationPhi();
262 }
264 const xAOD::MuonSegment* segment) {
265 if (!segment) {
266 return;
267 }
268 m_out_hasTruth = true;
269
270 const Amg::Vector3D segDir{segment->direction()};
271 static const SG::ConstAccessor<float> acc_pt{"pt"};
272 static const SG::ConstAccessor<float> acc_charge{"charge"};
273 // eta is interpreted as the eta-location
274 m_out_gen_Eta = segDir.eta();
275 m_out_gen_Phi = segDir.phi();
276 m_out_gen_Pt = acc_pt(*segment);
277 m_out_gen_Q = acc_charge(*segment);
278
279 const auto [chamberPos, chamberDir] = SegmentFit::makeLine(SegmentFit::localSegmentPars(*segment));
280 m_out_gen_nHits = segment->nPrecisionHits()+segment->nPhiLayers() + segment->nTrigEtaLayers();
281 using namespace Muon::MuonStationIndex;
284 m_out_gen_nTGCHits = (segment->nPhiLayers() + segment->nTrigEtaLayers()) * !isBarrel(segment->chamberIndex());
285 m_out_gen_nRPCHits = (segment->nPhiLayers() + segment->nTrigEtaLayers()) * isBarrel(segment->chamberIndex());
286
287 unsigned nMMHits{0}, nSTGHits{0};
288 for (const xAOD::MuonSimHit* simHit : getMatchingSimHits(*segment)) {
289 const TechnologyIndex simIdx = m_idHelperSvc->technologyIndex(simHit->identify());
290 nMMHits += simIdx == TechnologyIndex::MM;
291 nSTGHits += simIdx == TechnologyIndex::STGC;
292 }
293 m_out_gen_nMmHits = nMMHits;
294 m_out_gen_nSTGCHits = nSTGHits;
295
296 m_out_gen_tantheta = houghTanBeta(chamberDir);
297 m_out_gen_tanphi = houghTanAlpha(chamberDir);
298 m_out_gen_y0 = chamberPos.y();
299 m_out_gen_x0 = chamberPos.x();
300 m_out_gen_time = segment->t0();
301
302 double minYhit = std::numeric_limits<double>::max();
303 double maxYhit = -1 * std::numeric_limits<double>::max();
304 for (const xAOD::MuonSimHit* hit : getMatchingSimHits(*segment)){
305 const Identifier hitId = hit->identify();
306 const MuonGMR4::MuonReadoutElement* RE = m_detMgr->getReadoutElement(hitId);
307 const IdentifierHash hash{m_idHelperSvc->isMdt(hitId) ? RE->measurementHash(hitId)
308 : RE->layerHash(hitId) };
309 const Amg::Transform3D localToChamber = RE->msSector()->globalToLocalTransform(gctx) * RE->localToGlobalTransform(gctx, hash);
310 const Amg::Vector3D chamberPos = localToChamber * xAOD::toEigen(hit->localPosition());
311 minYhit = std::min(chamberPos.y(), minYhit);
312 maxYhit = std::max(chamberPos.y(), maxYhit);
313 }
314 m_out_gen_minYhit = minYhit;
315 m_out_gen_maxYhit = maxYhit;
316
317 ATH_MSG_DEBUG("A true max on chamber index "<<m_out_chamberIndex.getVariable()<<" side "<<m_out_stationSide.getVariable()<<" phi "<<m_out_stationPhi.getVariable()<<" with "
318 <<m_out_gen_nMDTHits.getVariable()<<" MDT and "<<m_out_gen_nRPCHits.getVariable()+m_out_gen_nTGCHits.getVariable()<< " trigger hits is at "
319 <<m_out_gen_tantheta.getVariable()<<" and "<<m_out_gen_y0.getVariable());
320
321 const xAOD::TruthParticle* truthMuon = getTruthMatchedParticle(*segment);
322 if (truthMuon) {
323 using namespace xAOD::TruthHelpers;
326 }
327 }
329 m_out_bucketEnd = bucket.coveredMax();
330 m_out_bucketStart = bucket.coveredMin();
331 m_out_nSpacePoints = bucket.size();
332 m_out_nPrecSpacePoints = std::ranges::count_if(bucket, [](const SpacePointBucket::value_type& sp){
333 return isPrecisionHit(*sp);
334 });
335 m_out_nPhiSpacePoints = std::ranges::count_if(bucket, [](const SpacePointBucket::value_type& sp){
336 return sp->measuresPhi();
337 });
338 if (!m_visionTool.isEnabled()){
339 return;
340 }
341 m_out_nTrueSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
342 return m_visionTool->isLabeled(*sp);
343 });
344 m_out_nTruePrecSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
345 return isPrecisionHit(*sp) && m_visionTool->isLabeled(*sp);
346 });
347 m_out_nTruePhiSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
348 return sp->measuresPhi() && m_visionTool->isLabeled(*sp);
349 });
350 }
352
353 m_out_seed_n = obj.matchedSeeds.size();
354 for (const auto [iseed, seed] : Acts::enumerate(obj.matchedSeeds)){
355 if (iseed ==0) {
356 fillBucketInfo(*seed->parentBucket());
357 }
358 double minYhit = m_out_bucketEnd.getVariable();
359 double maxYhit = m_out_bucketStart.getVariable();
360 for (const SpacePoint* hit : seed->getHitsInMax()){
361 minYhit = std::min(hit->localPosition().y(),minYhit);
362 maxYhit = std::max(hit->localPosition().y(),maxYhit);
363 }
364 m_out_seed_minYhit.push_back(minYhit);
365 m_out_seed_maxYhit.push_back(maxYhit);
366
367 m_out_seed_hasPhiExtension.push_back(seed->hasPhiExtension());
368 m_out_seed_nMatchedHits.push_back(countMatched(obj.truthSegment, *seed));
369 m_out_seed_y0.push_back(seed->interceptY());
370 m_out_seed_tantheta.push_back(seed->tanBeta());
371 if (seed->hasPhiExtension()){
372 m_out_seed_x0.push_back(seed->interceptX());
373 m_out_seed_tanphi.push_back(seed->tanAlpha());
374 } else{
375 m_out_seed_x0.push_back(-999);
376 m_out_seed_tanphi.push_back(-999);
377 }
378
379 m_out_seed_nHits.push_back(seed->getHitsInMax().size());
380 unsigned nMdtSeed{0}, nRpcSeed{0}, nTgcSeed{0}, nMmEtaSeed{0}, nMmStereoSeed{0},
381 nsTgcStripSeed{0}, nsTgcWireSeed{0}, nsTgcPadSeed{0};
382 unsigned nPrecHits{0}, nEtaHits{0}, nPhiHits{0}, nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
383 std::vector<unsigned char> treeIdxs{};
384
385 for (const HoughHitType & houghSP: seed->getHitsInMax()){
387 unsigned treeIdx = m_spTester->push_back(*houghSP);
388 treeIdxs.push_back(treeIdx);
389 }
390 nPrecHits += isPrecisionHit(*houghSP);
391 nPhiHits += houghSP->measuresPhi();
392 nEtaHits += houghSP->measuresEta();
393
394 if (m_visionTool.isEnabled()) {
395 nTrueHits += m_visionTool->isLabeled(*houghSP);
396 nTruePrecHits += m_visionTool->isLabeled(*houghSP) && isPrecisionHit(*houghSP);
397 nTruePhiHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresPhi();
398 nTrueEtaHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresEta();
399 }
400 switch (houghSP->type()) {
402 ++nMdtSeed;
403 break;
405 nRpcSeed+=houghSP->measuresEta();
406 nRpcSeed+=houghSP->measuresPhi();
407 break;
409 nTgcSeed+=houghSP->measuresEta();
410 nTgcSeed+=houghSP->measuresPhi();
411 break;
413 const Identifier sTgc = houghSP->primaryMeasurement()->identify();
414 const Identifier sTgc2 = houghSP->secondaryMeasurement() ?
415 houghSP->secondaryMeasurement()->identify() : Identifier{};
416 const sTgcIdHelper& idHelper{m_idHelperSvc->stgcIdHelper()};
417 const int primType = idHelper.channelType(sTgc);
418 const int secType = idHelper.channelType(sTgc2);
419 nsTgcStripSeed += primType == sTgcIdHelper::sTgcChannelTypes::Strip;
420 nsTgcWireSeed += primType == sTgcIdHelper::sTgcChannelTypes::Wire;
421 nsTgcPadSeed += primType == sTgcIdHelper::sTgcChannelTypes::Pad;
422
423 nsTgcWireSeed += secType == sTgcIdHelper::sTgcChannelTypes::Wire;
424 nsTgcPadSeed += primType != sTgcIdHelper::sTgcChannelTypes::Pad &&
426 break;
428 if (m_idHelperSvc->mmIdHelper().isStereo(houghSP->identify())) {
429 ++nMmEtaSeed;
430 } else {
431 ++nMmStereoSeed;
432 }
433 break;
434 }default:
435 ATH_MSG_WARNING("Technology "<<houghSP->identify() <<" not yet implemented");
436 }
437 }
438 m_out_seed_nMdt.push_back(nMdtSeed);
439 m_out_seed_nRpc.push_back(nRpcSeed);
440 m_out_seed_nTgc.push_back(nTgcSeed);
441
442 m_out_seed_nMmEta.push_back(nMmEtaSeed);
443 m_out_seed_nMmStereo.push_back(nMmStereoSeed);
444
445 m_out_seed_nsTgcStrip.push_back(nsTgcStripSeed);
446 m_out_seed_nsTgcWire.push_back(nsTgcWireSeed);
447 m_out_seed_nsTgcPad.push_back(nsTgcPadSeed);
448
449 m_out_seed_nPrecHits.push_back(nPrecHits);
450 m_out_seed_nEtaHits.push_back(nEtaHits);
451 m_out_seed_nPhiHits.push_back(nPhiHits);
452
453 m_out_seed_nTrueHits.push_back(nTrueHits);
454 m_out_seed_nTruePrecHits.push_back(nTruePrecHits);
455 m_out_seed_nTrueEtaHits.push_back(nTrueEtaHits);
456 m_out_seed_nTruePhiHits.push_back(nTruePhiHits);
457
458 m_out_seed_ledToSegment.push_back(obj.matchedSeedFoundSegment.at(iseed));
459 if (m_writeSpacePoints) {
460 m_spMatchedToPattern[iseed] = std::move(treeIdxs);
461
462 }
463 }
464 }
465
467 const ObjectMatching& obj){
468 using namespace SegmentFit;
469
470 m_out_segment_n = obj.matchedSegments.size();
471 for (const Segment* segment : obj.matchedSegments) {
472 m_out_segment_hasPhi.push_back(std::ranges::any_of(segment->measurements(),
473 [](const auto& meas){ return meas->measuresPhi();}));
474 m_out_segment_fitIter.push_back(segment->nFitIterations());
475 m_out_segment_truthMatchedHits.push_back(countMatched(obj.truthSegment, *segment));
476 m_out_segment_chi2.push_back(segment->chi2());
477 m_out_segment_nDoF.push_back(segment->nDoF());
478 m_out_segment_hasTimeFit.push_back(segment->hasTimeFit());
479
480 m_out_segment_err_x0.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::x0), Acts::toUnderlying(ParamDefs::x0)));
481 m_out_segment_err_y0.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::y0), Acts::toUnderlying(ParamDefs::y0)));
482 m_out_segment_err_tantheta.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::theta), Acts::toUnderlying(ParamDefs::theta)));
483 m_out_segment_err_tanphi.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::phi), Acts::toUnderlying(ParamDefs::phi)));
484 m_out_segment_err_time.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::t0), Acts::toUnderlying(ParamDefs::t0)));
485 const auto [locPos, locDir] = makeLine(localSegmentPars(gctx, *segment));
486 m_out_segment_tanphi.push_back(houghTanAlpha(locDir));
487 m_out_segment_tantheta.push_back(houghTanBeta(locDir));
488 m_out_segment_y0.push_back(locPos.y());
489 m_out_segment_x0.push_back(locPos.x());
490 m_out_segment_time.push_back(segment->segementT0() + segment->position().mag() * c_inv);
491
492 unsigned nMdtHits{0}, nRpcEtaHits{0}, nRpcPhiHits{0}, nTgcEtaHits{0}, nTgcPhiHits{0},
493 nMmEtaHits{0}, nMmStereoHits{0}, nStgcStripHits{0},nStgcWireHits{0}, nStgcPadHits{0};
494 unsigned nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
495
496 double minYhit = std::numeric_limits<double>::max();
497 double maxYhit = -1 * std::numeric_limits<double>::max();
498
499 std::vector<unsigned char> matched;
500 for (const auto & meas : segment->measurements()){
501 // skip dummy measurement from beam spot constraint
502 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Dump "<<(*meas));
503 if (meas->type() == xAOD::UncalibMeasType::Other) {
504 continue;
505 }
506 minYhit = std::min(meas->localPosition().y(),minYhit);
507 maxYhit = std::max(meas->localPosition().y(),maxYhit);
508 if (m_writeSpacePoints) {
509 unsigned treeIdx = m_spTester->push_back(*meas->spacePoint());
510 if (treeIdx >= matched.size()){
511 matched.resize(treeIdx +1);
512 }
513 matched[treeIdx] = true;
514 }
515 if (m_visionTool.isEnabled()) {
516 nTrueHits += m_visionTool->isLabeled(*meas->spacePoint());
517 nTruePrecHits += isPrecisionHit(*meas) && m_visionTool->isLabeled(*meas->spacePoint());
518 nTrueEtaHits += meas->measuresEta() && m_visionTool->isLabeled(*meas->spacePoint());
519 nTruePhiHits += meas->measuresPhi() && m_visionTool->isLabeled(*meas->spacePoint());
520 }
521 switch (meas->type()) {
523 ++nMdtHits;
524 break;
526 nRpcEtaHits += meas->measuresEta();
527 nRpcPhiHits += meas->measuresPhi();
528 break;
530 nTgcEtaHits += meas->measuresEta();
531 nTgcPhiHits += meas->measuresPhi();
532 break;
534 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
535 nMmEtaHits += !idHelper.isStereo(meas->spacePoint()->identify());
536 nMmStereoHits += !idHelper.isStereo(meas->spacePoint()->identify());
537 break;
539 const auto* prd = static_cast<const xAOD::sTgcMeasurement*>(meas->spacePoint()->primaryMeasurement());
540 const int primType = prd->channelType();
541 prd = dynamic_cast<const xAOD::sTgcMeasurement*>(meas->spacePoint()->secondaryMeasurement());
542 const int secType = (prd != nullptr ? prd->channelType() : -1);
543 nStgcStripHits += primType == sTgcIdHelper::sTgcChannelTypes::Strip;
544 nStgcWireHits += primType == sTgcIdHelper::sTgcChannelTypes::Wire;
545 nStgcPadHits += primType == sTgcIdHelper::sTgcChannelTypes::Pad;
546 nStgcWireHits += secType == sTgcIdHelper::sTgcChannelTypes::Wire;
547 nStgcPadHits += primType != secType && secType == sTgcIdHelper::sTgcChannelTypes::Pad;
548 break;
549 } default:
550 break;
551 }
552 }
553 m_out_segment_nMdtHits.push_back(nMdtHits);
554 m_out_segment_nRpcEtaHits.push_back(nRpcEtaHits);
555 m_out_segment_nRpcPhiHits.push_back(nRpcPhiHits);
556 m_out_segment_nTgcEtaHits.push_back(nTgcEtaHits);
557 m_out_segment_nTgcPhiHits.push_back(nTgcPhiHits);
558
559 m_out_segment_nMmEtaHits.push_back(nMmEtaHits);
560 m_out_segment_nMmStereoHits.push_back(nMmStereoHits);
561 m_out_segment_nsTgcStripHits.push_back(nStgcStripHits);
562 m_out_segment_nsTgcWireHits.push_back(nStgcWireHits);
563 m_out_segment_nsTgcPadpHits.push_back(nStgcPadHits);
564
565
566 m_out_segment_nTrueHits.push_back(nTrueHits);
567 m_out_segment_nTruePrecHits.push_back(nTruePrecHits);
568 m_out_segment_nTruePhiHits.push_back(nTruePhiHits);
569 m_out_segment_nTrueEtaHits.push_back(nTrueEtaHits);
570
571 m_out_segment_minYhit.push_back(minYhit);
572 m_out_segment_maxYhit.push_back(maxYhit);
573 if (m_writeSpacePoints) {
574 m_spMatchedToSegment.push_back(std::move(matched));
575 }
576 }
577 }
578} // 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
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 Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the local coordinate system of the readout element into the global AT...
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...
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
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
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::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
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
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
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
Tracking geometry context.
@ 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.