ATLAS Offline Software
SegmentFittingAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "SegmentFittingAlg.h"
6 
8 
11 
15 
16 #include <format>
17 
18 using namespace Acts;
19 namespace MuonR4 {
20  using namespace SegmentFit;
21  using namespace MuonValR4;
22 
23 
25 
26  SegmentFittingAlg::~SegmentFittingAlg() = default;
28  ATH_CHECK(m_geoCtxKey.initialize());
29  ATH_CHECK(m_seedKey.initialize());
30  ATH_CHECK(m_outSegments.initialize());
31  ATH_CHECK(m_calibTool.retrieve());
32  ATH_CHECK(m_idHelperSvc.retrieve());
33  ATH_CHECK(m_visionTool.retrieve(EnableTool{!m_visionTool.empty()}));
35  m_ambiSolver = std::make_unique<SegmentAmbiSolver>(name(), std::move(cfg));
36 
38  fitCfg.calibrator = m_calibTool.get();
39  fitCfg.visionTool = m_visionTool.get();
40  fitCfg.idHelperSvc = m_idHelperSvc.get();
41  fitCfg.fitT0 = m_doT0Fit;
42  fitCfg.recalibrate = m_recalibInFit;
43  fitCfg.useFastFitter = m_useFastFitter;
44  fitCfg.useHessian = m_hessianResidual;
45 
46  fitCfg.doBeamSpot = m_doBeamspotConstraint;
47  fitCfg.beamSpotRadius = m_beamSpotR;
48  fitCfg.beamSpotLength = m_beamSpotL;
49 
50  fitCfg.outlierRemovalCut = m_outlierRemovalCut;
51  fitCfg.recoveryPull = m_recoveryPull;
52  fitCfg.nPrecHitCut = m_precHitCut;
53  fitCfg.maxIter = m_maxIter;
54 
55  m_fitter = std::make_unique<SegmentFit::SegmentLineFitter>(name(), std::move(fitCfg));
56 
57  return StatusCode::SUCCESS;
58  }
59  StatusCode SegmentFittingAlg::execute(const EventContext& ctx) const {
60  const ActsTrk::GeometryContext* gctx{nullptr};
61  ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
62  const SegmentSeedContainer* segmentSeeds=nullptr;
63  ATH_CHECK(SG::get(segmentSeeds, m_seedKey, ctx));
64 
65  SG::WriteHandle writeSegments{m_outSegments, ctx};
66  ATH_CHECK(writeSegments.record(std::make_unique<SegmentContainer>()));
67  std::vector<std::unique_ptr<Segment>> allSegments{};
68  for (const SegmentSeed* seed : *segmentSeeds) {
69  std::vector<std::unique_ptr<Segment>> segments = fitSegmentSeed(ctx, *gctx, seed);
70  if (m_visionTool.isEnabled() && segments.size() > 1) {
71  auto drawFinalReco = [this, &segments, &gctx, &ctx,&seed](const std::string& nameTag) {
72  PrimitiveVec segmentLines{};
73  double yLegend{0.85};
74  segmentLines.push_back(drawLabel(std::format("# segments: {:d}", segments.size()), 0.2, yLegend, 14));
75  yLegend-=0.04;
76  for (const std::unique_ptr<Segment>& seg : segments) {
77  const Parameters pars = localSegmentPars(*gctx, *seg);
78  const auto [pos, dir] = makeLine(pars);
79  segmentLines.emplace_back(drawLine(pars, -Gaudi::Units::m, Gaudi::Units::m, kRed));
80  std::stringstream signStream{};
81  signStream<<std::format("#chi^{{2}}/nDoF: {:.2f} ({:}), ", seg->chi2() / seg->nDoF(), seg->nDoF());
82  signStream<<std::format("y_{{0}}={:.2f}",pars[toUnderlying(ParamDefs::y0)])<<", ";
83  signStream<<std::format("#theta={:.2f}^{{#circ}}", pars[toUnderlying(ParamDefs::theta)]/ Gaudi::Units::deg )<<", ";
84  for (const Segment::MeasType& m : seg->measurements()) {
85  if (m->type() == xAOD::UncalibMeasType::MdtDriftCircleType && m->fitState() == CalibratedSpacePoint::State::Valid) {
86  signStream<<(SeedingAux::strawSign(pos, dir, *m) == -1 ? "L" : "R");
87  }
88  }
89  segmentLines.push_back(drawLabel(signStream.str(), 0.2, yLegend, 13));
90  yLegend-=0.03;
91  }
92 
93  m_visionTool->visualizeBucket(ctx, *seed->parentBucket(), nameTag, std::move(segmentLines));
94  };
95  drawFinalReco("all segments");
96  const unsigned int nBeforeAmbi = segments.size();
97  segments = m_ambiSolver->resolveAmbiguity(*gctx, std::move(segments));
98  if (nBeforeAmbi != segments.size()) {
99  drawFinalReco("post ambiguity");
100  }
101  } else if (m_visionTool.isEnabled() && segments.empty() &&
102  std::ranges::count_if(seed->getHitsInMax(),[this](const SpacePoint* hit){
103  return m_visionTool->isLabeled(*hit);
104  })) {
105  m_visionTool->visualizeSeed(ctx, *seed, "Failed fit");
106  }
107  allSegments.insert(allSegments.end(), std::make_move_iterator(segments.begin()),
108  std::make_move_iterator(segments.end()));
109  }
110  resolveAmbiguities(*gctx, allSegments);
111  writeSegments->insert(writeSegments->end(),
112  std::make_move_iterator(allSegments.begin()),
113  std::make_move_iterator(allSegments.end()));
114  ATH_MSG_VERBOSE("Found in total "<<writeSegments->size()<<" segments. ");
115  return StatusCode::SUCCESS;
116  }
117 
118  std::vector<std::unique_ptr<Segment>>
119  SegmentFittingAlg::fitSegmentSeed(const EventContext& ctx,
120  const ActsTrk::GeometryContext& gctx,
121  const SegmentSeed* patternSeed) const {
122 
123  const Amg::Transform3D& locToGlob{patternSeed->msSector()->localToGlobalTrans(gctx)};
124  std::vector<std::unique_ptr<Segment>> segments{};
125 
127  genCfg.hitPullCut = m_seedHitChi2;
128  genCfg.recalibSeedCircles = m_recalibSeed;
129  genCfg.calibrator = m_calibTool.get();
130  genCfg.startWithPattern = m_tryPatternPars;
131 
133  genCfg.busyLayerLimit = 2 + 2*(patternSeed->parameters()[toUnderlying(ParamDefs::theta)] > 50 * Gaudi::Units::deg);
135  if (m_visionTool.isEnabled()) {
136  PrimitiveVec seedLines{};
137  MdtSegmentSeedGenerator drawMe{name(), patternSeed, genCfg};
138  while(auto s = drawMe.nextSeed(ctx)) {
139  seedLines.push_back(drawLine(s->parameters, -Gaudi::Units::m, Gaudi::Units::m, kViolet));
140  }
141  seedLines.push_back(drawLabel(std::format("possible seeds: {:d}", drawMe.numGenerated()), 0.2, 0.85, 14));
142  m_visionTool->visualizeSeed(ctx, *patternSeed, "pattern", std::move(seedLines));
143  }
144 
145  MdtSegmentSeedGenerator seedGen{name(), patternSeed, std::move(genCfg)};
146  ATH_MSG_VERBOSE("fitSegmentHits() - Start segment seed search");
147  while (auto seed = seedGen.nextSeed(ctx)) {
148  auto segment = m_fitter->fitSegment(ctx, patternSeed, seed->parameters,
149  locToGlob, std::move(seed->measurements));
150  if (segment) {
151  segments.push_back(std::move(segment));
152  }
153  }
154  ATH_MSG_VERBOSE("fitSegmentHits() - In total "<<segments.size()<<" segment were constructed ");
155  return segments;
156  }
157 
158  void SegmentFittingAlg::resolveAmbiguities(const ActsTrk::GeometryContext& gctx,
159  std::vector<std::unique_ptr<Segment>>& segmentCandidates) const {
160  if (segmentCandidates.empty()) {
161  return;
162  }
163  using SegmentVec = std::vector<std::unique_ptr<Segment>>;
164  ATH_MSG_VERBOSE("Resolve ambiguities amongst "<<segmentCandidates.size()<<" segment candidates. ");
165  std::unordered_map<const MuonGMR4::SpectrometerSector*, SegmentVec> candidatesPerChamber{};
166 
167  for (std::unique_ptr<Segment>& sortMe : segmentCandidates) {
168  const MuonGMR4::SpectrometerSector* chamb = sortMe->msSector();
169  candidatesPerChamber[chamb].push_back(std::move(sortMe));
170  }
171  segmentCandidates.clear();
172  for (auto& [chamber, resolveMe] : candidatesPerChamber) {
173  SegmentVec resolvedSegments = m_ambiSolver->resolveAmbiguity(gctx, std::move(resolveMe));
174  segmentCandidates.insert(segmentCandidates.end(),
175  std::make_move_iterator(resolvedSegments.begin()),
176  std::make_move_iterator(resolvedSegments.end()));
177  }
178  }
179 }
MuonR4::PrimitiveVec
MuonValR4::IPatternVisualizationTool::PrimitiveVec PrimitiveVec
Definition: SegmentFittingAlg.cxx:24
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
MuonGMR4::SpectrometerSector
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
Definition: SpectrometerSector.h:40
vtune_athena.format
format
Definition: vtune_athena.py:14
calibdata.chamber
chamber
Definition: calibdata.py:31
VisualizationHelpers.h
MuonGMR4::SpectrometerSector::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
Definition: SpectrometerSector.cxx:75
initialize
void initialize()
Definition: run_EoverP.cxx:894
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:75
MuonR4::SegmentFit::SegmentAmbiSolver::Config
Definition: SegmentAmbiSolver.h:17
SegmentFittingAlg.h
deg
#define deg
Definition: SbPolyhedron.cxx:17
MuonR4::SegmentFit::SegmentVec
SegmentAmbiSolver::SegmentVec SegmentVec
Definition: SegmentAmbiSolver.cxx:8
MuonR4::SegmentFit::MdtSegmentSeedGenerator
Helper class to generate valid seeds for the segment fit.
Definition: MdtSegmentSeedGenerator.h:27
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
MuonR4::SegmentFittingAlg::Parameters
SegmentFit::Parameters Parameters
Definition: SegmentFittingAlg.h:41
MuonR4::SegmentFit::SegmentLineFitter::Config
Full configuration object.
Definition: SegmentLineFitter.h:72
MuonR4::SegmentFit::MdtSegmentSeedGenerator::Config::hitPullCut
double hitPullCut
Upper cut on the hit chi2 w.r.t.
Definition: MdtSegmentSeedGenerator.h:38
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
MuonValR4::drawLabel
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const unsigned int fontSize=18)
Create a TLatex label,.
Definition: VisualizationHelpers.cxx:32
LArG4FSStartPointFilterLegacy.execute
execute
Definition: LArG4FSStartPointFilterLegacy.py:20
MuonR4::Segment::MeasType
std::unique_ptr< CalibratedSpacePoint > MeasType
Calibrated space point type.
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonPatternEvent/MuonPatternEvent/Segment.h:23
MdtSegmentSeedGenerator.h
SpacePointPerLayerSplitter.h
Acts
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/xAODMuonPrepData/UtilFunctions.h: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
MuonR4::SegmentFit::MdtSegmentSeedGenerator::Config
Configuration switches of the module
Definition: MdtSegmentSeedGenerator.h:32
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
MuonSimHitContainer.h
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
ActsTrk::GeometryContext
Definition: GeometryContext.h:28
MuonR4::SegmentFit::SegmentLineFitter::ConfigSwitches::calibrator
const ISpacePointCalibrator * calibrator
Pointer to the calibrator.
Definition: SegmentLineFitter.h:51
DataVector
Derived DataVector<T>.
Definition: DataVector.h:795
MdtDriftCircle.h
beamspotman.dir
string dir
Definition: beamspotman.py:619
MuonR4::SpacePoint
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
Definition: MuonSpectrometer/MuonPhaseII/Event/MuonSpacePoint/MuonSpacePoint/SpacePoint.h:24
MuonValR4
Lightweight algorithm to read xAOD MDT sim hits and (fast-digitised) drift circles from SG and fill a...
Definition: IPatternVisualizationTool.h:23
MuonValR4::IPatternVisualizationTool::PrimitiveVec
std::vector< PrimitivePtr > PrimitiveVec
Definition: IPatternVisualizationTool.h:31
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
WriteCaloSwCorrections.cfg
cfg
Definition: WriteCaloSwCorrections.py:23
python.LumiBlobConversion.pos
pos
Definition: LumiBlobConversion.py:16
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:73
GeoPrimitivesHelpers.h
MuonR4::SegmentSeed
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Definition: SegmentSeed.h:14
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
MuonR4::SegmentSeed::parameters
const Parameters & parameters() const
Returns the parameter array.
Definition: SegmentSeed.cxx:46
MuonR4::SegmentFit::localSegmentPars
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
Definition: SegmentFitterEventData.cxx:42
drawLine
void drawLine(std::ostream &os)
Definition: PrintMC.cxx:16
xAOD::UncalibMeasType::MdtDriftCircleType
@ MdtDriftCircleType
MuonR4::SegmentSeed::msSector
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated chamber.
Definition: SegmentSeed.cxx:50
python.SystemOfUnits.m
float m
Definition: SystemOfUnits.py:106