ATLAS Offline Software
MuonHoughTransformTester.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include "GaudiKernel/SystemOfUnits.h"
14 #include "GaudiKernel/PhysicalConstants.h"
15 
16 
17 namespace MuonValR4 {
18  using namespace MuonR4;
19  using simHitSet = std::unordered_set<const xAOD::MuonSimHit*>;
20  unsigned int countMatched(const simHitSet& truthHits,
21  const simHitSet& recoHits) {
22  unsigned int matched{0};
23  for (const xAOD::MuonSimHit* reco : recoHits) {
24  matched += truthHits.count(reco);
25  }
26  return matched;
27  }
28 
31  ATH_CHECK(m_inHoughSegmentSeedKey.initialize());
32  ATH_CHECK(m_truthSegmentKey.initialize(!m_truthSegmentKey.empty()));
33  ATH_CHECK(m_inSegmentKey.initialize(!m_inSegmentKey.empty()));
34  ATH_CHECK(m_tree.initialize(this));
35  ATH_CHECK(m_idHelperSvc.retrieve());
37  ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
38  ATH_MSG_DEBUG("Succesfully initialised");
39  return StatusCode::SUCCESS;
40  }
41 
42 
44  const xAOD::MuonSegment& truthSeg,
45  const MuonR4::Segment& recoSeg) const{
46  unsigned int same{0};
47  const auto [truPos, truDir] = SegmentFit::makeLine(SegmentFit::localSegmentPars(truthSeg));
48  const auto [recoPos, recoDir] = SegmentFit::makeLine(SegmentFit::localSegmentPars(gctx, recoSeg));
49  const std::vector<int> truthSigns = SegmentFitHelpers::driftSigns(truPos, truDir, recoSeg.measurements(), msgStream());
50  const std::vector<int> recoSigns = SegmentFitHelpers::driftSigns(recoPos, recoDir, recoSeg.measurements(), msgStream());
51  for (unsigned int s = 0 ; s < truthSigns.size(); ++s) {
52  same += (truthSigns[s] != 0) && truthSigns[s] == recoSigns[s];
53  }
54  return same;
55  }
56  std::vector<MuonValR4::ObjectMatching>
58  const xAOD::MuonSegmentContainer* truthSegments,
59  const SegmentSeedContainer* seedContainer,
60  const SegmentContainer* segmentContainer) const {
61  std::vector<ObjectMatching> allAssociations{};
62  std::unordered_set<const SegmentSeed*> usedSeeds{};
63  std::unordered_set<const Segment*> usedSegs{};
64 
67  if (truthSegments) {
68 
69  // collect the sim hits that contributed to our segments and seeds.
70  std::vector<simHitSet> truthHitsVec{}, seedSimHitVec{}, segmentSimHitVec{};
71  for (const SegmentSeed* seed: *seedContainer) {
72  seedSimHitVec.emplace_back(getMatchingSimHits(*seed));
73  }
74  for (const Segment* segment: *segmentContainer){
75  segmentSimHitVec.emplace_back(getMatchingSimHits(*segment));
76  }
77 
78  // Now look at the truth segments, collecting their sim hits.
79  // Compare these to the sim hits on our reco objects
80  for (const xAOD::MuonSegment* truth: *truthSegments) {
81  const simHitSet& truthHits{truthHitsVec.emplace_back(getMatchingSimHits(*truth))};
82  ObjectMatching & matchedWithTruth = allAssociations.emplace_back();
83  matchedWithTruth.truthSegment = truth;
84  matchedWithTruth.chamber = m_r4DetMgr->getSectorEnvelope((*truthHits.begin())->identify());
85 
86  std::vector<std::pair<const SegmentSeed*, unsigned>> matchedSeeds{};
87 
88  // Find seeds sharing at least one simHit with our truth segment
89  // can't wait for views::enumerate
90  int seedIdx{-1};
91  for (const SegmentSeed* seed : *seedContainer) {
92  ++seedIdx;
93  if (seed->msSector() != matchedWithTruth.chamber) {
94  continue;
95  }
96  const simHitSet& seedHits{seedSimHitVec[seedIdx]};
97  unsigned int matchedHits = countMatched(truthHits, seedHits);
98  if (!matchedHits) {
99  continue;
100  }
101  matchedSeeds.emplace_back(std::make_pair(seed, matchedHits));
102  }
103  // Find segments sharing at least one simHit with our truth segment
104  int segmentIdx{-1};
105  std::vector<std::pair<const Segment*, unsigned>> matchedSegs{};
106  for (const Segment* segment : *segmentContainer) {
107  ++segmentIdx;
108  if (segment->msSector() != matchedWithTruth.chamber) {
109  continue;
110  }
111  const simHitSet& segmentHits{segmentSimHitVec[segmentIdx]};
112  unsigned int matchedHits = countMatched(truthHits, segmentHits);
113  if (!matchedHits) {
114  continue;
115  }
116  matchedSegs.emplace_back(std::make_pair(segment,matchedHits));
117  }
118 
119  // sort by quality of match
120 
121  // for segments (by hit count and same-side hits)
122  std::ranges::sort(matchedSegs,
123  [this, &truth, &gctx](const std::pair<const Segment*, unsigned>& segA,
124  const std::pair<const Segment*, unsigned>& segB){
125  if (segA.second != segB.second) return segA.second > segB.second;
126  return countOnSameSide(gctx, *truth, *segA.first) > countOnSameSide(gctx, *truth, *segB.first);
127  });
128  // and for seeds (by raw hit count)
129  std::ranges::sort(matchedSeeds, [](const std::pair<const SegmentSeed*, unsigned>& seedA,
130  const std::pair<const SegmentSeed*, unsigned>& seedB) {
131  return seedA.second > seedB.second;
132  });
133 
134 
135  // now we can populate our association object
136 
137  // first, we handle the segments and any seeds connected with them
138  for (const auto& [matched, nMatchedHits] : matchedSegs) {
139  // add segment to the list of all segments
140  matchedWithTruth.matchedSegments.push_back(matched);
141  matchedWithTruth.matchedSegHits.push_back(nMatchedHits);
142  // and update our book-keeping to record that this segment and its seed have already been written
143  usedSeeds.insert(matched->parent());
144  usedSegs.insert(matched);
145  }
146 
147  // now, we add the seeds
148  for (const auto& [seed , nHits] : matchedSeeds) {
149  // add seed to the list of all seeds
150  matchedWithTruth.matchedSeeds.push_back(seed);
151  matchedWithTruth.matchedSeedHits.push_back(nHits);
152  matchedWithTruth.matchedSeedFoundSegment.push_back(usedSeeds.count(seed));
153  usedSeeds.insert(seed);
154  }
155  } // end of loop over truth segments
156  }
157 
161 
162  // start with segments, and also collect "their" seeds in a common entry
163  for (const Segment* seg: *segmentContainer) {
164  // skip segments that were previously seen and written in the truth loop
165  if (usedSegs.count(seg)) {
166  continue;
167  }
168  ObjectMatching & match = allAssociations.emplace_back();
169  match.chamber = seg->msSector();
170  match.matchedSegments = {seg};
171  match.matchedSeeds = {seg->parent()};
172  // this seed has been written as well - do not write it in the following loop
173  usedSeeds.insert(seg->parent());
174  }
175  for (const SegmentSeed* seed: *seedContainer) {
176  // skip seeds that are on segments or seen in the truth loop
177  if (usedSeeds.count(seed)) {
178  continue;
179  }
180  ObjectMatching & match = allAssociations.emplace_back();
181  match.chamber = seed->msSector();
182  match.matchedSeeds = {seed};
183  }
184  return allAssociations;
185  }
186 
187  template <class ContainerType>
190  const ContainerType*& contToPush) const {
191  contToPush = nullptr;
192  if (key.empty()) {
193  ATH_MSG_VERBOSE("No key has been parsed for object "<< typeid(ContainerType).name());
194  return StatusCode::SUCCESS;
195  }
196  SG::ReadHandle readHandle{key, ctx};
197  ATH_CHECK(readHandle.isPresent());
198  contToPush = readHandle.cptr();
199  return StatusCode::SUCCESS;
200  }
201 
204  return StatusCode::SUCCESS;
205  }
207 
208  const EventContext & ctx = Gaudi::Hive::currentContext();
209  const ActsGeometryContext* gctxPtr{nullptr};
210  ATH_CHECK(retrieveContainer(ctx, m_geoCtxKey, gctxPtr));
211  const ActsGeometryContext& gctx{*gctxPtr};
212 
213  // retrieve the two input collections
214 
215  const SegmentSeedContainer* readSegmentSeeds{nullptr};
216  ATH_CHECK(retrieveContainer(ctx, m_inHoughSegmentSeedKey, readSegmentSeeds));
217 
218  const SegmentContainer* readMuonSegments{nullptr};
219  ATH_CHECK(retrieveContainer(ctx, m_inSegmentKey, readMuonSegments));
220 
221  const xAOD::MuonSegmentContainer* readTruthSegments{nullptr};
222  ATH_CHECK(retrieveContainer(ctx, m_truthSegmentKey, readTruthSegments));
223 
224 
225  ATH_MSG_DEBUG("Succesfully retrieved input collections");
226 
227  std::vector<ObjectMatching> objects = matchWithTruth(gctx, readTruthSegments, readSegmentSeeds, readMuonSegments);
228  for (const ObjectMatching& obj : objects) {
229  m_tree.fillChamberInfo(obj.chamber);
230  m_tree.fillTruthInfo(obj.truthSegment, m_r4DetMgr, gctx);
232  m_tree.fillSegmentInfo(gctx, obj);
233  ATH_CHECK(m_tree.fill(ctx));
234  }
235 
236  return StatusCode::SUCCESS;
237  }
238 } // namespace MuonValR4
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
MuonR4::SegmentFitHelpers::driftSigns
std::vector< int > driftSigns(const Amg::Vector3D &posInChamber, const Amg::Vector3D &dirInChamber, const std::vector< const SpacePoint * > &uncalibHits, MsgStream &msg)
Calculates whether a segment line travereses the tube measurements on the left (-1) or right (1) side...
Definition: SegmentFitHelperFunctions.cxx:210
MuonSimHitHelpers.h
xAOD::MuonSimHit_v1
Definition: MuonSimHit_v1.h:18
UtilFunctions.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
MuonValR4::MuonHoughTransformTester::finalize
virtual StatusCode finalize() override
Definition: MuonHoughTransformTester.cxx:202
MuonValR4::countMatched
unsigned int countMatched(const simHitSet &truthHits, const simHitSet &recoHits)
Definition: MuonHoughTransformTester.cxx:20
MuonValR4::ObjectMatching
helper struct to associate truth to reco segments and hough seeds
Definition: MuonPatternRecognitionTestTree.h:24
LArConditions2Ntuple.objects
objects
Definition: LArConditions2Ntuple.py:59
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
MuonR4::Segment
Placeholder for what will later be the muon segment EDM representation.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:19
MuonValR4::MuonPatternRecognitionTestTree::fillTruthInfo
void fillTruthInfo(const xAOD::MuonSegment *truthSegment, const MuonGMR4::MuonDetectorManager *detMgr, const ActsGeometryContext &gctx)
Definition: MuonPatternRecognitionTestTree.cxx:32
MuonR4::Segment::measurements
const MeasVec & measurements() const
Returns the associated measurements.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:55
MuonValR4::MuonHoughTransformTester::m_visionTool
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
Definition: MuonHoughTransformTester.h:92
MuonValR4::MuonPatternRecognitionTestTree::fillSegmentInfo
void fillSegmentInfo(const ActsGeometryContext &gctx, const ObjectMatching &obj)
Definition: MuonPatternRecognitionTestTree.cxx:153
MuonValR4::ObjectMatching::matchedSegHits
std::vector< unsigned > matchedSegHits
Shared sim hit counts for segments matched to this object.
Definition: MuonPatternRecognitionTestTree.h:32
HoughHelperFunctions.h
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
EventInfoBranch.h
MuonValR4::MuonHoughTransformTester::m_tree
MuonValR4::MuonPatternRecognitionTestTree m_tree
Definition: MuonHoughTransformTester.h:97
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::ReadHandleKey< ContainerType >
SpectrometerSector.h
MuonR4::SegmentFit::makeLine
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
Definition: SegmentFitterEventData.cxx:26
python.TrigEgammaFastCaloHypoTool.same
def same(val, tool)
Definition: TrigEgammaFastCaloHypoTool.py:12
MuonValR4::MuonHoughTransformTester::m_truthSegmentKey
SG::ReadHandleKey< xAOD::MuonSegmentContainer > m_truthSegmentKey
Definition: MuonHoughTransformTester.h:82
MuonValR4::simHitSet
std::unordered_set< const xAOD::MuonSimHit * > simHitSet
Definition: MuonHoughTransformTester.cxx:19
AthCommonDataStore< AthCommonMsg< Algorithm > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
MuonValR4::MuonHoughTransformTester::matchWithTruth
std::vector< ObjectMatching > matchWithTruth(const ActsGeometryContext &gctx, const xAOD::MuonSegmentContainer *truthSegments, const MuonR4::SegmentSeedContainer *seedContainer, const MuonR4::SegmentContainer *segmentContainer) const
Definition: MuonHoughTransformTester.cxx:57
MuonValR4::ObjectMatching::truthSegment
const xAOD::MuonSegment * truthSegment
Truth segment for reference.
Definition: MuonPatternRecognitionTestTree.h:28
MuonValR4::MuonHoughTransformTester::countOnSameSide
unsigned int countOnSameSide(const ActsGeometryContext &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...
Definition: MuonHoughTransformTester.cxx:43
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
SegmentFitHelperFunctions.h
MuonValR4::ObjectMatching::matchedSeeds
std::vector< const MuonR4::SegmentSeed * > matchedSeeds
All seeds matched to this object.
Definition: MuonPatternRecognitionTestTree.h:34
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonValR4::ObjectMatching::matchedSeedFoundSegment
std::vector< char > matchedSeedFoundSegment
Definition: MuonPatternRecognitionTestTree.h:37
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
MuonValR4::MuonHoughTransformTester::m_r4DetMgr
const MuonGMR4::MuonDetectorManager * m_r4DetMgr
Definition: MuonHoughTransformTester.h:94
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
ActsGeometryContext
Include the GeoPrimitives which need to be put first.
Definition: ActsGeometryContext.h:27
MuonValR4::MuonPatternRecognitionTestTree::initialize
StatusCode initialize(AthHistogramAlgorithm *parent)
initialisation - internally calls the MuonTesterTree::init method
Definition: MuonPatternRecognitionTestTree.cxx:22
MuonValR4
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
Definition: IPatternVisualizationTool.h:23
MuonHoughDefs.h
MuonValR4::MuonHoughTransformTester::m_geoCtxKey
SG::ReadHandleKey< ActsGeometryContext > m_geoCtxKey
Definition: MuonHoughTransformTester.h:87
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
python.ElectronD3PDObject.matched
matched
Definition: ElectronD3PDObject.py:138
MuonValR4::MuonHoughTransformTester::initialize
virtual StatusCode initialize() override
Definition: MuonHoughTransformTester.cxx:29
MuonValR4::ObjectMatching::chamber
const MuonGMR4::SpectrometerSector * chamber
Associated chamber.
Definition: MuonPatternRecognitionTestTree.h:26
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
MuonValR4::MuonPatternRecognitionTestTree::fillChamberInfo
void fillChamberInfo(const MuonGMR4::SpectrometerSector *chamber)
Definition: MuonPatternRecognitionTestTree.cxx:27
MuonValR4::MuonHoughTransformTester::execute
virtual StatusCode execute() override
Definition: MuonHoughTransformTester.cxx:206
MuonValR4::MuonHoughTransformTester::m_inHoughSegmentSeedKey
SG::ReadHandleKey< MuonR4::SegmentSeedContainer > m_inHoughSegmentSeedKey
Definition: MuonHoughTransformTester.h:84
MuonR4::SegmentSeed
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Definition: SegmentSeed.h:14
MuonVal::MuonTesterTree::fill
bool fill(const EventContext &ctx)
Fills the tree per call.
Definition: MuonTesterTree.cxx:89
MuonVal::MuonTesterTree::write
StatusCode write()
Finally write the TTree objects.
Definition: MuonTesterTree.cxx:178
MuonHoughTransformTester.h
MuonValR4::ObjectMatching::matchedSegments
std::vector< const MuonR4::Segment * > matchedSegments
All segments matched to this object.
Definition: MuonPatternRecognitionTestTree.h:30
MuonR4::SegmentFit::localSegmentPars
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
Definition: SegmentFitterEventData.cxx:32
MuonValR4::MuonHoughTransformTester::m_inSegmentKey
SG::ReadHandleKey< MuonR4::SegmentContainer > m_inSegmentKey
Definition: MuonHoughTransformTester.h:85
MuonValR4::ObjectMatching::matchedSeedHits
std::vector< unsigned > matchedSeedHits
Shared sim hit counts for seeds matched to this object.
Definition: MuonPatternRecognitionTestTree.h:36
MuonValR4::MuonPatternRecognitionTestTree::fillSeedInfo
void fillSeedInfo(const ObjectMatching &obj)
Definition: MuonPatternRecognitionTestTree.cxx:82
python.PyAthena.obj
obj
Definition: PyAthena.py:132
MuonValR4::MuonHoughTransformTester::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: MuonHoughTransformTester.h:89
MuonR4::getMatchingSimHits
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
Definition: MuonSimHitHelpers.cxx:24
MuonSegmentReaderConfig.reco
reco
Definition: MuonSegmentReaderConfig.py:133
match
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition: hcg.cxx:356
MuonGMR4::MuonDetectorManager::getSectorEnvelope
const SpectrometerSector * getSectorEnvelope(const Identifier &channelId) const
Retrieves the spectrometer envelope enclosing the channel's readout element.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonDetectorManager.cxx:159
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5
MuonValR4::MuonHoughTransformTester::retrieveContainer
StatusCode retrieveContainer(const EventContext &ctx, const SG::ReadHandleKey< ContainerType > &key, const ContainerType *&contToPush) const
Helper method to fetch data from StoreGate.
Definition: MuonHoughTransformTester.cxx:188
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37