32 using namespace Acts::UnitLiterals;
40 constexpr double calcRedChi2(
const Result_t& result) {
41 return result.nDoF > 0ul ? result.chi2 / result.nDoF : result.chi2;
45 inline unsigned countPrecHits(
const HitVec_t& hits) {
46 return std::ranges::count_if(hits, [](
const Hit_t& hit){
51 inline unsigned countPhiHits(
const HitVec_t& hits) {
52 return std::ranges::count_if(hits, [](
const Hit_t& hit){
53 return isGoodHit(*hit) && hit->measuresPhi();
59 inline void removeBeamSpot(
HitVec_t& hits){
62 return a->type() == xAOD::UncalibMeasType::Other;
66 SegmentLineFitter::Config::RangeArray
69 constexpr double spatRang = 10._m;
70 constexpr double timeTange = 50._ns;
72 rng[toUnderlying(y0)] = std::array{-spatRang, spatRang};
73 rng[toUnderlying(x0)] = std::array{-spatRang, spatRang};
74 rng[toUnderlying(
phi)] = std::array{-179._degree, 179._degree};
75 rng[toUnderlying(
theta)] = std::array{0._degree, 175._degree};
76 rng[toUnderlying(
t0)] = std::array{-timeTange, timeTange};
91 bool appendsBS =
m_cfg.doBeamSpot && countPhiHits(calibHits) > 0;
96 if (
const std::size_t nPars =
m_fitter.config().parsToUse.size(); nPars > 0ul) {
98 if (dOF.bending + dOF.nonBending < nPars) {
102 if (dOF.nonBending == 0ul && nPars == 4ul){
103 bool foundU{
false}, foundV{
false};
104 for (
const HitVec_t::value_type& hit : calibHits) {
108 const auto* mmClust =
dynamic_cast<const xAOD::MMCluster*
>(hit->spacePoint()->primaryMeasurement());
109 assert(mmClust !=
nullptr);
110 const auto& design = mmClust->readoutElement()->stripLayer(mmClust->layerHash()).design();
111 if (!design.hasStereoAngle()) {
114 if (design.stereoAngle() > 0.) {
119 if (foundU && foundV) {
123 if (!foundU || !foundV) {
124 result.measurements = std::move(calibHits);
125 result.parameters = startPars;
128 if (
m_cfg.doBeamSpot) {
138 covariance[toUnderlying(AxisDefs::etaCov)] = square(
m_cfg.beamSpotRadius);
139 covariance[toUnderlying(AxisDefs::phiCov)] = square(
m_cfg.beamSpotLength);
141 auto beamSpotSP = std::make_unique<CalibratedSpacePoint>(
nullptr, std::move(beamSpot));
142 beamSpotSP->setBeamDirection(std::move(beamLine));
143 beamSpotSP->setCovariance(std::move(covariance));
145 <<
Amg::toString(beamSpotSP->localPosition())<<
", "<<beamSpotSP->covariance());
146 calibHits.emplace_back(std::move(beamSpotSP));
148 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__ <<
": Start segment fit with parameters "
150 <<std::endl<<
print(calibHits));
153 fitOpts.calibContext = cctx;
154 fitOpts.calibrator =
m_cfg.calibrator;
157 fitOpts.measurements = std::move(calibHits);
158 fitOpts.localToGlobal = localToGlobal;
159 fitOpts.startParameters = startPars;
161 constexpr auto t0idx = toUnderlying(ParamDefs::t0);
164 result =
m_fitter.fit(std::move(fitOpts));
168 result.covariance(t0idx, t0idx) = Acts::square(
ActsTrk::timeToAthena(1.)) * result.covariance(t0idx, t0idx);
169 for (
ParamDefs p : {ParamDefs::x0, ParamDefs::y0, ParamDefs::phi, ParamDefs::theta}) {
170 auto pidx = toUnderlying(p);
177 const auto[segPos, segDir] =
makeLine(result.parameters);
178 for (
Hit_t& hit : result.measurements) {
179 hit->setChi2Term(SeedingAux::chi2Term(segPos, segDir, *hit));
184 std::unique_ptr<Segment>
193 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__ <<
": Not enough degree of freedom available. What shall be fitted?!");
196 if (
m_cfg.visionTool) {
198 preFit.parameters = startPars;
199 preFit.measurements = calibHits;
201 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy,
"Prefit");
204 if (
m_cfg.visionTool && segFit.converged) {
206 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy,
"Intermediate fit");
209 segFit.converged? segFit.parameters : startPars,
213 if (!
plugHoles(cctx, *parent, localToGlobal, segFit)) {
217 if (
m_cfg.visionTool) {
218 m_cfg.visionTool->visualizeSegment(ctx, *finalSeg,
"Final fit");
222 std::unique_ptr<Segment>
226 const auto [locPos, locDir] =
makeLine(data.parameters);
230 std::ranges::sort(data.measurements, [](
const Hit_t&
a,
const Hit_t& b){
231 return a->localPosition().z() < b->localPosition().z();
235 <<
"built from:\n"<<
print(data.measurements));
237 auto finalSeg = std::make_unique<Segment>(std::move(globPos), std::move(globDir),
238 patternSeed, std::move(data.measurements),
239 data.chi2, data.nDoF);
240 finalSeg->setCallsToConverge(data.nIter);
241 finalSeg->setParUncertainties(std::move(data.covariance));
243 finalSeg->setSegmentT0(data.parameters[toUnderlying(ParamDefs::t0)]);
255 fitResult.nIter >
m_fitter.config().maxIter) {
257 <<
": No degree of freedom available. What shall be removed?!. nDoF: "
258 <<fitResult.nDoF<<
", n-meas: "<<countPrecHits(fitResult.measurements)
259 <<std::endl<<
print(fitResult.measurements));
262 if (fitResult.converged && calcRedChi2(fitResult) <
m_cfg.outlierRemovalCut) {
264 <<
" is already of good quality "<< calcRedChi2(fitResult)<<
". Don't remove outliers");
267 if (fitResult.nDoF == 0u){
271 <<
toString(fitResult.parameters)<<
", nIter: "<<fitResult.nIter
272 <<
" is of badish quality. "<<
print(fitResult.measurements)
273 <<std::endl<<
"Remove worst hit");
277 if (
m_cfg.doBeamSpot) {
278 removeBeamSpot(fitResult.measurements);
282 std::ranges::sort(fitResult.measurements,
283 [](
const HitVec_t::value_type&
a,
const HitVec_t::value_type& b){
285 if (isGoodHit(*a) != isGoodHit(*b)) {
286 return !isGoodHit(*a);
288 return a->chi2Term() < b->chi2Term();
290 fitResult.measurements.back()->setFitState(HitState::Outlier);
291 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
" Mark "<<(*fitResult.measurements.back())<<
" as outlier");
294 if (!checkPrecHitCount(fitResult.measurements)) {
296 <<
": No degree of freedom available after outlier removal. n-meas: "
297 <<countPrecHits(fitResult.measurements)<<std::endl<<
print(fitResult.measurements));
302 Result_t newAttempt = callLineFit(cctx, startPars, localToGlobal,
303 std::move(fitResult.measurements));
304 if (newAttempt.converged) {
305 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
" The outlier removal converged.");
306 newAttempt.nIter+=fitResult.nIter;
307 fitResult = std::move(newAttempt);
308 if (m_cfg.visionTool) {
309 const EventContext& ctx{*cctx.get<
const EventContext*>()};
310 auto seedCopy = convertToSegment(localToGlobal, &seed,
Result_t{fitResult});
311 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy,
"Bad fit recovery");
315 <<
" Outlier removal fit did not converge. Needed iterations: "<<newAttempt.nIter);
316 if (newAttempt.nIter == 0ul) {
319 fitResult.nIter+=newAttempt.nIter;
320 fitResult.measurements = std::move(newAttempt.measurements);
322 return removeOutliers(cctx, seed, localToGlobal,
323 fitResult.converged ? fitResult.parameters : startPars,
328 auto [segPos, segDir] =
makeLine(candidate.parameters);
330 candidate.measurements.erase(
std::remove_if(candidate.measurements.begin(),
331 candidate.measurements.end(),
332 [&](
const HitVec_t::value_type& hit){
333 if (hit->fitState() == HitState::Valid) {
335 }
else if (hit->fitState() == HitState::Duplicate) {
340 const double dist = Amg::lineDistance(segPos, segDir,
341 hit->localPosition(),
342 hit->sensorDirection());
343 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->spacePoint()->primaryMeasurement());
344 return dist >= dc->readoutElement()->innerTubeRadius();
347 }), candidate.measurements.end());
352 std::ranges::sort(hits, [&](
const Hit_t&
a ,
const Hit_t& b){
353 if (
a->isStraw() || b->isStraw()) {
354 return !
a->isStraw();
360 const unsigned lay_a = sorter.sectorLayerNum(*
a->spacePoint());
361 const unsigned lay_b = sorter.sectorLayerNum(*b->spacePoint());
362 if (lay_a != lay_b) {
363 return lay_a < lay_b;
365 const double chi2a =
a->chi2Term();
366 const double chi2b = b->chi2Term();
371 const auto* sTgcB =
static_cast<const xAOD::sTgcMeasurement*
>(b->spacePoint()->primaryMeasurement());
372 if (sTgcA->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Pad &&
373 sTgcB->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Strip) {
374 return std::sqrt(chi2b) >
m_cfg.recoveryPull;
375 }
else if (sTgcB->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Pad &&
376 sTgcA->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Strip) {
377 return std::sqrt(chi2a) <
m_cfg.recoveryPull;
380 return chi2a < chi2b;
383 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__ <<
": Check for duplicate strip hits");
385 for (HitVec_t::iterator itr = hits.begin(); itr != hits.end(); ++itr) {
386 const Hit_t& hit_a{*itr};
387 if (hit_a->isStraw()){
390 if(hit_a->fitState() == HitState::Duplicate ||
394 const unsigned lay_a = sorter.sectorLayerNum(*hit_a->spacePoint());
396 for (HitVec_t::iterator itr2 = itr + 1; itr2 != hits.end(); ++itr2) {
397 const Hit_t& hit_b{*itr2};
399 hit_b->fitState() == HitState::Duplicate) {
402 if (lay_a != sorter.sectorLayerNum(*hit_b->spacePoint())) {
406 if ((hit_a->measuresEta() && hit_b->measuresEta()) ||
407 (hit_a->measuresPhi() && hit_b->measuresPhi())) {
408 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__ <<
": Duplicate hit on same layer"<<std::endl
409 <<
" -- reject: "<<(*hit_b)<<std::endl
410 <<
" -- accept: "<<(*hit_a));
411 hit_b->setFitState(HitState::Duplicate);
418 if (!newResult.converged) {
419 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" The new result did not converge");
422 const double redChi2New = calcRedChi2(newResult);
423 const double redChi2Old = calcRedChi2(oldResult);
424 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" Compare results -- old chi2: "<<redChi2Old<<
", nDoF: "
425 <<oldResult.nDoF<<
" vs. new chi2: "<<redChi2New<<
", nDoF: "<<newResult.nDoF
426 <<
" -- outlier removal: "<<
m_cfg.outlierRemovalCut);
427 if (newResult.nDoF == oldResult.nDoF) {
429 const auto newPrecisionHits = countPrecHits(newResult.measurements);
430 const auto oldPrecisionHits = countPrecHits(oldResult.measurements);
431 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" Compare results -- old precHits: "<<oldPrecisionHits
432 <<
" vs. new precHits: "<<newPrecisionHits);
433 bool isbetter= (newPrecisionHits > oldPrecisionHits && redChi2New <
m_cfg.outlierRemovalCut) || (redChi2New < redChi2Old);
436 return (redChi2New < m_cfg.outlierRemovalCut && newResult.nDoF > oldResult.nDoF) ||
437 (redChi2New >
m_cfg.outlierRemovalCut && redChi2New < redChi2Old);
445 <<
", chi2: "<< calcRedChi2(toRecover) <<
", nDoF: "<<toRecover.nDoF);
449 std::unordered_set<const SpacePoint*> usedSpacePoints{};
450 for (
auto& hit : toRecover.measurements) {
451 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__ <<
": "<<(*hit)<<
" is known");
452 usedSpacePoints.insert(hit->spacePoint());
455 const EventContext& ctx{*cctx.get<
const EventContext*>()};
457 const double timeOff = toRecover.parameters[toUnderlying(ParamDefs::t0)];
459 std::size_t hasCandidate{0};
460 const auto [locPos, locDir] =
makeLine(toRecover.parameters);
463 for (
const auto& hit : *seed.parentBucket()){
465 if (usedSpacePoints.count(hit.get())){
470 if (hit->isStraw()) {
471 using namespace Acts::detail::LineHelper;
472 const double dist = signedDistance(locPos, locDir, hit->localPosition(), hit->sensorDirection());
475 if (std::abs(dist) >= dc->readoutElement()->innerTubeRadius()) {
480 if (!hit->measuresEta() &&
481 std::abs(hit->sensorDirection().dot(hit->localPosition() -
482 SeedingAux::extrapolateToPlane(locPos,locDir, *hit))) >
483 1.1*std::sqrt(hit->covariance()[toUnderlying(AxisDefs::etaCov)])){
488 pull = std::sqrt(SeedingAux::chi2Term(locPos, locDir, *hit));
489 if (pull > 1.1 *
m_cfg.recoveryPull) {
494 calibHit->setChi2Term(SeedingAux::chi2Term(locPos, locDir, *calibHit));
495 if (calibHit->chi2Term() <= Acts::square(
m_cfg.recoveryPull)) {
496 hasCandidate += calibHit->fitState() == HitState::Valid;
497 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Candidate hit for recovery "
500 calibHit->setFitState(HitState::Outlier);
502 <<(*calibHit)<<
" -> limit: "<<
m_cfg.recoveryPull);
504 candidateHits.push_back(std::move(calibHit));
508 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": No space point candidates for recovery were found");
509 toRecover.measurements.insert(toRecover.measurements.end(),
510 std::make_move_iterator(candidateHits.begin()),
511 std::make_move_iterator(candidateHits.end()));
513 return toRecover.nDoF > 0;
515 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Found "<<hasCandidate<<
" space points for recovery. ");
518 HitVec_t hitsForRecovery = toRecover.measurements;
520 if (
m_cfg.doBeamSpot) {
521 removeBeamSpot(hitsForRecovery);
524 hitsForRecovery.insert(hitsForRecovery.end(),
525 candidateHits.begin(),
526 candidateHits.end());
531 std::move(hitsForRecovery));
536 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Accept segment with recovered "
537 <<(recovered.nDoF - toRecover.nDoF)<<
" extra nDoF.");
538 recovered.nIter += toRecover.nIter;
539 toRecover = std::move(recovered);
541 std::vector<const CalibratedSpacePoint*> stripOutliers{};
542 stripOutliers.reserve(toRecover.measurements.size());
545 unsigned recovLoop{(candidateHits.size() != hasCandidate)*
m_cfg.nRecoveryLoops};
546 while (++recovLoop <=
m_cfg.nRecoveryLoops) {
547 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Enter recovery loop "<<recovLoop<<
".");
548 hitsForRecovery = toRecover.measurements;
550 if (
m_cfg.doBeamSpot) {
551 removeBeamSpot(hitsForRecovery);
554 for (HitVec_t::value_type& hit : hitsForRecovery) {
555 if (hit->fitState() != HitState::Outlier) {
558 if (hit->chi2Term() < Acts::square(
m_cfg.recoveryPull)) {
559 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Try to recover outlier "<<(*hit));
560 hit->setFitState(HitState::Valid);
561 stripOutliers.push_back(hit.get());
565 if (stripOutliers.empty()) {
566 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": No additional measurement found");
573 return sp->fitState() == HitState::Valid;
575 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Outliers turned out to be duplicates.");
578 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Start fit without the outliers.");
579 stripOutliers.clear();
580 recovered =
callLineFit(cctx, toRecover.parameters, localToGlobal, std::move(hitsForRecovery));
584 recovered.nIter += toRecover.nIter;
585 toRecover = std::move(recovered);
588 for (HitVec_t::value_type& hit : candidateHits) {
589 hit->setFitState(HitState::Outlier);
590 toRecover.measurements.push_back(std::move(hit));
599 const size_t nPrecHits = countPrecHits(candidateHits);
600 if (nPrecHits <
m_cfg.nPrecHitCut) {
601 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": Not enough precision hits for segment fit. "
602 <<nPrecHits<<
" < "<<
m_cfg.nPrecHitCut);
606 const auto firstHit {std::ranges::find_if(candidateHits, [](
const Hit_t& hit){
607 return hit->spacePoint() !=
nullptr;
609 assert(firstHit != candidateHits.end());
610 if (
toStationIndex((*firstHit)->spacePoint()->msSector()->chamberIndex()) == StIndex::EI &&
611 std::ranges::any_of(candidateHits, [](
const Hit_t& hit){
612 return xAOD::isNSW(hit->type()); })) {
614 std::array<std::size_t, 3> nStrips{Acts::filledArray<std::size_t, 3>(0u)};
615 std::size_t nPhiHits {0u};
616 for (
const Hit_t& hit : candidateHits) {
623 nPhiHits += hit->measuresPhi();
626 const auto* mmClust =
dynamic_cast<const xAOD::MMCluster*
>(hit->spacePoint()->primaryMeasurement());
628 const auto& design = mmClust->readoutElement()->stripLayer(mmClust->measurementHash()).design();
629 if (!design.hasStereoAngle()) {
631 }
else if (design.stereoAngle() > 0.) {
641 std::size_t nEtaOrientations =
642 std::ranges::count_if(nStrips, [](std::size_t n){
return n > 0; });
643 if (nEtaOrientations == 3u) {
644 nEtaOrientations += std::ranges::any_of( nStrips, [](std::size_t n){
return n > 1; });
646 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
": nHits: "<<candidateHits.size()
647 <<
", nPhiHits: "<<nPhiHits<<
", nEtaOrientations: "<<nEtaOrientations
648 <<
", N X-strips: "<<nStrips[0]<<
", U-strips: "<<nStrips[1]<<
", V-strips: "<<nStrips[2]);
650 if ( nEtaOrientations == 4u ||
651 (nEtaOrientations == 3u && nPhiHits >= 1u) ||
652 (nEtaOrientations == 2u && nPhiHits >= 2u)||
653 (std::ranges::any_of(nStrips, [](std::size_t n){
return n >= 2u; }) && nPhiHits >= 2u)) {
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_MSG_VERBOSE(x)
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
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.
Segment::MeasType Hit_t
Abrivation of the space point type to use.
bool plugHoles(const Acts::CalibrationContext &cctx, const SegmentSeed &seed, const Amg::Transform3D &localToGlobal, Result_t &toRecover) const
Recovery of missed hits.
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 betterResult(const Result_t &newResult, const Result_t &oldResult) const
Returns whether the new fit result is better than the one from the previous iteration.
void eraseWrongHits(Result_t &candidate) const
Removes all hits from the segment which are obvious outliers.
void cleanStripLayers(HitVec_t &hits) const
Marks duplicate hits on a strip layer as outliers to avoid competing contributions from the same laye...
std::unique_ptr< Segment > convertToSegment(const Amg::Transform3D &locToGlobTrf, const SegmentSeed *parentSeed, Result_t &&toConvert) const
Converts the fit result into a segment object.
bool checkPrecHitCount(const HitVec_t &candidateHits) const
Checks if the candidate has enough precision hits to fit a segment.
Fitter_t::FitOptions< HitVec_t, ISpacePointCalibrator > FitOpts_t
Abrivation of the fit options.
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.
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(T 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 auto timeToActs(T athenaT)
Converts a time unit from Athena to Acts units.
This class is not to needed in AthSimulation.
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).
std::string print(const cont_t &container)
Print a space point container to string.
bool isGoodHit(const CalibratedSpacePoint &hit)
Returns whether the calibrated spacepoint is valid and therefore suitable to be used in the segment f...
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
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
sTgcMeasurement_v1 sTgcMeasurement
Full configuration object.
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