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"
14#include "Acts/Utilities/Enumerate.hpp"
15#include "GaudiKernel/PhysicalConstants.h"
16
18
19
20namespace {
21 constexpr double c_inv = 1. /Gaudi::Units::c_light;
22}
23
24
25namespace MuonValR4 {
26 using namespace MuonR4;
27 using namespace MuonVal;
29 using simHitSet = std::unordered_set<const xAOD::MuonSimHit*>;
30 unsigned int countMatched(const simHitSet& truthHits,
31 const simHitSet& recoHits) {
32 unsigned int matched{0};
33 for (const xAOD::MuonSimHit* reco : recoHits) {
34 matched += truthHits.count(reco);
35 }
36 return matched;
37 }
38 unsigned int countMatched(const xAOD::MuonSegment* truthSeg,
39 const MuonR4::SegmentSeed* seed) {
40 return truthSeg ? countMatched(getMatchingSimHits(*truthSeg), getMatchingSimHits(*seed)) : 0;
41 }
42 unsigned int countMatched(const xAOD::MuonSegment* truthSeg,
43 const MuonR4::Segment* segment) {
44 return truthSeg ? countMatched(getMatchingSimHits(*truthSeg), getMatchingSimHits(*segment)) : 0;
45 }
46
47 template <class SpType>
48 bool isPrecHit(const SpType& sp) {
51 (sp.type() == xAOD::UncalibMeasType::sTgcStripType && sp.measuresEta());
52 }
53
55 ATH_CHECK(m_geoCtxKey.initialize());
56
57 {
58 int infoOpts = 0;
59 if (m_isMC) infoOpts = EventInfoBranch::isMC;
60 m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, infoOpts));
61 }
62
63 ATH_CHECK(m_truthSegmentKey.initialize(!m_truthSegmentKey.empty()));
65 ATH_CHECK(m_inSegmentKeys.initialize());
69 m_spTester = std::make_unique<SpacePointTesterModule>(m_tree, m_spKey.key(), msgLevel());
70 m_tree.addBranch(m_spTester);
71 } else {
72 m_tree.disableBranch(m_spMatchedToPattern.name());
73 m_tree.disableBranch(m_spMatchedToSegment.name());
74 }
75 ATH_CHECK(m_tree.init(this));
76 ATH_CHECK(m_idHelperSvc.retrieve());
77 ATH_CHECK(detStore()->retrieve(m_detMgr));
78
79 ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
80 ATH_MSG_DEBUG("Succesfully initialised");
81 return StatusCode::SUCCESS;
82 }
83
84
86 const xAOD::MuonSegment& truthSeg,
87 const MuonR4::Segment& recoSeg) const{
88 unsigned int same{0};
89 using namespace SegmentFit;
90 const auto[truePos, trueDir] = makeLine(localSegmentPars(truthSeg));
91 const auto[recoPos, recoDir] = makeLine(localSegmentPars(gctx, recoSeg));
92 const std::vector<int> truthSigns = SeedingAux::strawSigns(truePos, trueDir, recoSeg.measurements());
93 const std::vector<int> recoSigns = SeedingAux::strawSigns(recoPos, recoDir, recoSeg.measurements());
94 for (unsigned int s = 0 ; s < truthSigns.size(); ++s) {
95 same += (truthSigns[s] != 0) && truthSigns[s] == recoSigns[s];
96 }
97 return same;
98 }
99 std::vector<ObjectMatching>
101 const xAOD::MuonSegmentContainer* truthSegments,
102 const SegmentSeedContainer* seedContainer,
103 const SegmentContainer* segmentContainer) const {
104 std::vector<ObjectMatching> allAssociations{};
105 std::unordered_set<const SegmentSeed*> usedSeeds{};
106 std::unordered_set<const Segment*> usedSegs{};
107
110 if (m_isMC) {
111 // collect the sim hits that contributed to our segments and seeds.
112 std::vector<simHitSet> truthHitsVec{}, seedSimHitVec{}, segmentSimHitVec{};
113 for (const SegmentSeed* seed: *seedContainer) {
114 seedSimHitVec.emplace_back(getMatchingSimHits(*seed));
115 }
116 for (const Segment* segment: *segmentContainer){
117 segmentSimHitVec.emplace_back(getMatchingSimHits(*segment));
118 }
119
120 // Now look at the truth segments, collecting their sim hits.
121 // Compare these to the sim hits on our reco objects
122 for (const xAOD::MuonSegment* truth: *truthSegments) {
123 const simHitSet& truthHits{truthHitsVec.emplace_back(getMatchingSimHits(*truth))};
124 ObjectMatching & matchedWithTruth = allAssociations.emplace_back();
125 matchedWithTruth.truthSegment = truth;
126 matchedWithTruth.chamber = m_detMgr->getSectorEnvelope((*truthHits.begin())->identify());
127
128 std::vector<std::pair<const SegmentSeed*, unsigned>> matchedSeeds{};
129
130 // Find seeds sharing at least one simHit with our truth segment
131 // can't wait for views::enumerate
132 int seedIdx{-1};
133 for (const SegmentSeed* seed : *seedContainer) {
134 ++seedIdx;
135 if (seed->msSector() != matchedWithTruth.chamber) {
136 continue;
137 }
138 const simHitSet& seedHits{seedSimHitVec[seedIdx]};
139 unsigned int matchedHits = countMatched(truthHits, seedHits);
140 if (!matchedHits) {
141 continue;
142 }
143 matchedSeeds.emplace_back(std::make_pair(seed, matchedHits));
144 }
145 // Find segments sharing at least one simHit with our truth segment
146 std::vector<std::pair<const Segment*, unsigned>> matchedSegs{};
147 int segmentIdx{-1};
148 for (const Segment* segment : *segmentContainer) {
149 ++segmentIdx;
150 if (segment->msSector() != matchedWithTruth.chamber) {
151 continue;
152 }
153 const simHitSet& segmentHits{segmentSimHitVec[segmentIdx]};
154 unsigned int matchedHits = countMatched(truthHits, segmentHits);
155 if (!matchedHits) {
156 continue;
157 }
158 matchedSegs.emplace_back(std::make_pair(segment,matchedHits));
159 }
160
161 // sort by quality of match
162
163 // for segments (by hit count and same-side hits)
164 std::ranges::sort(matchedSegs,
165 [this, &truth, &gctx](const std::pair<const Segment*, unsigned>& segA,
166 const std::pair<const Segment*, unsigned>& segB){
167 if (segA.second != segB.second) return segA.second > segB.second;
168 return countOnSameSide(gctx, *truth, *segA.first) > countOnSameSide(gctx, *truth, *segB.first);
169 });
170 // and for seeds (by raw hit count)
171 std::ranges::sort(matchedSeeds, [](const std::pair<const SegmentSeed*, unsigned>& seedA,
172 const std::pair<const SegmentSeed*, unsigned>& seedB) {
173 return seedA.second > seedB.second;
174 });
175
176
177 // now we can populate our association object
178
179 // first, we handle the segments and any seeds connected with them
180 for (const auto& [matched, nMatchedHits] : matchedSegs) {
181 // add segment to the list of all segments
182 matchedWithTruth.matchedSegments.push_back(matched);
183 // and update our book-keeping to record that this segment and its seed have already been written
184 usedSeeds.insert(matched->parent());
185 usedSegs.insert(matched);
186 }
187
188 // now, we add the seeds
189 for (const auto& [seed , nHits] : matchedSeeds) {
190 // add seed to the list of all seeds
191 ATH_MSG_VERBOSE("Seed with "<<nHits);
192 matchedWithTruth.matchedSeeds.push_back(seed);
193 matchedWithTruth.matchedSeedFoundSegment.push_back(usedSeeds.count(seed));
194 usedSeeds.insert(seed);
195 }
196 } // end of loop over truth segments
197 }
198
202
203 // start with segments, and also collect "their" seeds in a common entry
204 for (const Segment* seg: *segmentContainer) {
205 // skip segments that were previously seen and written in the truth loop
206 if (usedSegs.count(seg)) {
207 continue;
208 }
209 ObjectMatching & match = allAssociations.emplace_back();
210 match.chamber = seg->msSector();
211 match.matchedSegments = {seg};
212 match.matchedSeeds = {seg->parent()};
213 // this seed has been written as well - do not write it in the following loop
214 usedSeeds.insert(seg->parent());
215 match.matchedSeedFoundSegment.push_back(1);
216 }
217 for (const SegmentSeed* seed: *seedContainer) {
218 // skip seeds that are on segments or seen in the truth loop so these will be seeds without segment
219 if (usedSeeds.count(seed)) {
220 continue;
221 }
222 ObjectMatching & match = allAssociations.emplace_back();
223 match.chamber = seed->msSector();
224 match.matchedSeeds = {seed};
225 match.matchedSeedFoundSegment.push_back(0);
226 }
227 return allAssociations;
228 }
229
231 ATH_CHECK(m_tree.write());
232 return StatusCode::SUCCESS;
233 }
235
236 const EventContext & ctx = Gaudi::Hive::currentContext();
237 const ActsTrk::GeometryContext* gctxPtr{nullptr};
238 ATH_CHECK(SG::get(gctxPtr, m_geoCtxKey, ctx));
239 const ActsTrk::GeometryContext& gctx{*gctxPtr};
240
241
244
246 const SegmentSeedContainer* readSegmentSeeds{nullptr};
247 ATH_CHECK(SG::get(readSegmentSeeds, key, ctx));
248 segmentSeeds.insert(segmentSeeds.end(),readSegmentSeeds->begin(), readSegmentSeeds->end());
249 }
251 const SegmentContainer* readSegments{nullptr};
252 ATH_CHECK(SG::get(readSegments, key, ctx));
253 segments.insert(segments.end(),readSegments->begin(), readSegments->end());
254 }
255 const xAOD::MuonSegmentContainer* readTruthSegments{nullptr};
256
257 if(m_isMC){
258 ATH_CHECK(SG::get(readTruthSegments , m_truthSegmentKey, ctx));
259 }
260
261 ATH_MSG_DEBUG("Succesfully retrieved input collections. Seeds: "<<segmentSeeds.size()
262 <<", segments: "<<segments.size() <<", truth segments: "<<(readTruthSegments? readTruthSegments->size() : -1)<<".");
263 std::vector<ObjectMatching> objects = matchWithTruth(gctx, readTruthSegments, segmentSeeds.asDataVector(),
264 segments.asDataVector());
265 for (const ObjectMatching& obj : objects) {
266 fillChamberInfo(obj.chamber);
267 fillSeedInfo(obj);
268 fillSegmentInfo(gctx, obj);
269 if(m_isMC) fillTruthInfo(gctx, obj.truthSegment);
270 ATH_CHECK(m_tree.fill(ctx));
271 }
272 return StatusCode::SUCCESS;
273 }
275 m_out_chamberIndex = Acts::toUnderlying(msSector->chamberIndex());
276 m_out_stationSide = msSector->side();
277 m_out_stationPhi = msSector->stationPhi();
278 }
280 const xAOD::MuonSegment* segment) {
281 if (!segment) return;
282 m_out_hasTruth = true;
283
284 const Amg::Vector3D segDir{segment->direction()};
285 static const SG::Accessor<float> acc_pt{"pt"};
286 static const SG::Accessor<float> acc_charge{"charge"};
287 // eta is interpreted as the eta-location
288 m_out_gen_Eta = segDir.eta();
289 m_out_gen_Phi = segDir.phi();
290 m_out_gen_Pt = acc_pt(*segment);
291 m_out_gen_Q = acc_charge(*segment);
292
293 const auto [chamberPos, chamberDir] = SegmentFit::makeLine(SegmentFit::localSegmentPars(*segment));
294 m_out_gen_nHits = segment->nPrecisionHits()+segment->nPhiLayers() + segment->nTrigEtaLayers();
295 using namespace Muon::MuonStationIndex;
298 m_out_gen_nTGCHits = (segment->nPhiLayers() + segment->nTrigEtaLayers()) * !isBarrel(segment->chamberIndex());
299 m_out_gen_nRPCHits = (segment->nPhiLayers() + segment->nTrigEtaLayers()) * isBarrel(segment->chamberIndex());
300
301 m_out_gen_tantheta = houghTanBeta(chamberDir);
302 m_out_gen_tanphi = houghTanAlpha(chamberDir);
303 m_out_gen_y0 = chamberPos.y();
304 m_out_gen_x0 = chamberPos.x();
305 m_out_gen_time = segment->t0();
306
307 double minYhit = std::numeric_limits<double>::max();
308 double maxYhit = -1 * std::numeric_limits<double>::max();
309 for (const xAOD::MuonSimHit* hit : getMatchingSimHits(*segment)){
310 const Identifier hitId = hit->identify();
311 const MuonGMR4::MuonReadoutElement* RE = m_detMgr->getReadoutElement(hitId);
312 const IdentifierHash hash{m_idHelperSvc->isMdt(hitId) ? RE->measurementHash(hitId)
313 : RE->layerHash(hitId) };
314 const Amg::Transform3D localToChamber = RE->msSector()->globalToLocalTrans(gctx) * RE->localToGlobalTrans(gctx, hash);
315 const Amg::Vector3D chamberPos = localToChamber * xAOD::toEigen(hit->localPosition());
316 minYhit = std::min(chamberPos.y(), minYhit);
317 maxYhit = std::max(chamberPos.y(), maxYhit);
318 }
319 m_out_gen_minYhit = minYhit;
320 m_out_gen_maxYhit = maxYhit;
321
322 ATH_MSG_DEBUG("A true max on chamber index "<<m_out_chamberIndex.getVariable()<<" side "<<m_out_stationSide.getVariable()<<" phi "<<m_out_stationPhi.getVariable()<<" with "
323 <<m_out_gen_nMDTHits.getVariable()<<" MDT and "<<m_out_gen_nRPCHits.getVariable()+m_out_gen_nTGCHits.getVariable()<< " trigger hits is at "
324 <<m_out_gen_tantheta.getVariable()<<" and "<<m_out_gen_y0.getVariable());
325 }
327 m_out_bucketEnd = bucket.coveredMax();
328 m_out_bucketStart = bucket.coveredMin();
329 m_out_nSpacePoints = bucket.size();
330 m_out_nPrecSpacePoints = std::ranges::count_if(bucket, [](const SpacePointBucket::value_type& sp){
331 return isPrecHit(*sp);
332 });
333 m_out_nPhiSpacePoints = std::ranges::count_if(bucket, [](const SpacePointBucket::value_type& sp){
334 return sp->measuresPhi();
335 });
336 if (!m_visionTool.isEnabled()){
337 return;
338 }
339 m_out_nTrueSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
340 return m_visionTool->isLabeled(*sp);
341 });
342 m_out_nTruePrecSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
343 return isPrecHit(*sp) && m_visionTool->isLabeled(*sp);
344 });
345 m_out_nTruePhiSpacePoints = std::ranges::count_if(bucket,[this](const SpacePointBucket::value_type& sp){
346 return sp->measuresPhi() && m_visionTool->isLabeled(*sp);
347 });
348 }
350
351 m_out_seed_n = obj.matchedSeeds.size();
352 for (const auto [iseed, seed] : Acts::enumerate(obj.matchedSeeds)){
353 if (iseed ==0) {
354 fillBucketInfo(*seed->parentBucket());
355 }
356 double minYhit = m_out_bucketEnd.getVariable();
357 double maxYhit = m_out_bucketStart.getVariable();
358 for (const SpacePoint* hit : seed->getHitsInMax()){
359 minYhit = std::min(hit->localPosition().y(),minYhit);
360 maxYhit = std::max(hit->localPosition().y(),maxYhit);
361 }
362 m_out_seed_minYhit.push_back(minYhit);
363 m_out_seed_maxYhit.push_back(maxYhit);
364
365 m_out_seed_hasPhiExtension.push_back(seed->hasPhiExtension());
366 m_out_seed_nMatchedHits.push_back(countMatched(obj.truthSegment, seed));
367 m_out_seed_y0.push_back(seed->interceptY());
368 m_out_seed_tantheta.push_back(seed->tanBeta());
369 if (seed->hasPhiExtension()){
370 m_out_seed_x0.push_back(seed->interceptX());
371 m_out_seed_tanphi.push_back(seed->tanAlpha());
372 } else{
373 m_out_seed_x0.push_back(-999);
374 m_out_seed_tanphi.push_back(-999);
375 }
376
377 m_out_seed_nHits.push_back(seed->getHitsInMax().size());
378 unsigned nMdtSeed{0}, nRpcSeed{0}, nTgcSeed{0}, nMmSeed{0}, nsTgcSeed{0};
379 unsigned nPrecHits{0}, nEtaHits{0}, nPhiHits{0}, nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
380 std::vector<unsigned char> treeIdxs{};
381
382 for (const HoughHitType & houghSP: seed->getHitsInMax()){
384 unsigned treeIdx = m_spTester->push_back(*houghSP);
385 treeIdxs.push_back(treeIdx);
386 }
387 nPrecHits += isPrecHit(*houghSP);
388 nPhiHits += houghSP->measuresPhi();
389 nEtaHits += houghSP->measuresEta();
390
391 if (m_visionTool.isEnabled()) {
392 nTrueHits += m_visionTool->isLabeled(*houghSP);
393 nTruePrecHits += m_visionTool->isLabeled(*houghSP) && isPrecHit(*houghSP);
394 nTruePhiHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresPhi();
395 nTrueEtaHits += m_visionTool->isLabeled(*houghSP) && houghSP->measuresEta();
396 }
397 switch (houghSP->type()) {
399 ++nMdtSeed;
400 break;
402 nRpcSeed+=houghSP->measuresEta();
403 nRpcSeed+=houghSP->measuresPhi();
404 break;
406 nTgcSeed+=houghSP->measuresEta();
407 nTgcSeed+=houghSP->measuresPhi();
408 break;
410 nsTgcSeed += houghSP->measuresEta();
411 nsTgcSeed += houghSP->measuresPhi();
412 break;
414 ++nMmSeed;
415 break;
416 default:
417 ATH_MSG_WARNING("Technology "<<houghSP->identify() <<" not yet implemented");
418 }
419 }
420 m_out_seed_nMdt.push_back(nMdtSeed);
421 m_out_seed_nRpc.push_back(nRpcSeed);
422 m_out_seed_nTgc.push_back(nTgcSeed);
423 m_out_seed_nsTgc.push_back(nsTgcSeed);
424 m_out_seed_nMm.push_back(nMmSeed);
425
426 m_out_seed_nPrecHits.push_back(nPrecHits);
427 m_out_seed_nEtaHits.push_back(nEtaHits);
428 m_out_seed_nPhiHits.push_back(nPhiHits);
429
430 m_out_seed_nTrueHits.push_back(nTrueHits);
431 m_out_seed_nTruePrecHits.push_back(nTruePrecHits);
432 m_out_seed_nTrueEtaHits.push_back(nTrueEtaHits);
433 m_out_seed_nTruePhiHits.push_back(nTruePhiHits);
434
435 m_out_seed_ledToSegment.push_back(obj.matchedSeedFoundSegment.at(iseed));
436 if (m_writeSpacePoints) {
437 m_spMatchedToPattern[iseed] = std::move(treeIdxs);
438
439 }
440 }
441 }
442
444 const ObjectMatching& obj){
445 using namespace SegmentFit;
446
447 m_out_segment_n = obj.matchedSegments.size();
448 for (auto & segment : obj.matchedSegments){
449 m_out_segment_hasPhi.push_back(std::ranges::find_if(segment->measurements(), [](const auto& meas){ return meas->measuresPhi();})
450 !=segment->measurements().end());
451 m_out_segment_fitIter.push_back(segment->nFitIterations());
452 m_out_segment_truthMatchedHits.push_back(countMatched(obj.truthSegment, segment));
453 m_out_segment_chi2.push_back(segment->chi2());
454 m_out_segment_nDoF.push_back(segment->nDoF());
455 m_out_segment_hasTimeFit.push_back(segment->hasTimeFit());
456
457 m_out_segment_err_x0.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::x0), Acts::toUnderlying(ParamDefs::x0)));
458 m_out_segment_err_y0.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::y0), Acts::toUnderlying(ParamDefs::y0)));
459 m_out_segment_err_tantheta.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::theta), Acts::toUnderlying(ParamDefs::theta)));
460 m_out_segment_err_tanphi.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::phi), Acts::toUnderlying(ParamDefs::phi)));
461 m_out_segment_err_time.push_back(segment->covariance()(Acts::toUnderlying(ParamDefs::t0), Acts::toUnderlying(ParamDefs::t0)));
462 const auto [locPos, locDir] = makeLine(localSegmentPars(gctx, *segment));
463 m_out_segment_tanphi.push_back(houghTanAlpha(locDir));
464 m_out_segment_tantheta.push_back(houghTanBeta(locDir));
465 m_out_segment_y0.push_back(locPos.y());
466 m_out_segment_x0.push_back(locPos.x());
467 m_out_segment_time.push_back(segment->segementT0() + segment->position().mag() * c_inv);
468
469 unsigned nMdtHits{0}, nRpcEtaHits{0}, nRpcPhiHits{0}, nTgcEtaHits{0}, nTgcPhiHits{0},
470 nMmEtaHits{0}, nMmStereoHits{0}, nStgcStripHits{0},nStgcWireHits{0}, nStgcPadHits{0};
471 unsigned nTrueHits{0}, nTruePrecHits{0}, nTrueEtaHits{0}, nTruePhiHits{0};
472
473 double minYhit = std::numeric_limits<double>::max();
474 double maxYhit = -1 * std::numeric_limits<double>::max();
475
476 std::vector<unsigned char> matched;
477 for (const auto & meas : segment->measurements()){
478 // skip dummy measurement from beam spot constraint
479 if (meas->type() == xAOD::UncalibMeasType::Other) continue;
480 minYhit = std::min(meas->localPosition().y(),minYhit);
481 maxYhit = std::max(meas->localPosition().y(),maxYhit);
482 if (m_writeSpacePoints) {
483 unsigned treeIdx = m_spTester->push_back(*meas->spacePoint());
484 if (treeIdx >= matched.size()){
485 matched.resize(treeIdx +1);
486 }
487 matched[treeIdx] = true;
488 }
489 if (m_visionTool.isEnabled()) {
490 nTrueHits += m_visionTool->isLabeled(*meas->spacePoint());
491 nTruePrecHits += isPrecHit(*meas) && m_visionTool->isLabeled(*meas->spacePoint());
492 nTrueEtaHits += meas->measuresEta() && m_visionTool->isLabeled(*meas->spacePoint());
493 nTruePhiHits += meas->measuresPhi() && m_visionTool->isLabeled(*meas->spacePoint());
494 }
495 switch (meas->type()) {
497 ++nMdtHits;
498 break;
500 nRpcEtaHits += meas->measuresEta();
501 nRpcPhiHits += meas->measuresPhi();
502 break;
504 nTgcEtaHits += meas->measuresEta();
505 nTgcPhiHits += meas->measuresPhi();
506 break;
508 const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
509 nMmEtaHits += !idHelper.isStereo(meas->spacePoint()->identify());
510 nMmStereoHits += !idHelper.isStereo(meas->spacePoint()->identify());
511 break;
513 const auto* prd = static_cast<const xAOD::sTgcMeasurement*>(meas->spacePoint()->primaryMeasurement());
514 nStgcStripHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Strip;
515 nStgcWireHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire;
516 nStgcPadHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad;
517 prd = dynamic_cast<const xAOD::sTgcMeasurement*>(meas->spacePoint()->secondaryMeasurement());
518 if (prd) {
519 nStgcWireHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire;
520 nStgcPadHits += prd->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad;
521 }
522 break;
523 } default:
524 break;
525 }
526 }
527 m_out_segment_nMdtHits.push_back(nMdtHits);
528 m_out_segment_nRpcEtaHits.push_back(nRpcEtaHits);
529 m_out_segment_nRpcPhiHits.push_back(nRpcPhiHits);
530 m_out_segment_nTgcEtaHits.push_back(nTgcEtaHits);
531 m_out_segment_nTgcPhiHits.push_back(nTgcPhiHits);
532
533 m_out_segment_nMmEtaHits.push_back(nMmEtaHits);
534 m_out_segment_nMmStereoHits.push_back(nMmStereoHits);
535 m_out_segment_nsTgcStripHits.push_back(nStgcStripHits);
536 m_out_segment_nsTgcWireHits.push_back(nStgcWireHits);
537 m_out_segment_nsTgcPadpHits.push_back(nStgcPadHits);
538
539
540 m_out_segment_nTrueHits.push_back(nTrueHits);
541 m_out_segment_nTruePrecHits.push_back(nTruePrecHits);
542 m_out_segment_nTruePhiHits.push_back(nTruePhiHits);
543 m_out_segment_nTrueEtaHits.push_back(nTrueEtaHits);
544
545 m_out_segment_minYhit.push_back(minYhit);
546 m_out_segment_maxYhit.push_back(maxYhit);
547 if (m_writeSpacePoints) {
548 m_spMatchedToSegment.push_back(std::move(matched));
549 }
550 }
551 }
552} // 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 const uint32_t nHits
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
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
const SpectrometerSector * msSector() const
Returns the pointer to the envelope volume enclosing all chambers in the sector.
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
virtual IdentifierHash measurementHash(const Identifier &measId) const =0
Constructs the identifier hash from the full measurement Identifier.
virtual IdentifierHash layerHash(const Identifier &measId) const =0
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 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.
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 muon space point is the combination of two uncalibrated measurements one of them measures the eta...
std::vector< ObjectMatching > matchWithTruth(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegmentContainer *truthSegments, const MuonR4::SegmentSeedContainer *seedContainer, const MuonR4::SegmentContainer *segmentContainer) const
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.
SG::ReadHandleKeyArray< MuonR4::SegmentContainer > m_inSegmentKeys
MuonVal::ScalarBranch< unsigned > & m_out_segment_n
========== Segment block: Filled when we have one or multiple segments =============
MuonVal::VectorBranch< unsigned short > & m_out_seed_nMm
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
MuonVal::ScalarBranch< unsigned short > & m_out_gen_nMDTHits
MuonVal::VectorBranch< float > & m_out_seed_x0
MuonVal::VectorBranch< unsigned short > & m_out_segment_truthMatchedHits
SG::ReadHandleKey< MuonR4::SpacePointContainer > m_spKey
MuonVal::VectorBranch< unsigned short > & m_out_seed_nTruePrecHits
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::VectorBranch< unsigned short > & m_out_segment_nsTgcPadpHits
MuonVal::VectorBranch< unsigned short > & m_out_segment_nsTgcWireHits
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_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
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
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::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
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
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_nsTgc
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
SG::ReadHandleKeyArray< MuonR4::SegmentSeedContainer > m_inHoughSegmentSeedKeys
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
@ isMC
Flag determining whether the branch is simulation.
Helper class to provide type-safe access to aux data.
Property holding a SG store/key/clid from which a ReadHandle is made.
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.
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
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.
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
DataVector< SegmentSeed > SegmentSeedContainer
DataVector< Segment > SegmentContainer
double houghTanAlpha(const Amg::Vector3D &v)
: Returns the hough tanAlpha [x] / [z]
const SpacePoint * HoughHitType
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
std::unordered_set< const xAOD::MuonSimHit * > simHitSet
bool isPrecHit(const SpType &sp)
Define a spacepoint as precision hit if it's a Mdt or NSW eta hit.
MuonHoughTransformTester::ObjectMatching ObjectMatching
unsigned int countMatched(const simHitSet &truthHits, const simHitSet &recoHits)
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.
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12
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.