ATLAS Offline Software
Loading...
Searching...
No Matches
SegmentLineFitter.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// Compile this file assuming that FP operations may trap.
6// Prevents spurious FPEs in the clang build.
9
12
16
17#include <ActsInterop/Logger.h>
20
21
22#include <format>
23
26
27
28namespace MuonR4::SegmentFit{
29 using namespace Acts;
30 using namespace Acts::UnitLiterals;
31
35
36 namespace {
39 inline unsigned countPrecHits(const HitVec_t& hits) {
40 return std::ranges::count_if(hits, [](const Hit_t& hit){
41 return isPrecisionHit(*hit);
42 });
43 }
45 inline unsigned countPhiHits(const HitVec_t& hits) {
46 return std::ranges::count_if(hits, [](const Hit_t& hit){
47 return isGoodHit(*hit) && hit->measuresPhi();
48 });
49 }
53 inline void removeBeamSpot(HitVec_t& hits){
54 hits.erase(std::remove_if(hits.begin(), hits.end(),
55 [](const Hit_t& a){
56 return a->type() == xAOD::UncalibMeasType::Other;
57 }), hits.end());
58 }
60 HitVec_t copy(const HitVec_t& hits) {
61 HitVec_t copied{};
62 copied.reserve(hits.size());
63 std::ranges::transform(hits, std::back_inserter(copied),
64 [](const Hit_t& hit) {
65 return std::make_unique<CalibratedSpacePoint>(*hit);
66 });
67 return copied;
68 }
69 Result_t copy(const Result_t& toCopy) {
70 Result_t toRet{};
71 using FitPars_t = SegmentLineFitter::FitPars_t;
72 static_cast<FitPars_t&>(toRet) = toCopy;
73 toRet.measurements = copy(toCopy.measurements);
74 return toRet;
75 }
76 }
77 SegmentLineFitter::Config::RangeArray
79 RangeArray rng{};
80 constexpr double spatRang = 10._m;
81 constexpr double timeTange = 50._ns;
82 using enum ParamDefs;
83 rng[toUnderlying(y0)] = std::array{-spatRang, spatRang};
84 rng[toUnderlying(x0)] = std::array{-spatRang, spatRang};
85 rng[toUnderlying(phi)] = std::array{-179._degree, 179._degree};
86 rng[toUnderlying(theta)] = std::array{0._degree, 175._degree};
87 rng[toUnderlying(t0)] = std::array{-timeTange, timeTange};
88 return rng;
89 }
90 SegmentLineFitter::SegmentLineFitter(const std::string& name, Config&& config):
91 AthMessaging{name},
92 m_fitter{config, makeActsAthenaLogger(this, name)},
93 m_cfg{config} {
94 m_goodHitSel.connect<isGoodHit>();
95 }
96 Result_t SegmentLineFitter::callLineFit(const Acts::CalibrationContext& cctx,
97 const Parameters& startPars,
98 const Amg::Transform3D& localToGlobal,
99 HitVec_t&& calibHits) const {
101 if (m_cfg.doBeamSpot && countPhiHits(calibHits) > 0) {
102 const Amg::Transform3D globToLoc{localToGlobal.inverse()};
103 Amg::Vector3D beamSpot{globToLoc.translation()};
104 Amg::Vector3D beamLine{globToLoc.linear().col(2)};
105 SpacePoint::Cov_t covariance{};
106 covariance[toUnderlying(AxisDefs::etaCov)] = square(m_cfg.beamSpotRadius);
107 covariance[toUnderlying(AxisDefs::phiCov)] = square(m_cfg.beamSpotLength);
109 auto beamSpotSP = std::make_unique<CalibratedSpacePoint>(nullptr, std::move(beamSpot));
110 beamSpotSP->setBeamDirection(std::move(beamLine));
111 beamSpotSP->setCovariance(std::move(covariance));
112 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Beam spot constraint "
113 <<Amg::toString(beamSpotSP->localPosition())<<", "<<beamSpotSP->covariance());
114 calibHits.push_back(std::move(beamSpotSP));
115 }
116
117 if (msgLvl(MSG::VERBOSE)) {
118 const auto [pos, dir] = makeLine(startPars);
119 std::stringstream hitStream{};
120 for (const Hit_t& hit : calibHits) {
121 hitStream<<" **** "<< (*hit)<<", pull: "
122 <<std::sqrt(SeedingAux::chi2Term(pos, dir, *hit)) <<std::endl;
123 }
124 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Start segment fit with parameters "
125 <<toString(startPars) <<", plane location: "<<Amg::toString(localToGlobal)<<std::endl
126 <<hitStream.str());
127 }
128 FitOpts_t fitOpts{};
129 Result_t result{};
130 fitOpts.calibContext = cctx;
131 fitOpts.calibrator = m_cfg.calibrator;
132 fitOpts.selector = m_goodHitSel;
133 //check the degrees of freedom before try the fit
134 const auto dOF = m_fitter.countDoF(calibHits, fitOpts.selector);
135 if((dOF.bending + dOF.nonBending) < m_fitter.config().parsToUse.size()){
136 return result;
137 }
138 fitOpts.measurements = std::move(calibHits);
139 fitOpts.localToGlobal = localToGlobal;
140 fitOpts.startParameters = startPars;
142 constexpr auto t0idx = toUnderlying(ParamDefs::t0);
143 fitOpts.startParameters[t0idx] = ActsTrk::timeToActs(fitOpts.startParameters[t0idx]);
145 result = m_fitter.fit(std::move(fitOpts));
147 if (m_fitter.config().fitT0){
148 result.parameters[t0idx] = ActsTrk::timeToAthena(result.parameters[t0idx]);
149 result.covariance(t0idx, t0idx) = Acts::square(ActsTrk::timeToAthena(1.)) * result.covariance(t0idx, t0idx);
150 for (ParamDefs p : {ParamDefs::x0, ParamDefs::y0, ParamDefs::phi, ParamDefs::theta}) {
151 auto pidx = toUnderlying(p);
152 result.covariance(t0idx, pidx) = ActsTrk::timeToAthena(result.covariance(t0idx, pidx));
153 result.covariance(pidx, t0idx) = ActsTrk::timeToAthena(result.covariance(pidx, t0idx));
154 }
155 }
156 return result;
157 }
158 std::unique_ptr<Segment>
159 SegmentLineFitter::fitSegment(const EventContext& ctx,
160 const SegmentSeed* parent,
161 const Parameters& startPars,
162 const Amg::Transform3D& localToGlobal,
163 HitVec_t&& calibHits) const {
164
165 const Acts::CalibrationContext cctx = ActsTrk::getCalibrationContext(ctx);
166 if (m_cfg.visionTool) {
167 Result_t preFit{};
168 preFit.parameters = startPars;
169 preFit.measurements = copy(calibHits);
170 auto seedCopy = convertToSegment(localToGlobal, parent, std::move(preFit));
171 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Prefit");
172 }
173 Result_t segFit = callLineFit(cctx, startPars, localToGlobal, std::move(calibHits));
174 if (m_cfg.visionTool && segFit.converged) {
175 auto seedCopy = convertToSegment(localToGlobal, parent, copy(segFit));
176 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Intermediate fit");
177 }
178 if (!removeOutliers(cctx, *parent, localToGlobal,
179 segFit.converged? segFit.parameters : startPars,
180 segFit)) {
181 return nullptr;
182 }
183 if (!plugHoles(cctx, *parent, localToGlobal, segFit)) {
184 return nullptr;
185 }
186 auto finalSeg = convertToSegment(localToGlobal, parent, std::move(segFit));
187 if (m_cfg.visionTool) {
188 m_cfg.visionTool->visualizeSegment(ctx, *finalSeg, "Final fit");
189 }
190 return finalSeg;
191 }
192 std::unique_ptr<Segment>
194 const SegmentSeed* patternSeed,
195 Result_t&& data) const {
196 const auto [locPos, locDir] = makeLine(data.parameters);
197 Amg::Vector3D globPos = locToGlob * locPos;
198 Amg::Vector3D globDir = locToGlob.linear()* locDir;
199
200 std::ranges::sort(data.measurements, [](const Hit_t& a, const Hit_t& b){
201 return a->localPosition().z() < b->localPosition().z();
202 });
203 if (msgLvl(MSG::VERBOSE)) {
204 std::stringstream sstr{};
205 for (const Hit_t& h : data.measurements) {
206 sstr<<" **** "<<(*h)<<", pull: "
207 <<std::sqrt(SeedingAux::chi2Term(locPos, locDir, *h))<<std::endl;
208 }
209 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Create new segment "
210 <<toString(data.parameters)<<" in "<<patternSeed->msSector()->identString()<<"built from:\n"<<sstr.str());
211 }
212
213 auto finalSeg = std::make_unique<Segment>(std::move(globPos), std::move(globDir),
214 patternSeed, std::move(data.measurements),
215 data.chi2, data.nDoF);
216 finalSeg->setCallsToConverge(data.nIter);
217 finalSeg->setParUncertainties(std::move(data.covariance));
218 if (m_fitter.config().fitT0) {
219 finalSeg->setSegmentT0(data.parameters[toUnderlying(ParamDefs::t0)]);
220 }
221 return finalSeg;
222 }
223
224 bool SegmentLineFitter::removeOutliers(const Acts::CalibrationContext& cctx,
225 const SegmentSeed& seed,
226 const Amg::Transform3D& localToGlobal,
227 const LinePar_t& startPars,
228 Result_t& fitResult) const {
229
230
231 if (countPrecHits(fitResult.measurements) < m_cfg.nPrecHitCut || fitResult.nDoF == 0
232 || fitResult.nIter > m_fitter.config().maxIter) {
233 for(const auto& meas : fitResult.measurements){
234 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Measurement from fitresult is" << (*meas));
235 }
236 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__
237 <<": No degree of freedom available. What shall be removed?!. nDoF: "
238 <<fitResult.nDoF<<", n-meas: "<<countPrecHits(fitResult.measurements));
239 return false;
240 }
241 if (fitResult.converged && fitResult.chi2 / std::max(fitResult.nDoF, 1ul) < m_cfg.outlierRemovalCut) {
242 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": The segment "<<toString(fitResult.parameters)
243 <<" is already of good quality "<<fitResult.chi2 / std::max(fitResult.nDoF, 1ul)
244 <<". Don't remove outliers");
245 return true;
246 }
247 if (fitResult.nDoF == 0u){
248 return false;
249 }
250 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Segment "
251 <<toString(fitResult.parameters)<<" is of badish quality. Remove worst hit");
252
255 if (m_cfg.doBeamSpot) {
256 removeBeamSpot(fitResult.measurements);
257 }
258 const auto [segPos, segDir] = makeLine(fitResult.parameters);
260 std::ranges::sort(fitResult.measurements,
261 [&segPos, &segDir](const HitVec_t::value_type& a, const HitVec_t::value_type& b){
262 const double chiSqA = isGoodHit(*a) ? SeedingAux::chi2Term(segPos, segDir, *a) : 0.;
263 const double chiSqB = isGoodHit(*b) ? SeedingAux::chi2Term(segPos, segDir, *b) : 0.;
264 return chiSqA < chiSqB;
265 });
266 fitResult.measurements.back()->setFitState(HitState::Outlier);
267
269 Result_t newAttempt = callLineFit(cctx, startPars, localToGlobal,
270 std::move(fitResult.measurements));
271 if (newAttempt.converged) {
272 newAttempt.nIter+=fitResult.nIter;
273 fitResult = std::move(newAttempt);
274 if (m_cfg.visionTool) {
275 const EventContext& ctx{*cctx.get<const EventContext*>()};
276 auto seedCopy = convertToSegment(localToGlobal, &seed, copy(fitResult));
277 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Bad fit recovery");
278 }
279 } else {
280 fitResult.nIter+=newAttempt.nIter;
281 fitResult.measurements = std::move(newAttempt.measurements);
282 }
283 return removeOutliers(cctx, seed, localToGlobal,
284 fitResult.converged ? fitResult.parameters : startPars,
285 fitResult);
286 }
287
289 auto [segPos, segDir] = makeLine(candidate.parameters);
290 cleanStripLayers(segPos, segDir, candidate.measurements);
291 candidate.measurements.erase(std::remove_if(candidate.measurements.begin(),
292 candidate.measurements.end(),
293 [&](const HitVec_t::value_type& hit){
294 if (hit->fitState() == HitState::Valid) {
295 return false;
296 } else if (hit->fitState() == HitState::Duplicate) {
297 return true;
298 }
301 const double dist = Amg::lineDistance(segPos, segDir,
302 hit->localPosition(),
303 hit->sensorDirection());
304 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->spacePoint()->primaryMeasurement());
305 return dist >= dc->readoutElement()->innerTubeRadius();
306 }
307 return false;
308 }), candidate.measurements.end());
309 }
311 const Amg::Vector3D& lineDir,
312 HitVec_t& hits) const {
313 const SpacePointPerLayerSorter sorter{};
315 std::ranges::sort(hits, [&sorter, &linePos, &lineDir](const Hit_t&a ,const Hit_t& b){
316 if (a->isStraw() || b->isStraw()) {
317 return !a->isStraw();
318 }
319 if (a->type() == xAOD::UncalibMeasType::Other ||
320 b->type() == xAOD::UncalibMeasType::Other) {
321 return a->type() != xAOD::UncalibMeasType::Other;
322 }
323 const unsigned lay_a = sorter.sectorLayerNum(*a->spacePoint());
324 const unsigned lay_b = sorter.sectorLayerNum(*b->spacePoint());
325 if (lay_a != lay_b) {
326 return lay_a < lay_b;
327 }
328 return SeedingAux::chi2Term(linePos, lineDir, *a) <
329 SeedingAux::chi2Term(linePos, lineDir, *b);
330 });
332 for (HitVec_t::iterator itr = hits.begin(); itr != hits.end(); ++itr) {
333 const Hit_t& hit_a{*itr};
334 if (hit_a->isStraw()){
335 break;
336 }
337 if(hit_a->fitState() == HitState::Duplicate ||
338 hit_a->type() == xAOD::UncalibMeasType::Other) {
339 continue;
340 }
341 const unsigned lay_a = sorter.sectorLayerNum(*hit_a->spacePoint());
343 for (HitVec_t::iterator itr2 = itr + 1; itr2 != hits.end(); ++itr2) {
344 const Hit_t& hit_b{*itr2};
345 if (hit_b->type() == xAOD::UncalibMeasType::Other) {
346 continue;
347 }
348 if (lay_a != sorter.sectorLayerNum(*hit_b->spacePoint())) {
349 break;
350 }
352 if ( (hit_a->measuresEta() && hit_b->measuresEta()) ||
353 (hit_a->measuresPhi() && hit_b->measuresPhi())) {
354 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Reject "
355 <<m_cfg.idHelperSvc->toString(hit_b->spacePoint()->identify()) <<" in favour of "
356 <<m_cfg.idHelperSvc->toString(hit_a->spacePoint()->identify()));
357 hit_b->setFitState(HitState::Duplicate);
358 }
359 }
360 }
361 }
362 bool SegmentLineFitter::plugHoles(const Acts::CalibrationContext& cctx,
363 const SegmentSeed& seed,
364 const Amg::Transform3D& localToGlobal,
365 Result_t& toRecover) const {
367 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": segment "<<toString(toRecover.parameters)
368 <<", chi2: "<<toRecover.chi2 /std::max(toRecover.nDoF, 1ul)
369 <<", nDoF: "<<toRecover.nDoF);
371
372
373 std::unordered_set<const SpacePoint*> usedSpacePoints{};
374 for (auto& hit : toRecover.measurements) {
375 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": "<<(*hit)<<" is known");
376 usedSpacePoints.insert(hit->spacePoint());
377 }
379 const EventContext& ctx{*cctx.get<const EventContext*>()};
380
381 const double timeOff = toRecover.parameters[toUnderlying(ParamDefs::t0)];
382 HitVec_t candidateHits{};
383 bool hasCandidate{false};
384 const auto [locPos, locDir] = makeLine(toRecover.parameters);
385
387 for (const auto& hit : *seed.parentBucket()){
389 if (usedSpacePoints.count(hit.get())){
390 continue;
391 }
392 Hit_t calibHit{};
393 double pull{-1.};
394 if (hit->isStraw()) {
395 using namespace Acts::detail::LineHelper;
396 const double dist = signedDistance(locPos, locDir, hit->localPosition(), hit->sensorDirection());
397 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->primaryMeasurement());
398 // Check whether the tube is crossed by the hit
399 if (Acts::abs(dist) >= dc->readoutElement()->innerTubeRadius()) {
400 continue;
401 }
402 } else {
404 if (!hit->measuresEta() &&
405 std::abs(hit->sensorDirection().dot(hit->localPosition() -
406 SeedingAux::extrapolateToPlane(locPos,locDir, *hit))) >
407 std::sqrt(hit->covariance()[toUnderlying(AxisDefs::etaCov)])){
408 continue;
409 }
412 pull = std::sqrt(SeedingAux::chi2Term(locPos, locDir, *hit));
413 if (pull > 1.1 * m_cfg.recoveryPull) {
414 continue;
415 }
416 }
417 calibHit = m_cfg.calibrator->calibrate(ctx, hit.get(), locPos, locDir, ActsTrk::timeToActs(timeOff));
418 pull = std::sqrt(SeedingAux::chi2Term(locPos, locDir, *calibHit));
419 if (pull <= m_cfg.recoveryPull) {
420 hasCandidate |= calibHit->fitState() == HitState::Valid;
421 } else {
422 calibHit->setFitState(HitState::Outlier);
423 }
424 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Candidate hit for recovery "
425 <<seed.msSector()->idHelperSvc()->toString(hit->identify())<<", pull: "<<pull);
426 candidateHits.push_back(std::move(calibHit));
427 }
429 if (!hasCandidate) {
430 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": No space point candidates for recovery were found");
431 toRecover.measurements.insert(toRecover.measurements.end(),
432 std::make_move_iterator(candidateHits.begin()),
433 std::make_move_iterator(candidateHits.end()));
434 eraseWrongHits(toRecover);
435 return toRecover.nDoF > 0;
436 }
437
438
439 HitVec_t copied = copy(toRecover.measurements);
440 HitVec_t copiedCandidates = copy(candidateHits);
442 if (m_cfg.doBeamSpot) {
443 removeBeamSpot(copied);
444 }
445
446 candidateHits.insert(candidateHits.end(),
447 std::make_move_iterator(copied.begin()),
448 std::make_move_iterator(copied.end()));
449
450 cleanStripLayers(locPos, locDir, candidateHits);
451 Result_t recovered = callLineFit(cctx, toRecover.parameters, localToGlobal,
452 std::move(candidateHits));
453 if (!recovered.converged) {
454 return false;
455 }
457 if (recovered.nDoF <= toRecover.nDoF) {
458 for (HitVec_t::value_type& hit : copiedCandidates) {
459 hit->setFitState(HitState::Outlier);
460 toRecover.measurements.push_back(std::move(hit));
461 }
462 eraseWrongHits(toRecover);
463 return true;
464 }
465 std::vector<const CalibratedSpacePoint*> stripOutliers{};
466 stripOutliers.reserve(toRecover.measurements.size());
467 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Before - chi2: "<<toRecover.chi2
468 <<", nDoF "<<toRecover.nDoF<<" <=> after recovery - chi2: "
469 <<recovered.chi2<<", nDoF: "<<recovered.nDoF);
470
471 double redChi2 = recovered.chi2 / std::max(recovered.nDoF, 1ul);
474 if (redChi2 < m_cfg.outlierRemovalCut ||
475 toRecover.nDoF == 0 || redChi2 < toRecover.chi2 / toRecover.nDoF) {
476 ATH_MSG_VERBOSE("Accept segment with recovered "<<(recovered.nDoF - toRecover.nDoF)<<" hits.");
477 recovered.nIter += toRecover.nIter;
478 toRecover = std::move(recovered);
481 unsigned recovLoop{0u};
482 while (++recovLoop <= m_cfg.nRecoveryLoops) {
483 copied = copy(toRecover.measurements);
484 if (m_cfg.doBeamSpot) {
485 removeBeamSpot(copied);
486 }
487 const auto [beforePos, beforeDir] = makeLine(toRecover.parameters);
488
489 for (HitVec_t::value_type& copyHit : copied) {
490 if (copyHit->fitState() != HitState::Outlier) {
491 continue;
492 }
493 if (std::sqrt(SeedingAux::chi2Term(beforePos, beforeDir, *copyHit)) < m_cfg.recoveryPull) {
494 copyHit->setFitState(HitState::Valid);
495 stripOutliers.push_back(copyHit.get());
496 }
497 }
498 // Nothing to recover
499 if (stripOutliers.empty()) {
500 break;
501 }
502 cleanStripLayers(beforePos, beforeDir, copied);
503 // Recovery turned out to be duplicates on the same layer
504 if (std::ranges::none_of(stripOutliers,[](const CalibratedSpacePoint* sp){
505 return sp->fitState() == HitState::Valid;
506 })) {
507 break;
508 }
509 stripOutliers.clear();
510 recovered = callLineFit(cctx, toRecover.parameters, localToGlobal, std::move(copied));
511 if (!recovered.converged) {
512 break;
513 }
514 if (recovered.nDoF <= toRecover.nDoF) {
515 break;
516 }
517 redChi2 = recovered.chi2 / std::max(recovered.nDoF, 1ul);
518 if (redChi2 < m_cfg.outlierRemovalCut || redChi2 < toRecover.chi2 / toRecover.nDoF) {
519 recovered.nIter += toRecover.nIter;
520 toRecover = std::move(recovered);
521 } else {
522 break;
523 }
524 }
525 } else{
526 for (HitVec_t::value_type& hit : copiedCandidates) {
527 hit->setFitState(HitState::Outlier);
528 toRecover.measurements.push_back(std::move(hit));
529 }
530 }
531 eraseWrongHits(toRecover);
532 return true;
533 }
534
535}
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_MSG_VERBOSE(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sp
static Double_t a
static Double_t t0
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Header file for AthHistogramAlgorithm.
bool msgLvl(const MSG::Level lvl) const
Test the output level.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
The calibrated Space point is created during the calibration process.
bool plugHoles(const Acts::CalibrationContext &cctx, const SegmentSeed &seed, const Amg::Transform3D &localToGlobal, Result_t &toRecover) const
Recovery of missed hits.
std::unique_ptr< CalibratedSpacePoint > Hit_t
Abrivation of the space point type to use.
void cleanStripLayers(const Amg::Vector3D &linePos, const Amg::Vector3D &lineDir, HitVec_t &hits) const
Marks duplicate hits on a strip layer as outliers to avoid competing contributions from the same laye...
Selector_t m_goodHitSel
Selector to identify the valid hits.
Result_t callLineFit(const Acts::CalibrationContext &cctx, const Parameters &startPars, const Amg::Transform3D &localToGlobal, HitVec_t &&calibHits) const
Calls the underlying line fitter to determine the segment parameters.
ConfigSwitches m_cfg
Configuration switches of the ATLAS fitter implementation.
Fitter_t::FitResult< HitVec_t > Result_t
Abrivation of the fit result.
void eraseWrongHits(Result_t &candidate) const
Removes all hits from the segment which are obvious outliers.
std::unique_ptr< Segment > convertToSegment(const Amg::Transform3D &locToGlobTrf, const SegmentSeed *parentSeed, Result_t &&toConvert) const
Converts the fit result into a segment object.
Fitter_t::FitOptions< HitVec_t, ISpacePointCalibrator > FitOpts_t
Abrivation of the fit options.
Fitter_t::FitParameters FitPars_t
Abrivation of the fit parameters.
std::unique_ptr< Segment > fitSegment(const EventContext &ctx, const SegmentSeed *parent, const LinePar_t &startPars, const Amg::Transform3D &localToGlobal, HitVec_t &&calibHits) const
Fit a set of measurements to a straight segment line.
Fitter_t m_fitter
Actual implementation of the straight line fit.
Fitter_t::ParamVec_t LinePar_t
Abrivation of the fitted line parameters.
std::vector< Hit_t > HitVec_t
Collection of space points.
SegmentLineFitter(const std::string &name, Config &&config)
Standard constructor.
bool removeOutliers(const Acts::CalibrationContext &cctx, const SegmentSeed &seed, const Amg::Transform3D &localToGlobal, const LinePar_t &startPars, Result_t &fitResult) const
Cleans the fitted segment from the most outlier hit and then attempts to refit the segment.
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Definition SegmentSeed.h:14
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated chamber.
The SpacePointPerLayerSorter sort two given space points by their layer Identifier.
std::array< double, 3 > Cov_t
Abrivation of the covariance type.
constexpr double timeToAthena(const double actsT)
Converts a time unit from Acts to Athena units.
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...
constexpr double timeToActs(const double athenaT)
Converts a time unit from Athena to Acts units.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
SegmentLineFitter::Result_t Result_t
SegmentLineFitter::HitVec_t HitVec_t
SeedingAux::FitParIndex ParamDefs
Use the same parameter indices as used by the CompSpacePointAuxiliaries.
SegmentLineFitter::Hit_t Hit_t
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
Acts::Experimental::CompositeSpacePointLineFitter::ParamVec_t Parameters
std::string toString(const Parameters &pars)
Dumps the parameters into a string with labels in front of each number.
bool isPrecisionHit(const SpacePoint &hit)
Returns whether the uncalibrated spacepoint is a precision hit (Mdt, micromegas, stgc strips)
bool isGoodHit(const CalibratedSpacePoint &hit)
Returns whether the calibrated spacepoint is valid and therefore suitable to be used in the segment f...
DataModel_detail::iterator< DVL > remove_if(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end, Predicate pred)
Specialization of remove_if for DataVector/List.
MdtDriftCircle_v1 MdtDriftCircle
static RangeArray defaultRanges()
Function that returns a set of predefined ranges for testing.
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24