Loading [MathJax]/jax/input/TeX/config.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MsTrackTester.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "MsTrackTester.h"
5 
6 #include "StoreGate/ReadHandle.h"
9 
10 using namespace MuonVal;
11 using namespace MuonPRDTest;
12 
13 namespace {
15  using SegLinkVec_t = std::vector<SegLink_t>;
16  static const SG::ConstAccessor<SegLinkVec_t> acc_truthSegLinks{"truthSegmentLinks"};
17 }
18 
19 namespace MuonValR4 {
21  ATH_CHECK(m_truthSegmentKey.initialize(m_isMC));
22  ATH_CHECK(m_truthKey.initialize(m_isMC));
23  ATH_CHECK(m_msTrkSeedKey.initialize());
24  ATH_CHECK(m_recoSegmentKey.initialize());
25  ATH_CHECK(m_segSelector.retrieve());
26 
27  int evOpts{0};
28 
29  m_recoSegs = std::make_unique<SegmentVariables>(m_tree, m_recoSegmentKey.key(), "Segments", msgLevel());
31  "Segments_passSeedQual",[this](const SG::AuxElement* aux){
32  const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
33  return m_segSelector->passSeedingQuality(Gaudi::Hive::currentContext(),
34  *MuonR4::detailedSegment(*seg)); }));
36  "Segments_passTrackQual",[this](const SG::AuxElement* aux){
37  const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
38  return m_segSelector->passTrackQuality(Gaudi::Hive::currentContext(),
39  *MuonR4::detailedSegment(*seg));
40  }));
41  if (m_isMC) {
42  evOpts |= EventInfoBranch::isMC;
44  "Segments_truthSegLink",[this](const SG::AuxElement* aux){
45  const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
47  const unsigned linkIdx = truthS ? m_truthSegs->push_back(*truthS) : -1;
49  if (truthS) {
50  m_truthSegToRecoLink.push_back(linkIdx, m_recoSegs->push_back(*seg));
52  if (truthMuon){
53  m_truthTrks->push_back(truthMuon);
54  m_truthMuRecoSegLinks[m_truthTrks->find(truthMuon)].push_back(m_recoSegs->push_back(*seg));
55  }
56  }
57  return linkIdx;
58  }));
59 
60  m_truthSegs = std::make_unique<SegmentVariables>(m_tree, m_truthSegmentKey.key(), "TruthSegments", msgLevel());
61 
63  "TruthSegments_truthLink",[this](const SG::AuxElement* aux){
64  const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
66  m_truthTrks->push_back(truthP);
67  unsigned short linkIdx = m_truthTrks->find(truthP);
68  return linkIdx;
69  }));
71  "TruthSegments_hasBarrelProj", [this](const SG::AuxElement* aux){
72  const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
73  return std::abs(expressAtRefPlane(*seg, Location::Barrel)) < m_refEndcapDiscZ;
74  }));
75 
77  "TruthSegments_hasEndcapProj", [this](const SG::AuxElement* aux){
78  const auto* seg = static_cast<const xAOD::MuonSegment*>(aux);
79  return std::abs(expressAtRefPlane(*seg, Location::Endcap)) < m_refEndcapDiscR;
80  }));
81  m_tree.addBranch(m_truthSegs);
82 
83  m_truthTrks = std::make_unique<IParticleFourMomBranch>(m_tree, "TruthMuons");
84  m_tree.addBranch(m_truthTrks);
85  m_trkTruthLinks.emplace_back(m_truthSegmentKey, "truthParticleLink");
86  m_trkTruthLinks.emplace_back(m_truthKey, "truthSegmentLinks");
87  m_trkTruthLinks.emplace_back(m_recoSegmentKey, "truthSegmentLink");
88  }
89 
90  m_tree.addBranch(m_recoSegs);
91  m_tree.addBranch(std::make_unique<EventInfoBranch>(m_tree, evOpts));
92 
93  ATH_CHECK(m_trkTruthLinks.initialize());
94  ATH_CHECK(m_tree.init(this));
95  return StatusCode::SUCCESS;
96  }
98  const EventContext& ctx{Gaudi::Hive::currentContext()};
99 
101  const MuonR4::MsTrackSeedContainer* trkSeeds{nullptr};
102  ATH_CHECK(SG::get(trkSeeds, m_msTrkSeedKey, ctx));
103  std::map<const xAOD::TruthParticle*, std::vector<unsigned>> truthToSeedMatchCounter{};
104  for (const MuonR4::MsTrackSeed& seed : *trkSeeds) {
105  unsigned int seedIdx = m_seedPos.size();
106  m_seedPos += seed.position();
107  m_seedType+= static_cast<char>(seed.location());
108  double minL{Gaudi::Units::km}, maxL{-Gaudi::Units::km}, minTheta{M_PI}, maxTheta{-M_PI};
109  for (const xAOD::MuonSegment* seg : seed.segments()) {
110  m_seedRecoSegMatch[seedIdx].push_back(m_recoSegs->push_back(*seg));
111  const xAOD::MuonSegment* truthSeg = MuonR4::getMatchedTruthSegment(*seg);
112  if (!truthSeg) {
113  continue;
114  }
115  const double projected = expressAtRefPlane(*seg, seed.location());
116  const double theta = seg->direction().theta();
117  minL = std::min(minL, projected);
118  maxL = std::max(maxL, projected);
119  minTheta = std::min(minTheta, theta);
120  maxTheta = std::max(maxTheta, theta);
121 
122  std::vector<unsigned>& matchCounter = truthToSeedMatchCounter[MuonR4::getTruthMatchedParticle(*truthSeg)];
123  if (seedIdx >= matchCounter.size()) matchCounter.resize(seedIdx +1);
124  ++matchCounter[seedIdx];
125  }
126  m_seedLength+=(maxL - minL);
127  m_seedThetaCone+=(maxTheta - minTheta);
128  }
130  const xAOD::MuonSegmentContainer* recoSegments{nullptr};
131  ATH_CHECK(SG::get(recoSegments, m_recoSegmentKey, ctx));
132  for (const xAOD::MuonSegment* seg : *recoSegments) {
133  m_recoSegs->push_back(*seg);
134  }
136  const xAOD::MuonSegmentContainer* truthSegs{nullptr};
137  ATH_CHECK(SG::get(truthSegs, m_truthSegmentKey, ctx));
138  if (truthSegs) {
139  for (const xAOD::MuonSegment* seg : *truthSegs) {
140  m_truthSegs->push_back(*seg);
141  }
142  if (truthSegs->size()) {
143  m_truthSegToRecoLink[truthSegs->size()-1];
144  }
145  }
147  const xAOD::TruthParticleContainer* truthMuons{nullptr};
148  ATH_CHECK(SG::get(truthMuons, m_truthKey, ctx));
149  if (truthMuons && truthMuons->size()) {
150  m_truthMuToSeedIdx[truthMuons->size() -1];
151  m_truthMuToSeedCounter[truthMuons->size() -1];
152  m_truthMuTruthSegLinks[truthMuons->size() -1];
153  m_truthMuRecoSegLinks[truthMuons->size() -1];
154 
155  for (const xAOD::TruthParticle* truth : *truthMuons) {
156  m_truthTrks->push_back(*truth);
157  unsigned truthIdx = m_truthTrks->find(truth);
158  std::vector<unsigned>& matchCounter = truthToSeedMatchCounter[truth];
159 
160  std::vector<unsigned>::iterator maxSeed = matchCounter.begin();
161  while ( (maxSeed = std::ranges::max_element(matchCounter))!=matchCounter.end() && (*maxSeed) > 0) {
162  m_truthMuToSeedIdx[truthIdx].push_back(std::distance(matchCounter.begin(), maxSeed));
163  m_truthMuToSeedCounter[truthIdx].push_back(*maxSeed);
164  (*maxSeed) = 0;
165  }
166 
167  std::vector<unsigned short>& truthSegLinks = m_truthMuTruthSegLinks[truthIdx];
168  for (const SegLink_t& link : acc_truthSegLinks(*truth)) {
169  truthSegLinks.push_back(m_truthSegs->push_back(**link));
170  }
171  }
172  }
173  ATH_CHECK(m_tree.fill(ctx));
174  return StatusCode::SUCCESS;
175  }
176  double MsTrackTester::expressAtRefPlane(const xAOD::MuonSegment& segment,
177  const Location plane) const {
178 
179  const Amg::Vector3D pos{segment.position()};
180  const Amg::Vector3D dir{segment.direction()};
181 
182  const Amg::Vector2D projPos{pos.perp(), pos.z()};
183  const Amg::Vector2D projDir{dir.perp(), dir.z()};
184 
185  double lambda{0.};
186  if (Location::Barrel == plane) {
187  lambda = Amg::intersect<2>(projPos, projDir, Amg::Vector2D::UnitX(),
188  m_refBarrelR).value_or(0.);
189  } else {
190  lambda = Amg::intersect<2>(projPos, projDir, Amg::Vector2D::UnitY(),
191  (projPos[1] > 0 ? 1. : .1)* m_refEndcapDiscZ).value_or(0.);
192  }
193  const Amg::Vector2D refPoint{ (projPos + lambda * projDir)};
194  return plane == Location::Barrel ? refPoint.y() : refPoint.x();
195  }
196 
198  ATH_CHECK(m_tree.write());
199  return StatusCode::SUCCESS;
200  }
201 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
MuonSimHitHelpers.h
python.tests.PyTestsLib.finalize
def finalize(self)
_info( "content of StoreGate..." ) self.sg.dump()
Definition: PyTestsLib.py:50
DetType::Endcap
@ Endcap
Definition: DetType.h:14
MuonR4::getTruthMatchedParticle
const xAOD::TruthParticle * getTruthMatchedParticle(const xAOD::MuonSegment &segment)
Returns the particle truth-matched to the segment.
Definition: MuonSimHitHelpers.cxx:100
make_unique
std::unique_ptr< T > make_unique(Args &&... args)
Definition: SkimmingToolEXOT5.cxx:23
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
MuonVal::EventInfoBranch::isMC
@ isMC
Flag determining whether the branch is simulation.
Definition: EventInfoBranch.h:20
SG::AuxElement
Base class for elements of a container that can have aux data.
Definition: AuxElement.h:483
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
MuonVal::GenericAuxDecorationBranch
Generic branch object where the information is evaluated by a std::function instead reading it from t...
Definition: AuxElementBranch.h:33
MuonR4::MsTrackSeed
Definition: MsTrackSeed.h:18
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
initialize
void initialize()
Definition: run_EoverP.cxx:894
M_PI
#define M_PI
Definition: ActiveFraction.h:11
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
MuonR4::getMatchedTruthSegment
const xAOD::MuonSegment * getMatchedTruthSegment(const xAOD::MuonSegment &segment)
Returns the truth-matched segment.
Definition: MuonSimHitHelpers.cxx:111
MsTrackTester.h
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
MuonR4::MsTrackSeed::Location
Location
Enum defining whether the seed is made in the endcap / barrel.
Definition: MsTrackSeed.h:21
DetType::Barrel
@ Barrel
Definition: DetType.h:14
MuonR4::detailedSegment
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Definition: TrackingHelpers.cxx:7
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
SG::get
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition: ReadCondHandle.h:287
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:37
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonR4::SegLink_t
ElementLink< MuonR4::SegmentContainer > SegLink_t
Definition: xAODSegmentCnvAlg.cxx:18
python.SystemOfUnits.km
float km
Definition: SystemOfUnits.py:109
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
beamspotman.dir
string dir
Definition: beamspotman.py:623
MuonValR4
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
Definition: IPatternVisualizationTool.h:23
TrackingHelpers.h
MuonVal
Class to store array like branches into the n-tuples.
Definition: HitValAlg.cxx:19
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:18
python.TruthMuonD3PDObject.truthMuon
truthMuon
Definition: TruthMuonD3PDObject.py:51
MuonR4::SegLinkVec_t
std::vector< SegLink_t > SegLinkVec_t
Definition: MeasurementMarkerAlg.cxx:15
MuonR4::MsTrackSeedContainer
std::vector< MsTrackSeed > MsTrackSeedContainer
Definition: MsTrackSeed.h:61
MuonPRDTest
Definition: MuonHitTesterAlg.h:15
ReadHandle.h
Handle class for reading from StoreGate.
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5