ATLAS Offline Software
SegmentAmbiSolver.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
5 #include <Acts/Utilities/Enumerate.hpp>
6 
7 namespace MuonR4::SegmentFit {
9 
12  m_cfg{std::move(cfg)} {}
13 
14  double SegmentAmbiSolver::redChi2(const Segment& segment) const {
15  return segment.chi2() / segment.nDoF();
16  }
18  SegmentVec&& toResolve) const {
19 
20  std::ranges::stable_sort(toResolve,[this](const SegmentVec::value_type& a,
21  const SegmentVec::value_type& b){
22  const double redChi2A = redChi2(*a);
23  const double redChi2B = redChi2(*b);
24  if (redChi2A < m_cfg.selectByNDoFChi2 && redChi2B < m_cfg.selectByNDoFChi2){
25  return a->nDoF() > b->nDoF();
26  }
27  return redChi2A < redChi2B;
28  });
29  SegmentVec resolved{};
30 
32  resolved.push_back(std::move(toResolve[0]));
33  toResolve.erase(toResolve.begin());
34  std::vector<std::vector<int>> segmentSigns{driftSigns(gctx, *resolved.front(), resolved.front()->measurements())};
35  std::vector<MeasurementSet> segMeasurements{extractPrds(*resolved.front())};
36 
37  for (std::unique_ptr<Segment>& resolveMe : toResolve) {
38  ATH_MSG_VERBOSE("Try to resolve new segment "<<toString(localSegmentPars(gctx, *resolveMe))
39  <<" redChi2: "<<redChi2(*resolveMe)<<" nDoF: "<<resolveMe->nDoF());
41  MeasurementSet testMeas{extractPrds(*resolveMe)};
43  unsigned resolvedIdx{0};
44  for (std::unique_ptr<Segment>& goodSeg : resolved) {
45  ATH_MSG_VERBOSE("Test against segment "<<toString(localSegmentPars(gctx, *goodSeg))
46  <<" redChi2: "<<redChi2(*goodSeg)<<" nDoF: "<<goodSeg->nDoF());
47  MeasurementSet& resolvedM = segMeasurements[resolvedIdx];
48  std::vector<int>& existSigns{segmentSigns[resolvedIdx++]};
50  unsigned shared = countShared(resolvedM, testMeas);
51  if (shared < m_cfg.sharedPrecHits) {
52  ATH_MSG_VERBOSE("Too few shared measurements "<<shared<<" (Required: "<<m_cfg.sharedPrecHits<<").");
53  continue;
54  }
56  const std::vector<int> reEvaluatedSigns{driftSigns(gctx, *resolveMe, goodSeg->measurements())};
57 
58  unsigned sameSides{0};
59  for (unsigned s =0 ; s < existSigns.size(); ++s) {
60  sameSides += (reEvaluatedSigns[s] == existSigns[s]);
61  }
63  if (!m_cfg.remLeftRightAmbi && sameSides != existSigns.size() && resolveMe->nDoF() == goodSeg->nDoF()) {
64  ATH_MSG_VERBOSE("Reference signs: "<<existSigns<<" / re-evaluated: "<<reEvaluatedSigns);
65  continue;
66  }
67  const double resolvedChi2 = redChi2(*goodSeg);
68  const double resolveMeChi2 = redChi2(*resolveMe);
69  reso = resolveMeChi2 < resolvedChi2 ? Resolution::superSet : Resolution::subSet;
70 
71  ATH_MSG_VERBOSE("Chi2 good "<<resolvedChi2<<", candidate chi2: "<<resolveMeChi2);
74  if (resolveMeChi2 < m_cfg.selectByNDoFChi2 && resolvedChi2 < m_cfg.selectByNDoFChi2) {
75  reso = goodSeg->nDoF() > resolveMe->nDoF() ? Resolution::subSet : Resolution::superSet;
76  }
77  if (reso == Resolution::superSet) {
78  std::swap(goodSeg, resolveMe);
79  std::swap(resolvedM, testMeas);
80  existSigns = driftSigns(gctx, *resolveMe, resolveMe->measurements());
81  break;
82  } else if (reso == Resolution::subSet) {
83  break;
84  }
85  }
87  if (reso == Resolution::noOverlap) {
88  segMeasurements.push_back(std::move(testMeas));
89  segmentSigns.push_back(driftSigns(gctx, *resolveMe, resolveMe->measurements()));
90  resolved.push_back(std::move(resolveMe));
91  }
92  }
93  return resolved;
94  }
96  const Segment& segment,
97  const Segment::MeasVec& measurements) const {
98  const auto [pos, dir] = makeLine(localSegmentPars(gctx, segment));
99 
100  ATH_MSG_VERBOSE("Fetch drift signs for segment "<<segment.msSector()->identString()
101  <<" -- "<<Amg::toString(pos)<<" + " <<Amg::toString(dir));
102  return SeedingAux::strawSigns(pos, dir, measurements);
103  }
105  SegmentAmbiSolver::extractPrds(const Segment& segment) const {
106 
107  MeasurementSet meas{};
108  for (const Segment::MeasVec::value_type& hit : segment.measurements()) {
109  if (!hit->spacePoint() || hit->fitState() != CalibratedSpacePoint::State::Valid || !hit->measuresEta()) {
110  continue;
111  }
112  meas.insert(hit->spacePoint()->primaryMeasurement());
113  if (hit->spacePoint()->secondaryMeasurement()) {
114  meas.insert(hit->spacePoint()->secondaryMeasurement());
115  }
116  }
117  return meas;
118  }
120  const MeasurementSet& measSet2) const {
121  if (measSet1.size() > measSet2.size()) {
122  return std::count_if(measSet2.begin(),measSet2.end(),[&measSet1](const xAOD::UncalibratedMeasurement* meas){
123  return measSet1.count(meas);
124  });
125  }
126  return std::count_if(measSet1.begin(),measSet1.end(),[&measSet2](const xAOD::UncalibratedMeasurement* meas){
127  return measSet2.count(meas);
128  });
129  }
130 }
MuonR4::SegmentFit::SegmentAmbiSolver::SegmentAmbiSolver
SegmentAmbiSolver(const std::string &name, Config &&config)
Definition: SegmentAmbiSolver.cxx:10
MuonR4::SegmentFit::SegmentAmbiSolver::driftSigns
std::vector< int > driftSigns(const ActsTrk::GeometryContext &gctx, const Segment &segment, const Segment::MeasVec &measurements) const
Definition: SegmentAmbiSolver.cxx:95
MuonR4::SegmentFit
Definition: MuonHoughDefs.h:34
MuonR4::CalibratedSpacePoint::State::Valid
@ Valid
MuonR4::Segment
Placeholder for what will later be the muon segment EDM representation.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:19
MuonR4::SegmentFit::SegmentAmbiSolver::Config
Definition: SegmentAmbiSolver.h:17
MuonR4::Segment::measurements
const MeasVec & measurements() const
Returns the associated measurements.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:49
MuonR4::SegmentFit::SegmentAmbiSolver::Resolution
Resolution
Definition: SegmentAmbiSolver.h:36
MuonR4::SegmentFit::SegmentAmbiSolver::m_cfg
const Config m_cfg
Definition: SegmentAmbiSolver.h:42
MuonR4::SegmentFit::SegmentAmbiSolver::MeasurementSet
std::unordered_set< const xAOD::UncalibratedMeasurement * > MeasurementSet
Definition: SegmentAmbiSolver.h:48
MuonR4::SegmentFit::SegmentVec
SegmentAmbiSolver::SegmentVec SegmentVec
Definition: SegmentAmbiSolver.cxx:8
MuonR4::Segment::chi2
double chi2() const
Returns the chi2 of the segment fit.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:45
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
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:35
MuonGMR4::SpectrometerSector::identString
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
Definition: SpectrometerSector.cxx:66
MuonR4::Segment::nDoF
unsigned int nDoF() const
Returns the number of degrees of freedom.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:47
xAOD::UncalibratedMeasurement_v1
Definition: UncalibratedMeasurement_v1.h:13
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
MuonR4::SegmentFit::SegmentAmbiSolver::Resolution::noOverlap
@ noOverlap
MuonR4::Segment::MeasVec
std::vector< MeasType > MeasVec
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:24
MuonR4::SegmentFit::SegmentAmbiSolver::resolveAmbiguity
SegmentVec resolveAmbiguity(const ActsTrk::GeometryContext &gctx, SegmentVec &&toResolve) const
Definition: SegmentAmbiSolver.cxx:17
AthMessaging
Class to provide easy MsgStream access and capabilities.
Definition: AthMessaging.h:55
MuonR4::SegmentFit::toString
std::string toString(const Parameters &pars)
Dumps the parameters into a string with labels in front of each number.
Definition: SegmentFitterEventData.cxx:73
ActsTrk::GeometryContext
Definition: GeometryContext.h:28
MuonR4::Segment::msSector
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated MS sector.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:39
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
MuonR4::SegmentFit::SegmentAmbiSolver::Resolution::subSet
@ subSet
beamspotman.dir
string dir
Definition: beamspotman.py:619
MuonR4::SegmentFit::SegmentAmbiSolver::extractPrds
MeasurementSet extractPrds(const Segment &segment) const
Extract the Uncalibrated measurements used to build the segment.
Definition: SegmentAmbiSolver.cxx:105
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
WriteCaloSwCorrections.cfg
cfg
Definition: WriteCaloSwCorrections.py:23
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
SegmentAmbiSolver.h
MuonR4::SegmentFit::SegmentAmbiSolver::SegmentVec
std::vector< std::unique_ptr< Segment > > SegmentVec
Definition: SegmentAmbiSolver.h:31
MuonR4::SegmentFit::SegmentAmbiSolver::countShared
unsigned int countShared(const MeasurementSet &measSet1, const MeasurementSet &measSet2) const
counts the number of measurements that're in both sets
Definition: SegmentAmbiSolver.cxx:119
MuonR4::SegmentFit::SegmentAmbiSolver::redChi2
double redChi2(const Segment &segment) const
Returns the reduced chi2 of the segment.
Definition: SegmentAmbiSolver.cxx:14
MuonR4::SegmentFit::SegmentAmbiSolver::Resolution::superSet
@ superSet
MuonR4::SegmentFit::SegmentAmbiSolver::Config::remLeftRightAmbi
bool remLeftRightAmbi
Allow for left-right ambiguities.
Definition: SegmentAmbiSolver.h:24
a
TList * a
Definition: liststreamerinfos.cxx:10
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
MuonR4::SegmentFit::localSegmentPars
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
Definition: SegmentFitterEventData.cxx:42
MuonR4::SegmentFit::SegmentAmbiSolver::Config::sharedPrecHits
unsigned int sharedPrecHits
Cut on the number of shared precision hits.
Definition: SegmentAmbiSolver.h:22
MuonR4::SegmentFit::SegmentAmbiSolver::Config::selectByNDoFChi2
double selectByNDoFChi2
If two overlapping segments have both the chi2 below the threshold, the one with more degrees of free...
Definition: SegmentAmbiSolver.h:20