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
15
16#include <ActsInterop/Logger.h>
19
20
21#include <format>
22
25
26
27namespace MuonR4::SegmentFit{
28 using namespace Acts;
29 using namespace Acts::UnitLiterals;
30
34
35 namespace {
38 bool isGoodHit(const MuonR4::CalibratedSpacePoint& hit) {
40 return hit.fitState() == Valid;
41 }
43 bool isPrecisionHit(const MuonR4::CalibratedSpacePoint& hit) {
44 using enum xAOD::UncalibMeasType;
45 return isGoodHit(hit) && (
47 hit.type() == MdtDriftCircleType || hit.type() == MMClusterType ||
49 (hit.type() == sTgcStripType &&
50 static_cast<const xAOD::sTgcMeasurement*>(hit.spacePoint()->primaryMeasurement())->channelType() ==
52 );
53 }
56 inline unsigned countPrecHits(const HitVec_t& hits) {
57 return std::ranges::count_if(hits, [](const Hit_t& hit){
58 return isPrecisionHit(*hit);
59 });
60 }
62 inline unsigned countPhiHits(const HitVec_t& hits) {
63 return std::ranges::count_if(hits, [](const Hit_t& hit){
64 return isGoodHit(*hit) && hit->measuresPhi();
65 });
66 }
70 inline void removeBeamSpot(HitVec_t& hits){
71 hits.erase(std::remove_if(hits.begin(), hits.end(),
72 [](const Hit_t& a){
73 return a->type() == xAOD::UncalibMeasType::Other;
74 }), hits.end());
75 }
77 HitVec_t copy(const HitVec_t& hits) {
78 HitVec_t copied{};
79 copied.reserve(hits.size());
80 std::ranges::transform(hits, std::back_inserter(copied),
81 [](const Hit_t& hit) {
82 return std::make_unique<CalibratedSpacePoint>(*hit);
83 });
84 return copied;
85 }
86 Result_t copy(const Result_t& toCopy) {
87 Result_t toRet{};
88 using FitPars_t = SegmentLineFitter::FitPars_t;
89 static_cast<FitPars_t&>(toRet) = toCopy;
90 toRet.measurements = copy(toCopy.measurements);
91 return toRet;
92 }
93 }
94 SegmentLineFitter::Config::RangeArray
96 RangeArray rng{};
97 constexpr double spatRang = 10._m;
98 constexpr double timeTange = 25._ns;
99 using enum ParamDefs;
100 rng[toUnderlying(y0)] = std::array{-spatRang, spatRang};
101 rng[toUnderlying(x0)] = std::array{-spatRang, spatRang};
102 rng[toUnderlying(phi)] = std::array{-179._degree, 179._degree};
103 rng[toUnderlying(theta)] = std::array{-85._degree, 85._degree};
104 rng[toUnderlying(t0)] = std::array{-timeTange, timeTange};
105 return rng;
106 }
108 AthMessaging{name},
110 m_cfg{config} {
111 m_goodHitSel.connect<isGoodHit>();
112 }
113 Result_t SegmentLineFitter::callLineFit(const Acts::CalibrationContext& cctx,
114 const Parameters& startPars,
115 const Amg::Transform3D& localToGlobal,
116 HitVec_t&& calibHits) const {
118 if (m_cfg.doBeamSpot && countPhiHits(calibHits) > 0) {
119 const Amg::Transform3D globToLoc{localToGlobal.inverse()};
120 Amg::Vector3D beamSpot{globToLoc.translation()};
121 Amg::Vector3D beamLine{globToLoc.linear().col(2)};
122 SpacePoint::Cov_t covariance{};
123 covariance[toUnderlying(AxisDefs::etaCov)] = square(m_cfg.beamSpotRadius);
124 covariance[toUnderlying(AxisDefs::phiCov)] = square(m_cfg.beamSpotLength);
126 auto beamSpotSP = std::make_unique<CalibratedSpacePoint>(nullptr, std::move(beamSpot));
127 beamSpotSP->setBeamDirection(std::move(beamLine));
128 beamSpotSP->setCovariance(std::move(covariance));
129 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Beam spot constraint "
130 <<Amg::toString(beamSpotSP->localPosition())<<", "<<beamSpotSP->covariance());
131 calibHits.push_back(std::move(beamSpotSP));
132 }
133
134 if (msgLvl(MSG::VERBOSE)) {
135 const auto [pos, dir] = makeLine(startPars);
136 std::stringstream hitStream{};
137 for (const Hit_t& hit : calibHits) {
138 hitStream<<" **** "<< (*hit)<<", pull: "
139 <<std::sqrt(SeedingAux::chi2Term(pos, dir, *hit)) <<std::endl;
140 }
141 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Start segment fit with parameters "
142 <<toString(startPars) <<", plane location: "<<Amg::toString(localToGlobal)<<std::endl
143 <<hitStream.str());
144 }
145 FitOpts_t fitOpts{};
147 fitOpts.calibContext = cctx;
148 fitOpts.calibrator = m_cfg.calibrator;
149 fitOpts.selector = m_goodHitSel;
150 //check the degrees of freedom before try the fit
151 const auto dOF = m_fitter.countDoF(calibHits, fitOpts.selector);
152 if((dOF.bending + dOF.nonBending) < startPars.size()){
153 return result;
154 }
155 fitOpts.measurements = std::move(calibHits);
156 fitOpts.localToGlobal = localToGlobal;
157 fitOpts.startParameters = startPars;
159 fitOpts.startParameters[toUnderlying(ParamDefs::t0)] = ActsTrk::timeToActs(fitOpts.startParameters[toUnderlying(ParamDefs::t0)]);
161 result = m_fitter.fit(std::move(fitOpts));
163 result.parameters[toUnderlying(ParamDefs::t0)] = ActsTrk::timeToAthena(result.parameters[toUnderlying(ParamDefs::t0)]);
165 return result;
166 }
167 std::unique_ptr<Segment>
168 SegmentLineFitter::fitSegment(const EventContext& ctx,
169 const SegmentSeed* parent,
170 const Parameters& startPars,
171 const Amg::Transform3D& localToGlobal,
172 HitVec_t&& calibHits) const {
173
174 const Acts::CalibrationContext cctx = ActsTrk::getCalibrationContext(ctx);
175 if (m_cfg.visionTool) {
176 Result_t preFit{};
177 preFit.parameters = startPars;
178 preFit.measurements = copy(calibHits);
179 auto seedCopy = convertToSegment(localToGlobal, parent, std::move(preFit));
180 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Prefit");
181 }
182 Result_t segFit = callLineFit(cctx, startPars, localToGlobal, std::move(calibHits));
183 if (m_cfg.visionTool && segFit.converged) {
184 auto seedCopy = convertToSegment(localToGlobal, parent, copy(segFit));
185 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Intermediate fit");
186 }
187 if (!removeOutliers(cctx, *parent, localToGlobal, segFit)) {
188 return nullptr;
189 }
190 if (!plugHoles(cctx, *parent, localToGlobal, segFit)) {
191 return nullptr;
192 }
193 auto finalSeg = convertToSegment(localToGlobal, parent, std::move(segFit));
194 if (m_cfg.visionTool) {
195 m_cfg.visionTool->visualizeSegment(ctx, *finalSeg, "Final fit");
196 }
197 return finalSeg;
198 }
199 std::unique_ptr<Segment>
201 const SegmentSeed* patternSeed,
202 Result_t&& data) const {
203 const auto [locPos, locDir] = makeLine(data.parameters);
204 Amg::Vector3D globPos = locToGlob * locPos;
205 Amg::Vector3D globDir = locToGlob.linear()* locDir;
206
207 std::ranges::sort(data.measurements, [](const Hit_t& a, const Hit_t& b){
208 return a->localPosition().z() < b->localPosition().z();
209 });
210 if (msgLvl(MSG::VERBOSE)) {
211 std::stringstream sstr{};
212 for (const Hit_t& h : data.measurements) {
213 sstr<<" **** "<<(*h)<<", pull: "
214 <<std::sqrt(SeedingAux::chi2Term(locPos, locDir, *h))<<std::endl;
215 }
216 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Create new segment "
217 <<toString(data.parameters)<<" in "<<patternSeed->msSector()->identString()<<"built from:\n"<<sstr.str());
218 }
219
220 auto finalSeg = std::make_unique<Segment>(std::move(globPos), std::move(globDir),
221 patternSeed, std::move(data.measurements),
222 data.chi2, data.nDoF);
223 finalSeg->setCallsToConverge(data.nIter);
224 finalSeg->setParUncertainties(std::move(data.covariance));
225 if (m_fitter.config().fitT0) {
226 finalSeg->setSegmentT0(data.parameters[toUnderlying(ParamDefs::t0)]);
227 }
228 return finalSeg;
229 }
230
231 bool SegmentLineFitter::removeOutliers(const Acts::CalibrationContext& cctx,
232 const SegmentSeed& seed,
233 const Amg::Transform3D& localToGlobal,
234 Result_t& fitResult) const {
235
236
237 if (countPrecHits(fitResult.measurements) < m_cfg.nPrecHitCut || fitResult.nDoF == 0
238 || fitResult.nIter > m_fitter.config().maxIter) {
239 for(const auto& meas : fitResult.measurements){
240 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Measurement from fitresult is" << (*meas));
241 }
242 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__
243 <<": No degree of freedom available. What shall be removed?!. nDoF: "
244 <<fitResult.nDoF<<", n-meas: "<<countPrecHits(fitResult.measurements));
245 return false;
246 }
247 if (fitResult.converged && fitResult.chi2 / std::max(fitResult.nDoF, 1ul) < m_cfg.outlierRemovalCut) {
248 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": The segment "<<toString(fitResult.parameters)
249 <<" is already of good quality "<<fitResult.chi2 / std::max(fitResult.nDoF, 1ul)
250 <<". Don't remove outliers");
251 return true;
252 }
253 if (fitResult.nDoF == 0u){
254 return false;
255 }
256 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Segment "
257 <<toString(fitResult.parameters)<<" is of badish quality. Remove worst hit");
258
261 if (m_cfg.doBeamSpot) {
262 removeBeamSpot(fitResult.measurements);
263 }
264 const auto [segPos, segDir] = makeLine(fitResult.parameters);
266 std::ranges::sort(fitResult.measurements,
267 [&segPos, &segDir](const HitVec_t::value_type& a, const HitVec_t::value_type& b){
268 const double chiSqA = isGoodHit(*a) ? SeedingAux::chi2Term(segPos, segDir, *a) : 0.;
269 const double chiSqB = isGoodHit(*b) ? SeedingAux::chi2Term(segPos, segDir, *b) : 0.;
270 return chiSqA < chiSqB;
271 });
272 fitResult.measurements.back()->setFitState(HitState::Outlier);
273
275 Result_t newAttempt = callLineFit(cctx, fitResult.parameters,
276 localToGlobal, std::move(fitResult.measurements));
277 if (newAttempt.converged) {
278 newAttempt.nIter+=fitResult.nIter;
279 fitResult = std::move(newAttempt);
280 if (m_cfg.visionTool) {
281 const EventContext& ctx{*cctx.get<const EventContext*>()};
282 auto seedCopy = convertToSegment(localToGlobal, &seed, copy(fitResult));
283 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Bad fit recovery");
284 }
285 } else {
286 fitResult.nIter+=newAttempt.nIter;
287 fitResult.measurements = std::move(newAttempt.measurements);
288 }
289 return removeOutliers(cctx, seed, localToGlobal, fitResult);
290 }
291
293 auto [segPos, segDir] = makeLine(candidate.parameters);
294 cleanStripLayers(segPos, segDir, candidate.measurements);
295 candidate.measurements.erase(std::remove_if(candidate.measurements.begin(),
296 candidate.measurements.end(),
297 [&](const HitVec_t::value_type& hit){
298 if (hit->fitState() == HitState::Valid) {
299 return false;
300 } else if (hit->fitState() == HitState::Duplicate) {
301 return true;
302 }
305 const double dist = Amg::lineDistance(segPos, segDir,
306 hit->localPosition(),
307 hit->sensorDirection());
308 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->spacePoint()->primaryMeasurement());
309 return dist >= dc->readoutElement()->innerTubeRadius();
310 }
311 return false;
312 }), candidate.measurements.end());
313 }
315 const Amg::Vector3D& lineDir,
316 HitVec_t& hits) const {
317 const SpacePointPerLayerSorter sorter{};
319 std::ranges::sort(hits, [&sorter, &linePos, &lineDir](const Hit_t&a ,const Hit_t& b){
320 if (a->isStraw() || b->isStraw()) {
321 return !a->isStraw();
322 }
323 if (a->type() == xAOD::UncalibMeasType::Other ||
324 b->type() == xAOD::UncalibMeasType::Other) {
325 return a->type() != xAOD::UncalibMeasType::Other;
326 }
327 const unsigned lay_a = sorter.sectorLayerNum(*a->spacePoint());
328 const unsigned lay_b = sorter.sectorLayerNum(*b->spacePoint());
329 if (lay_a != lay_b) {
330 return lay_a < lay_b;
331 }
332 return SeedingAux::chi2Term(linePos, lineDir, *a) <
333 SeedingAux::chi2Term(linePos, lineDir, *b);
334 });
336 for (HitVec_t::iterator itr = hits.begin(); itr != hits.end(); ++itr) {
337 const Hit_t& hit_a{*itr};
338 if (hit_a->isStraw()){
339 break;
340 }
341 if(hit_a->fitState() == HitState::Duplicate ||
342 hit_a->type() == xAOD::UncalibMeasType::Other) {
343 continue;
344 }
345 const unsigned lay_a = sorter.sectorLayerNum(*hit_a->spacePoint());
347 for (HitVec_t::iterator itr2 = itr + 1; itr2 != hits.end(); ++itr2) {
348 const Hit_t& hit_b{*itr2};
349 if (hit_b->type() == xAOD::UncalibMeasType::Other) {
350 continue;
351 }
352 if (lay_a != sorter.sectorLayerNum(*hit_b->spacePoint())) {
353 break;
354 }
356 if ( (hit_a->measuresEta() && hit_b->measuresEta()) ||
357 (hit_a->measuresPhi() && hit_b->measuresPhi())) {
358 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Reject "
359 <<m_cfg.idHelperSvc->toString(hit_b->spacePoint()->identify()) <<" in favour of "
360 <<m_cfg.idHelperSvc->toString(hit_a->spacePoint()->identify()));
361 hit_b->setFitState(HitState::Duplicate);
362 }
363 }
364 }
365 }
366 bool SegmentLineFitter::plugHoles(const Acts::CalibrationContext& cctx,
367 const SegmentSeed& seed,
368 const Amg::Transform3D& localToGlobal,
369 Result_t& toRecover) const {
371 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": segment "<<toString(toRecover.parameters)
372 <<", chi2: "<<toRecover.chi2 /std::max(toRecover.nDoF, 1ul)
373 <<", nDoF: "<<toRecover.nDoF);
375
376
377 std::unordered_set<const SpacePoint*> usedSpacePoints{};
378 for (auto& hit : toRecover.measurements) {
379 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": "<<(*hit)<<" is known");
380 usedSpacePoints.insert(hit->spacePoint());
381 }
383 const EventContext& ctx{*cctx.get<const EventContext*>()};
384
385 const double timeOff = toRecover.parameters[toUnderlying(ParamDefs::t0)];
386 HitVec_t candidateHits{};
387 bool hasCandidate{false};
388 const auto [locPos, locDir] = makeLine(toRecover.parameters);
389
391 for (const auto& hit : *seed.parentBucket()){
393 if (usedSpacePoints.count(hit.get())){
394 continue;
395 }
396 Hit_t calibHit{};
397 double pull{-1.};
398 if (hit->isStraw()) {
399 using namespace Acts::detail::LineHelper;
400 const double dist = signedDistance(locPos, locDir, hit->localPosition(), hit->sensorDirection());
401 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->primaryMeasurement());
402 // Check whether the tube is crossed by the hit
403 if (Acts::abs(dist) >= dc->readoutElement()->innerTubeRadius()) {
404 continue;
405 }
406 } else {
408 if (!hit->measuresEta() &&
409 std::abs(hit->sensorDirection().dot(hit->localPosition() -
410 SeedingAux::extrapolateToPlane(locPos,locDir, *hit))) >
411 std::sqrt(hit->covariance()[toUnderlying(AxisDefs::etaCov)])){
412 continue;
413 }
416 pull = std::sqrt(SeedingAux::chi2Term(locPos, locDir, *hit));
417 if (pull > 1.1 * m_cfg.recoveryPull) {
418 continue;
419 }
420 }
421 calibHit = m_cfg.calibrator->calibrate(ctx, hit.get(), locPos, locDir, timeOff);
422 pull = std::sqrt(SeedingAux::chi2Term(locPos, locDir, *calibHit));
423 if (pull <= m_cfg.recoveryPull) {
424 hasCandidate |= calibHit->fitState() == HitState::Valid;
425 } else {
426 calibHit->setFitState(HitState::Outlier);
427 }
428 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Candidate hit for recovery "
429 <<seed.msSector()->idHelperSvc()->toString(hit->identify())<<", pull: "<<pull);
430 candidateHits.push_back(std::move(calibHit));
431 }
433 if (!hasCandidate) {
434 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": No space point candidates for recovery were found");
435 toRecover.measurements.insert(toRecover.measurements.end(),
436 std::make_move_iterator(candidateHits.begin()),
437 std::make_move_iterator(candidateHits.end()));
438 eraseWrongHits(toRecover);
439 return toRecover.nDoF > 0;
440 }
441
442
443 HitVec_t copied = copy(toRecover.measurements);
444 HitVec_t copiedCandidates = copy(candidateHits);
446 if (m_cfg.doBeamSpot) {
447 removeBeamSpot(copied);
448 }
449
450 candidateHits.insert(candidateHits.end(),
451 std::make_move_iterator(copied.begin()),
452 std::make_move_iterator(copied.end()));
453
454 cleanStripLayers(locPos, locDir, candidateHits);
455 Result_t recovered = callLineFit(cctx, toRecover.parameters, localToGlobal,
456 std::move(candidateHits));
457 if (!recovered.converged) {
458 return false;
459 }
461 if (recovered.nDoF <= toRecover.nDoF) {
462 for (HitVec_t::value_type& hit : copiedCandidates) {
463 hit->setFitState(HitState::Outlier);
464 toRecover.measurements.push_back(std::move(hit));
465 }
466 eraseWrongHits(toRecover);
467 return true;
468 }
469 std::vector<const CalibratedSpacePoint*> stripOutliers{};
470 stripOutliers.reserve(toRecover.measurements.size());
471 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Before - chi2: "<<toRecover.chi2
472 <<", nDoF "<<toRecover.nDoF<<" <=> after recovery - chi2: "
473 <<recovered.chi2<<", nDoF: "<<recovered.nDoF);
474
475 double redChi2 = recovered.chi2 / std::max(recovered.nDoF, 1ul);
478 if (redChi2 < m_cfg.outlierRemovalCut ||
479 toRecover.nDoF == 0 || redChi2 < toRecover.chi2 / toRecover.nDoF) {
480 ATH_MSG_VERBOSE("Accept segment with recovered "<<(recovered.nDoF - toRecover.nDoF)<<" hits.");
481 recovered.nIter += toRecover.nIter;
482 toRecover = std::move(recovered);
485 unsigned recovLoop{0u};
486 while (++recovLoop <= m_cfg.nRecoveryLoops) {
487 copied = copy(toRecover.measurements);
488 if (m_cfg.doBeamSpot) {
489 removeBeamSpot(copied);
490 }
491 const auto [beforePos, beforeDir] = makeLine(toRecover.parameters);
492
493 for (HitVec_t::value_type& copyHit : copied) {
494 if (copyHit->fitState() != HitState::Outlier) {
495 continue;
496 }
497 if (std::sqrt(SeedingAux::chi2Term(beforePos, beforeDir, *copyHit)) < m_cfg.recoveryPull) {
498 copyHit->setFitState(HitState::Valid);
499 stripOutliers.push_back(copyHit.get());
500 }
501 }
502 // Nothing to recover
503 if (stripOutliers.empty()) {
504 break;
505 }
506 cleanStripLayers(beforePos, beforeDir, copied);
507 // Recovery turned out to be duplicates on the same layer
508 if (std::ranges::none_of(stripOutliers,[](const CalibratedSpacePoint* sp){
509 return sp->fitState() == HitState::Valid;
510 })) {
511 break;
512 }
513 stripOutliers.clear();
514 recovered = callLineFit(cctx, toRecover.parameters, localToGlobal, std::move(copied));
515 if (!recovered.converged) {
516 break;
517 }
518 if (recovered.nDoF <= toRecover.nDoF) {
519 break;
520 }
521 redChi2 = recovered.chi2 / std::max(recovered.nDoF, 1ul);
522 if (redChi2 < m_cfg.outlierRemovalCut || redChi2 < toRecover.chi2 / toRecover.nDoF) {
523 recovered.nIter += toRecover.nIter;
524 toRecover = std::move(recovered);
525 } else {
526 break;
527 }
528 }
529 } else{
530 for (HitVec_t::value_type& hit : copiedCandidates) {
531 hit->setFitState(HitState::Outlier);
532 toRecover.measurements.push_back(std::move(hit));
533 }
534 }
535 eraseWrongHits(toRecover);
536 return true;
537 }
539 if (std::ranges::any_of(result.measurements,[](const Hit_t& h){
540 return h->measuresPhi();
541 })) {
542 ATH_MSG_VERBOSE("The segment has phi measurements. No centering needed");
543 return;
544 }
545 double avgX{0.};
546 const double nHits = result.measurements.size();
547 std::ranges::for_each(result.measurements, [&avgX, nHits](const Hit_t& hit) {
548 return avgX += hit->localPosition().x() / nHits;
549 });
550 result.parameters[toUnderlying(ParamDefs::x0)] = avgX;
551 }
552
553
554}
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
if(febId1==febId2)
static const uint32_t nHits
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.
const SpacePoint * spacePoint() const
The pointer to the space point out of which this space point has been built.
xAOD::UncalibMeasType type() const
Returns the space point type.
State
State flag to distinguish different space point states.
State fitState() const
Returns the state of the calibrated space point.
void centerAlongWire(Result_t &fitResult) const
Moves the segment to the average x0 position, if the segment does not contain any measurement.
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.
bool removeOutliers(const Acts::CalibrationContext &cctx, const SegmentSeed &seed, const Amg::Transform3D &localToGlobal, Result_t &fitResult) const
Cleans the fitted segment from the most outlier hit and then attempts to refit the segment.
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.
std::vector< Hit_t > HitVec_t
Collection of space points.
SegmentLineFitter(const std::string &name, Config &&config)
Standard constructor.
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.
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
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.
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
UncalibMeasType
Define the type of the uncalibrated measurement.
sTgcMeasurement_v1 sTgcMeasurement
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