ATLAS Offline Software
Loading...
Searching...
No Matches
MuonR4::SegmentFit::SegmentLineFitter Class Reference

The SegmentLineFitter is a standalone module to fit a straight line to calibrated muon space points. More...

#include <SegmentLineFitter.h>

Inheritance diagram for MuonR4::SegmentFit::SegmentLineFitter:
Collaboration diagram for MuonR4::SegmentFit::SegmentLineFitter:

Classes

struct  ConfigSwitches
 Configuration object of the ATLAS implementation. More...
struct  Config
 Full configuration object. More...

Public Types

using Fitter_t = Acts::Experimental::CompositeSpacePointLineFitter
 Abrivation of the actual line fitter.
using LinePar_t = Fitter_t::ParamVec_t
 Abrivation of the fitted line parameters.
using Hit_t = Segment::MeasType
 Abrivation of the space point type to use.
using HitVec_t = std::vector<Hit_t>
 Collection of space points.
using FitPars_t = Fitter_t::FitParameters
 Abrivation of the fit parameters.
using Result_t = Fitter_t::FitResult<HitVec_t>
 Abrivation of the fit result.
using FitOpts_t = Fitter_t::FitOptions<HitVec_t, ISpacePointCalibrator>
 Abrivation of the fit options.
using Selector_t = Fitter_t::Selector_t<CalibratedSpacePoint>
 Abrivation of the hit selector to choose valid hits.
using HitState = CalibratedSpacePoint::State
 Abrivation of the fit state flag.

Public Member Functions

 SegmentLineFitter (const std::string &name, Config &&config)
 Standard constructor.
std::unique_ptr< SegmentfitSegment (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.
bool msgLvl (const MSG::Level lvl) const
 Test the output level.
MsgStream & msg () const
 The standard message stream.
MsgStream & msg (const MSG::Level lvl) const
 The standard message stream.
void setLevel (MSG::Level lvl)
 Change the current logging level.

Private Member Functions

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.
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.
bool plugHoles (const Acts::CalibrationContext &cctx, const SegmentSeed &seed, const Amg::Transform3D &localToGlobal, Result_t &toRecover) const
 Recovery of missed hits.
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 layers in the fit.
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.
std::unique_ptr< SegmentconvertToSegment (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.
void initMessaging () const
 Initialize our message level and MessageSvc.

Private Attributes

Fitter_t m_fitter
 Actual implementation of the straight line fit.
ConfigSwitches m_cfg {}
 Configuration switches of the ATLAS fitter implementation.
Selector_t m_goodHitSel {}
 Selector to identify the valid hits.
std::string m_nm
 Message source name.
boost::thread_specific_ptr< MsgStream > m_msg_tls
 MsgStream instance (a std::cout like with print-out levels).
std::atomic< IMessageSvc * > m_imsg { nullptr }
 MessageSvc pointer.
std::atomic< MSG::Level > m_lvl { MSG::NIL }
 Current logging level.
std::atomic_flag m_initialized ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
 Messaging initialized (initMessaging).

Detailed Description

The SegmentLineFitter is a standalone module to fit a straight line to calibrated muon space points.

The CompositeSpacePointLineFitter from the ACTS toolkit is used to perform the actual fit to the measurements. The SegmentLineFitter is a wrapper class taking care of relaunching fits of poor quality but with cleaned measurements and also to put back meaurements on the line that have been missed by the initial line fit.

Definition at line 28 of file SegmentLineFitter.h.

Member Typedef Documentation

◆ FitOpts_t

Abrivation of the fit options.

Definition at line 43 of file SegmentLineFitter.h.

◆ FitPars_t

using MuonR4::SegmentFit::SegmentLineFitter::FitPars_t = Fitter_t::FitParameters

Abrivation of the fit parameters.

Definition at line 39 of file SegmentLineFitter.h.

◆ Fitter_t

using MuonR4::SegmentFit::SegmentLineFitter::Fitter_t = Acts::Experimental::CompositeSpacePointLineFitter

Abrivation of the actual line fitter.

Definition at line 31 of file SegmentLineFitter.h.

◆ Hit_t

Abrivation of the space point type to use.

Definition at line 35 of file SegmentLineFitter.h.

◆ HitState

Abrivation of the fit state flag.

Definition at line 47 of file SegmentLineFitter.h.

◆ HitVec_t

Collection of space points.

Definition at line 37 of file SegmentLineFitter.h.

◆ LinePar_t

Abrivation of the fitted line parameters.

Definition at line 33 of file SegmentLineFitter.h.

◆ Result_t

Abrivation of the fit result.

Definition at line 41 of file SegmentLineFitter.h.

◆ Selector_t

Abrivation of the hit selector to choose valid hits.

Definition at line 45 of file SegmentLineFitter.h.

Constructor & Destructor Documentation

◆ SegmentLineFitter()

MuonR4::SegmentFit::SegmentLineFitter::SegmentLineFitter ( const std::string & name,
Config && config )

Standard constructor.

Parameters
nameName to be printed in the messaging
configFit configuration parameters

Definition at line 85 of file SegmentLineFitter.cxx.

85 :
88 m_cfg{config} {
89 m_goodHitSel.connect<isGoodHit>();
90 }
std::unique_ptr< const Acts::Logger > makeActsAthenaLogger(IMessageSvc *svc, const std::string &name, int level, std::optional< std::string > parent_name)
Definition Logger.cxx:64
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
Selector_t m_goodHitSel
Selector to identify the valid hits.
ConfigSwitches m_cfg
Configuration switches of the ATLAS fitter implementation.
Fitter_t m_fitter
Actual implementation of the straight line fit.
bool isGoodHit(const CalibratedSpacePoint &hit)
Returns whether the calibrated spacepoint is valid and therefore suitable to be used in the segment f...

Member Function Documentation

◆ betterResult()

bool MuonR4::SegmentFit::SegmentLineFitter::betterResult ( const Result_t & newResult,
const Result_t & oldResult ) const
inlineprivate

Returns whether the new fit result is better than the one from the previous iteration.

Selection criterion is the chi2 estimation for the same number of degrees of freedom and then the one which has more degree of freedom but still remains under the good segment threshold

Parameters
newResultThe first fit result
oldResultThe second fit result

Definition at line 456 of file SegmentLineFitter.cxx.

456 {
457 if (!newResult.converged) {
458 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" The new result did not converge");
459 return false;
460 }
461 const double redChi2New = calcRedChi2(newResult);
462 const double redChi2Old = calcRedChi2(oldResult);
463 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Compare results -- old chi2: "<<redChi2Old<<", nDoF: "
464 <<oldResult.nDoF<<" vs. new chi2: "<<redChi2New<<", nDoF: "<<newResult.nDoF
465 <<" -- outlier removal: "<<m_cfg.outlierRemovalCut);
466 if (newResult.nDoF == oldResult.nDoF) {
467 //check the number of precision hits
468 const std::size_t newPrecisionHits = countPrecHits(newResult.measurements);
469 const std::size_t oldPrecisionHits = countPrecHits(oldResult.measurements);
470 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" Compare results -- old precHits: "<<oldPrecisionHits
471 <<" vs. new precHits: "<<newPrecisionHits);
472 return (newPrecisionHits > oldPrecisionHits && redChi2New < m_cfg.outlierRemovalCut) ||
473 redChi2New < redChi2Old;
474 }
475 return (redChi2New < m_cfg.outlierRemovalCut && newResult.nDoF > oldResult.nDoF) ||
476 (redChi2New > m_cfg.outlierRemovalCut && redChi2New < redChi2Old);
477 }
#define ATH_MSG_VERBOSE(x)

◆ callLineFit()

Result_t MuonR4::SegmentFit::SegmentLineFitter::callLineFit ( const Acts::CalibrationContext & cctx,
const Parameters & startPars,
const Amg::Transform3D & localToGlobal,
HitVec_t && calibHits ) const
private

Calls the underlying line fitter to determine the segment parameters.

Parameters
cctxCalibration context to fetch later the measurement's calib constants from StoreGate (It's a packed EventContext*)
startParsInitial line parameters guess
localToGlobalTransform to align the segment's station inside ATLAS (Mainly neede if the time is fit)
calibHitsList of hits that will be fitted

Check whether a beamspot constraint should be appended

placeholder for a very generous beam spot: 300mm in X,Y (tracking volume), 20000 along Z

Recall that the time is not the same in Acts & Athena

Fit the measurements

Convert back to athena time units

Cache the chi2 terms of the measurements w.r.t. the segment

Definition at line 91 of file SegmentLineFitter.cxx.

94 {
95
97 bool appendsBS = m_cfg.doBeamSpot && countPhiHits(calibHits) > 0;
98
99
101 //check the degrees of freedom before try the fit
102 if (const std::size_t nPars = m_fitter.config().parsToUse.size(); nPars > 0ul) {
103 auto dOF = m_fitter.countDoF(calibHits, m_goodHitSel);
104 if (dOF.bending + dOF.nonBending < nPars) {
105 return result;
106 }
107 // check that there are at least two crossing stereo measurements
108 if (dOF.nonBending == 0ul && nPars == 4ul){
109 bool foundU{false}, foundV{false};
110 for (const HitVec_t::value_type& hit : calibHits) {
112 continue;
113 }
114 const auto* mmClust = dynamic_cast<const xAOD::MMCluster*>(hit->spacePoint()->primaryMeasurement());
115 assert(mmClust != nullptr);
116 const auto& design = mmClust->readoutElement()->stripLayer(mmClust->layerHash()).design();
117 if (!design.hasStereoAngle()) {
118 continue;
119 }
120 if (design.stereoAngle() > 0.) {
121 foundU = true;
122 } else {
123 foundV = true;
124 }
125 if (foundU && foundV) {
126 break;
127 }
128 }
129 if (!foundU || !foundV) {
130 result.measurements = std::move(calibHits);
131 result.parameters = startPars;
132 return result;
133 }
134 if (m_cfg.doBeamSpot) {
135 appendsBS = true;
136 }
137 }
138 }
139 if (appendsBS) {
140 const Amg::Transform3D globToLoc{localToGlobal.inverse()};
141 Amg::Vector3D beamSpot{globToLoc.translation()};
142 Amg::Vector3D beamLine{globToLoc.linear().col(2)};
143 SpacePoint::Cov_t covariance{};
144 covariance[toUnderlying(AxisDefs::etaCov)] = square(m_cfg.beamSpotRadius);
145 covariance[toUnderlying(AxisDefs::phiCov)] = square(m_cfg.beamSpotLength);
147 auto beamSpotSP = std::make_unique<CalibratedSpacePoint>(nullptr, std::move(beamSpot));
148 beamSpotSP->setBeamDirection(std::move(beamLine));
149 beamSpotSP->setCovariance(std::move(covariance));
150 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Beam spot constraint "
151 <<Amg::toString(beamSpotSP->localPosition())<<", "<<beamSpotSP->covariance());
152 calibHits.emplace_back(std::move(beamSpotSP));
153 }
154 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Start segment fit with parameters "
155 <<toString(startPars) <<", plane location: "<<Amg::toString(localToGlobal)
156 <<std::endl<<print(calibHits));
157
158 FitOpts_t fitOpts{};
159 fitOpts.calibContext = cctx;
160 fitOpts.calibrator = m_cfg.calibrator;
161 fitOpts.selector = m_goodHitSel;
162
163 fitOpts.measurements = std::move(calibHits);
164 fitOpts.localToGlobal = localToGlobal;
165 fitOpts.startParameters = startPars;
167 constexpr auto t0idx = toUnderlying(ParamDefs::t0);
168 fitOpts.startParameters[t0idx] = ActsTrk::timeToActs(fitOpts.startParameters[t0idx]);
170 result = m_fitter.fit(std::move(fitOpts));
172 if (m_fitter.config().fitT0) {
173 result.parameters[t0idx] = ActsTrk::timeToAthena(result.parameters[t0idx]);
174 result.covariance(t0idx, t0idx) = Acts::square(ActsTrk::timeToAthena(1.)) * result.covariance(t0idx, t0idx);
175 for (ParamDefs p : {ParamDefs::x0, ParamDefs::y0, ParamDefs::phi, ParamDefs::theta}) {
176 auto pidx = toUnderlying(p);
177 result.covariance(t0idx, pidx) = ActsTrk::timeToAthena(result.covariance(t0idx, pidx));
178 result.covariance(pidx, t0idx) = ActsTrk::timeToAthena(result.covariance(pidx, t0idx));
179 }
180 }
182 {
183 const auto[segPos, segDir] = makeLine(result.parameters);
184 for (Hit_t& hit : result.measurements) {
185 hit->setChi2Term(SeedingAux::chi2Term(segPos, segDir, *hit));
186 }
187 }
188 return result;
189 }
bool hit(const Container &ids, int pdgId)
Segment::MeasType Hit_t
Abrivation of the space point type to use.
Fitter_t::FitResult< HitVec_t > Result_t
Abrivation of the fit result.
Fitter_t::FitOptions< HitVec_t, ISpacePointCalibrator > FitOpts_t
Abrivation of the fit options.
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.
constexpr auto timeToActs(T 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
SeedingAux::FitParIndex ParamDefs
Use the same parameter indices as used by the CompSpacePointAuxiliaries.
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
std::string toString(const Parameters &pars)
Dumps the parameters into a string with labels in front of each number.
std::string print(const cont_t &container)
Print a space point container to string.
AthConfigFlags beamSpot(AthConfigFlags flags, str instanceName, str recoMode)
MMCluster_v1 MMCluster

◆ checkPrecHitCount()

bool MuonR4::SegmentFit::SegmentLineFitter::checkPrecHitCount ( const HitVec_t & candidateHits) const
inlineprivate

Checks if the candidate has enough precision hits to fit a segment.

In case of NSW, we check also the orientation of the strips to ensure they provide indipendent constraints on the segment.

Parameters
candidateHitsList of hits on the candidate segment
seedSegment seed from which the segment was built. Needed for station index

Check whether there is at least one of each micromega strip type. To have a sane topology we need to have at least 2 strips from one kind.

Definition at line 634 of file SegmentLineFitter.cxx.

634 {
635 using namespace Muon::MuonStationIndex;
636
637 const size_t nPrecHits = countPrecHits(candidateHits);
638 if (nPrecHits < m_cfg.nPrecHitCut) {
639 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Not enough precision hits for segment fit. "
640 <<nPrecHits<<" < "<<m_cfg.nPrecHitCut);
641 return false;
642 }
643
644 const auto firstHit {std::ranges::find_if(candidateHits, [](const Hit_t& hit){
645 return hit->spacePoint() != nullptr;
646 })};
647 assert(firstHit != candidateHits.end());
648 if (toStationIndex((*firstHit)->spacePoint()->msSector()->chamberIndex()) == StIndex::EI &&
649 std::ranges::any_of(candidateHits, [](const Hit_t& hit){
650 return xAOD::isNSW(hit->type()); })) {
651
652 std::array<std::size_t, 3> nStrips{Acts::filledArray<std::size_t, 3>(0u)};
653 std::size_t nPhiHits {0u};
654 for (const Hit_t& hit : candidateHits) {
655 if (!isGoodHit(*hit)) {
656 continue;
657 }
658
660 nStrips[0] += isPrecisionHit(*hit);
661 nPhiHits += hit->measuresPhi();
662 continue;
663 } else if (hit->type() == xAOD::UncalibMeasType::MMClusterType) {
664 const auto* mmClust = dynamic_cast<const xAOD::MMCluster*>(hit->spacePoint()->primaryMeasurement());
665 assert(mmClust);
666 const auto& design = mmClust->readoutElement()->stripLayer(mmClust->measurementHash()).design();
667 if (!design.hasStereoAngle()) {
668 ++nStrips[0];
669 } else if (design.stereoAngle() > 0.) {
670 ++nStrips[1];
671 } else {
672 ++nStrips[2];
673 }
674 }
675 }
678
679 std::size_t nEtaOrientations =
680 std::ranges::count_if(nStrips, [](std::size_t n){ return n > 0; });
681 if (nEtaOrientations == 3u) {
682 nEtaOrientations += std::ranges::any_of( nStrips, [](std::size_t n){ return n > 1; });
683 }
684 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": nHits: "<<candidateHits.size()
685 <<", nPhiHits: "<<nPhiHits<<", nEtaOrientations: "<<nEtaOrientations
686 <<", N X-strips: "<<nStrips[0]<<", U-strips: "<<nStrips[1]<<", V-strips: "<<nStrips[2]);
687
688 if ( nEtaOrientations == 4u ||
689 (nEtaOrientations == 3u && nPhiHits >= 1u) ||
690 (nEtaOrientations == 2u && nPhiHits >= 2u)||
691 (std::ranges::any_of(nStrips, [](std::size_t n){ return n >= 2u; }) && nPhiHits >= 2u)) {
692 return true;
693 }
694 return false;
695 }
696 return true;
697 }
int nStrips(const MuonGM::TgcReadoutElement &readoutEle, int layer)
bool isPrecisionHit(const SpacePoint &hit)
Returns whether the uncalibrated spacepoint is a precision hit (Mdt, micromegas, stgc strips).
StIndex toStationIndex(ChIndex index)
convert ChIndex into StIndex
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77

◆ cleanStripLayers()

void MuonR4::SegmentFit::SegmentLineFitter::cleanStripLayers ( HitVec_t & hits) const
inlineprivate

Marks duplicate hits on a strip layer as outliers to avoid competing contributions from the same layers in the fit.

Hits on the same layer are sorted by their chi2 and the worse ones are rejected if they don't provide additional information

Parameters
hitsList of hit measurements to clean

We need to sort out strip hits on the same layer

Loop over the hits to mark the less compatible hits on the layer as outlier

Both hits measure eta. They've been sorted by lower chi2 -> reject b

Definition at line 355 of file SegmentLineFitter.cxx.

355 {
356 const SpacePointPerLayerSorter sorter{};
358 std::ranges::sort(hits, [&](const Hit_t&a ,const Hit_t& b){
359 // move the straws to the end of the vector
360 if (a->isStraw() || b->isStraw()) {
361 return !a->isStraw();
362 }
363 // move the beam spot to the end of the vector
364 if (a->type() == xAOD::UncalibMeasType::Other ||
365 b->type() == xAOD::UncalibMeasType::Other) {
366 return a->type() != xAOD::UncalibMeasType::Other;
367 }
368 // sort the strips by layer
369 const unsigned lay_a = sorter.sectorLayerNum(*a->spacePoint());
370 const unsigned lay_b = sorter.sectorLayerNum(*b->spacePoint());
371 if (lay_a != lay_b) {
372 return lay_a < lay_b;
373 }
374 if (a->fitState() != b->fitState()) {
375 return a->fitState() == HitState::Valid;
376 }
377 const double chi2a = a->chi2Term();
378 const double chi2b = b->chi2Term();
379 /* Do not accept pad hits even though they've smaller chi2
380 * than the neighbouring strip */
382 const auto* sTgcA = static_cast<const xAOD::sTgcMeasurement*>(a->spacePoint()->primaryMeasurement());
383 const auto* sTgcB = static_cast<const xAOD::sTgcMeasurement*>(b->spacePoint()->primaryMeasurement());
384 if (sTgcA->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Pad &&
385 sTgcB->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Strip) {
386 return std::sqrt(chi2b) > m_cfg.recoveryPull;
387 } else if (sTgcB->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Pad &&
388 sTgcA->channelType() == xAOD::sTgcMeasurement::sTgcChannelTypes::Strip) {
389 return std::sqrt(chi2a) < m_cfg.recoveryPull;
390 }
391 }
392
393 /*
394 * Prefer a two-coordinate RPC/TGC space point over a phi-only
395 * RPC/TGC space point, provided that the two-coordinate point
396 * is compatible with the recovery-pull requirement.
397 */
398 if (a->type() == xAOD::UncalibMeasType::RpcStripType ||
400
401 const bool aEtaPhi = a->measuresEta() && a->measuresPhi();
402 const bool bEtaPhi = b->measuresEta() && b->measuresPhi();
403
404 const bool aPhiOnly = !a->measuresEta() && a->measuresPhi();
405 const bool bPhiOnly = !b->measuresEta() && b->measuresPhi();
406
407 if (aPhiOnly && bEtaPhi) {
408 // Keep the 1D point first only when the 2D point
409 // is outside the recovery-pull requirement.
410 return std::sqrt(chi2b) > m_cfg.recoveryPull;
411 } else if (aEtaPhi && bPhiOnly) {
412 // Put the 2D point first when it is compatible.
413 return std::sqrt(chi2a) < m_cfg.recoveryPull;
414 }
415 }
416
417 return chi2a < chi2b;
418 });
419
420 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Check for duplicate strip hits");
422 for (HitVec_t::iterator itr = hits.begin(); itr != hits.end(); ++itr) {
423 const Hit_t& hit_a{*itr};
424 // Straws and the beamspot are after all the strips have been passed
425 if (hit_a->isStraw() || hit_a->type() == xAOD::UncalibMeasType::Other) {
426 break;
427 }
428 if(hit_a->fitState() == HitState::Duplicate) {
429 continue;
430 }
431 const unsigned lay_a = sorter.sectorLayerNum(*hit_a->spacePoint());
433 for (HitVec_t::iterator itr2 = itr + 1; itr2 != hits.end(); ++itr2) {
434 const Hit_t& hit_b{*itr2};
435 if (hit_b->type() == xAOD::UncalibMeasType::Other || hit_b->isStraw()) {
436 break;
437 }
438 if (hit_b->fitState() == HitState::Duplicate) {
439 continue;
440 }
441 if (lay_a != sorter.sectorLayerNum(*hit_b->spacePoint())) {
442 break;
443 }
445 if ((hit_a->measuresEta() && hit_b->measuresEta()) ||
446 (hit_a->measuresPhi() && hit_b->measuresPhi())) {
447 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Duplicate hit on same layer"<<std::endl
448 <<" -- reject: "<<(*hit_b)<<std::endl
449 <<" -- accept: "<<(*hit_a));
450 hit_b->setFitState(HitState::Duplicate);
451 }
452 }
453 }
454 }
static Double_t a
sTgcMeasurement_v1 sTgcMeasurement

◆ convertToSegment()

std::unique_ptr< Segment > MuonR4::SegmentFit::SegmentLineFitter::convertToSegment ( const Amg::Transform3D & locToGlobTrf,
const SegmentSeed * parentSeed,
Result_t && toConvert ) const
private

Converts the fit result into a segment object.

Parameters
locToGlobTrfLocal to global transform to translate the segment parameters into global parameters
parentSeedSegment seed from which the segment was built
toConvertFitted segment that needs conversion

Definition at line 229 of file SegmentLineFitter.cxx.

231 {
232 const auto [locPos, locDir] = makeLine(data.parameters);
233 Amg::Vector3D globPos = locToGlob * locPos;
234 Amg::Vector3D globDir = locToGlob.linear()* locDir;
235
236 std::ranges::sort(data.measurements, [](const Hit_t& a, const Hit_t& b){
237 return a->localPosition().z() < b->localPosition().z();
238 });
239 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Create new segment "
240 <<toString(data.parameters)<<" in "<<patternSeed->msSector()->identString()
241 <<"built from:\n"<<print(data.measurements));
242
243 auto finalSeg = std::make_unique<Segment>(std::move(globPos), std::move(globDir),
244 patternSeed, std::move(data.measurements),
245 data.chi2, data.nDoF);
246 finalSeg->setCallsToConverge(data.nIter);
247 finalSeg->setParUncertainties(std::move(data.covariance));
248 if (m_fitter.config().fitT0) {
249 finalSeg->setSegmentT0(data.parameters[toUnderlying(ParamDefs::t0)]);
250 }
251 return finalSeg;
252 }

◆ eraseWrongHits()

void MuonR4::SegmentFit::SegmentLineFitter::eraseWrongHits ( Result_t & candidate) const
private

Removes all hits from the segment which are obvious outliers.

E.g. tubes which cannot be crossed by the segment.

Parameters
candidateReference of the segment candidate to prune.

The segment has never crossed the tube

Definition at line 333 of file SegmentLineFitter.cxx.

333 {
334 auto [segPos, segDir] = makeLine(candidate.parameters);
335 cleanStripLayers(candidate.measurements);
336 candidate.measurements.erase(std::remove_if(candidate.measurements.begin(),
337 candidate.measurements.end(),
338 [&](const HitVec_t::value_type& hit){
339 if (hit->fitState() == HitState::Valid) {
340 return false;
341 } else if (hit->fitState() == HitState::Duplicate) {
342 return true;
343 }
346 const double dist = Amg::lineDistance(segPos, segDir,
347 hit->localPosition(),
348 hit->sensorDirection());
349 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->spacePoint()->primaryMeasurement());
350 return dist >= dc->readoutElement()->innerTubeRadius();
351 }
352 return false;
353 }), candidate.measurements.end());
354 }
if(pathvar)
void cleanStripLayers(HitVec_t &hits) const
Marks duplicate hits on a strip layer as outliers to avoid competing contributions from the same laye...
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.

◆ fitSegment()

std::unique_ptr< Segment > MuonR4::SegmentFit::SegmentLineFitter::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.

Badish initial fits are cleaned and then holes are put filled back Returns a nullptr if the fit failed

Parameters
ctxEventContext to access the calibration constants
parentPointer to the seed from which the hits to fit are taken. The seed gives also access to the parent bucket to recover lost hits
startParsList of parameters serving as an initial guess
localToGlobalTransform to align the segment's station inside ATLAS (Mainly neede if the time is fit)
calibHitsList of hits that will be fitted

Definition at line 191 of file SegmentLineFitter.cxx.

195 {
196
197 const Acts::CalibrationContext cctx = ActsTrk::getCalibrationContext(ctx);
198 if (!checkPrecHitCount(calibHits) ) {
199 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Not enough degree of freedom available. What shall be fitted?!");
200 return nullptr;
201 }
202 if (m_cfg.visionTool) {
203 Result_t preFit{};
204 preFit.parameters = startPars;
205 preFit.measurements = calibHits;
206 auto seedCopy = convertToSegment(localToGlobal, parent, std::move(preFit));
207 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Prefit");
208 }
209 Result_t segFit = callLineFit(cctx, startPars, localToGlobal, std::move(calibHits));
210 if (m_cfg.visionTool && segFit.converged) {
211 auto seedCopy = convertToSegment(localToGlobal, parent, Result_t{segFit});
212 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Intermediate fit");
213 }
214 if (!removeOutliers(cctx, *parent, localToGlobal,
215 segFit.converged ? segFit.parameters : startPars,
216 segFit)) {
217 return nullptr;
218 }
219 if (!plugHoles(cctx, *parent, localToGlobal, segFit)) {
220 return nullptr;
221 }
222 auto finalSeg = convertToSegment(localToGlobal, parent, std::move(segFit));
223 if (m_cfg.visionTool) {
224 m_cfg.visionTool->visualizeSegment(ctx, *finalSeg, "Final fit");
225 }
226 return finalSeg;
227 }
bool plugHoles(const Acts::CalibrationContext &cctx, const SegmentSeed &seed, const Amg::Transform3D &localToGlobal, Result_t &toRecover) const
Recovery of missed 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.
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.
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.
Acts::CalibrationContext getCalibrationContext(const EventContext &ctx)
The Acts::Calibration context is piped through the Acts fitters to (re)calibrate the Acts::SourceLink...

◆ initMessaging()

void AthMessaging::initMessaging ( ) const
privateinherited

Initialize our message level and MessageSvc.

This method should only be called once.

Definition at line 39 of file AthMessaging.cxx.

40{
42 // If user did not set an explicit level, set a default
43 if (m_lvl == MSG::NIL) {
44 m_lvl = m_imsg ?
45 static_cast<MSG::Level>( m_imsg.load()->outputLevel(m_nm) ) :
46 MSG::INFO;
47 }
48}
std::string m_nm
Message source name.
std::atomic< IMessageSvc * > m_imsg
MessageSvc pointer.
std::atomic< MSG::Level > m_lvl
Current logging level.
IMessageSvc * getMessageSvc(bool quiet=false)

◆ msg() [1/2]

MsgStream & AthMessaging::msg ( ) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 167 of file AthMessaging.h.

168{
169 MsgStream* ms = m_msg_tls.get();
170 if (!ms) {
171 if (!m_initialized.test_and_set()) initMessaging();
172 ms = new MsgStream(m_imsg,m_nm);
173 m_msg_tls.reset( ms );
174 }
175
176 ms->setLevel (m_lvl);
177 return *ms;
178}
boost::thread_specific_ptr< MsgStream > m_msg_tls
MsgStream instance (a std::cout like with print-out levels).
void initMessaging() const
Initialize our message level and MessageSvc.

◆ msg() [2/2]

MsgStream & AthMessaging::msg ( const MSG::Level lvl) const
inlineinherited

The standard message stream.

Returns a reference to the default message stream May not be invoked before sysInitialize() has been invoked.

Definition at line 182 of file AthMessaging.h.

183{ return msg() << lvl; }
MsgStream & msg() const
The standard message stream.

◆ msgLvl()

bool AthMessaging::msgLvl ( const MSG::Level lvl) const
inlineinherited

Test the output level.

Parameters
lvlThe message level to test against
Returns
boolean Indicating if messages at given level will be printed
Return values
trueMessages at level "lvl" will be printed

Definition at line 151 of file AthMessaging.h.

152{
153 // If user did not set explicit message level we have to initialize
154 // the messaging and retrieve the default via the MessageSvc.
155 if (m_lvl==MSG::NIL && !m_initialized.test_and_set()) initMessaging();
156
157 if (m_lvl <= lvl) {
158 msg() << lvl;
159 return true;
160 } else {
161 return false;
162 }
163}

◆ plugHoles()

bool MuonR4::SegmentFit::SegmentLineFitter::plugHoles ( const Acts::CalibrationContext & cctx,
const SegmentSeed & seed,
const Amg::Transform3D & localToGlobal,
Result_t & toRecover ) const
private

Recovery of missed hits.

Hits in the space point bucket that are maximally <RecoveryPull> away from the fitted segment are put onto the segment candidate and the candidate is refitted. If the refitted candidate has a chi2/nDoF < <OutlierRemoval> the canidate is automatically choosen otherwise, its chi needs to be better.

Parameters
cctxCalibration context to fetch later the measurement's calib constants from StoreGate (It's a packed EventContext*)
seedParent seed from which the segment fit is actually triggered The seed is mainly used for visualization purposes
localToGlobalTransform to align the spectrometer sector within ATLAS mainly used for the t0 fit
fitResultPreviously achieved fit result to be checked. The measurements on the result and the paramters are updated accordingly

We've the first estimator of the segment fit

Setup a map to replace space points if they better suite

Loop over all hits in the parent bucket

Hit already used in the segment fit

If the hit is a phi measurement check at least if it can be hit by the segment

Use the pull of the uncalibrated measurement to estimate whether a calibration is actually worth

No extra hit has been found

Remove the beamspot constraint measurement

If the chi2 is less than 5, no outlier rejection is launched. So also accept any recovered segment below that threshold

Next check whether the recovery made measurements marked as outlier are feasable to the hole recovery

Definition at line 478 of file SegmentLineFitter.cxx.

481 {
483 ATH_MSG_DEBUG(__func__<<"() - "<<__LINE__ <<": segment "<<toString(toRecover.parameters)
484 <<", chi2: "<< calcRedChi2(toRecover) <<", nDoF: "<<toRecover.nDoF
485 <<std::endl<<print(copyAndSort(toRecover.measurements)));
487 std::vector<const SpacePoint*> usedSpacePoints{};
488 usedSpacePoints.reserve(toRecover.measurements.size());
489 for (auto& hit : toRecover.measurements) {
490 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": "<<(*hit)<<" is known");
491 usedSpacePoints.push_back(hit->spacePoint());
492 }
493
494 const EventContext& ctx{*cctx.get<const EventContext*>()};
495
496 const double timeOff = toRecover.parameters[toUnderlying(ParamDefs::t0)];
497 HitVec_t candidateHits{};
498 std::size_t recovCandidates{0};
499 const auto [locPos, locDir] = makeLine(toRecover.parameters);
500
502 for (const auto& hit : *seed.parentBucket()){
504 if (Acts::rangeContainsValue(usedSpacePoints, hit.get())) {
505 continue;
506 }
507 Hit_t calibHit{};
508 double pull{-1.};
509 if (hit->isStraw()) {
510 using namespace Acts::detail::LineHelper;
511 const double dist = signedDistance(locPos, locDir, hit->localPosition(), hit->sensorDirection());
512 const auto* dc = static_cast<const xAOD::MdtDriftCircle*>(hit->primaryMeasurement());
513 // Check whether the tube is crossed by the hit
514 if (std::abs(dist) >= dc->readoutElement()->innerTubeRadius()) {
515 continue;
516 }
517 } else {
519 if (!hit->measuresEta() &&
520 std::abs(hit->sensorDirection().dot(hit->localPosition() -
521 SeedingAux::extrapolateToPlane(locPos,locDir, *hit))) >
522 1.1*std::sqrt(hit->covariance()[toUnderlying(AxisDefs::etaCov)])){
523 continue;
524 }
527 pull = std::sqrt(SeedingAux::chi2Term(locPos, locDir, *hit));
528 if (pull > 1.1 * m_cfg.recoveryPull) {
529 continue;
530 }
531 }
532 calibHit = m_cfg.calibrator->calibrate(ctx, hit.get(), locPos, locDir, ActsTrk::timeToActs(timeOff));
533 calibHit->setChi2Term(SeedingAux::chi2Term(locPos, locDir, *calibHit));
534 if (calibHit->chi2Term() <= Acts::square(m_cfg.recoveryPull)) {
535 recovCandidates += calibHit->fitState() == HitState::Valid;
536 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Candidate hit for recovery "
537 <<(*calibHit));
538 } else {
539 calibHit->setFitState(HitState::Outlier);
540 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Outlier hit "
541 <<(*calibHit)<<" -> limit: "<<m_cfg.recoveryPull);
542 }
543 candidateHits.push_back(std::move(calibHit));
544 }
546 if (!recovCandidates) {
547 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": No space point candidates for recovery were found");
548 toRecover.measurements.insert(toRecover.measurements.end(),
549 std::make_move_iterator(candidateHits.begin()),
550 std::make_move_iterator(candidateHits.end()));
551 eraseWrongHits(toRecover);
552 return toRecover.nDoF > 0;
553 }
554 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Found "<<recovCandidates<<" space points for recovery. ");
555
556 HitVec_t hitsForRecovery = toRecover.measurements;
558 if (m_cfg.doBeamSpot) {
559 removeBeamSpot(hitsForRecovery);
560 }
561
562 hitsForRecovery.insert(hitsForRecovery.end(), candidateHits.begin(), candidateHits.end());
563
564 cleanStripLayers(hitsForRecovery);
565
566 Result_t recovered = callLineFit(cctx, toRecover.parameters, localToGlobal,
567 std::move(hitsForRecovery));
568
571 if (betterResult(recovered, toRecover)) {
572 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Accept segment with recovered "
573 <<(recovered.nDoF - toRecover.nDoF)<<" extra nDoF.");
574 recovered.nIter += toRecover.nIter;
575 toRecover = std::move(recovered);
576
577 std::vector<const CalibratedSpacePoint*> stripOutliers{};
578 stripOutliers.reserve(toRecover.measurements.size());
581 unsigned recovLoop{(candidateHits.size() == recovCandidates)*m_cfg.nRecoveryLoops};
582 while (++recovLoop <= m_cfg.nRecoveryLoops) {
583 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Enter recovery loop "<<recovLoop<<".");
584 hitsForRecovery = toRecover.measurements;
585 // Remove the beamspot
586 if (m_cfg.doBeamSpot) {
587 removeBeamSpot(hitsForRecovery);
588 }
589 // Check whether an outlier can be lifted to on-track
590 for (HitVec_t::value_type& hit : hitsForRecovery) {
591 if (hit->fitState() != HitState::Outlier) {
592 continue;
593 }
594 if (hit->chi2Term() < Acts::square(m_cfg.recoveryPull)) {
595 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Try to recover outlier "<<(*hit));
596 hit->setFitState(HitState::Valid);
597 stripOutliers.push_back(hit.get());
598 }
599 }
600 // Nothing to recover
601 if (stripOutliers.empty()) {
602 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": No additional measurement found");
603 break;
604 }
605 // Ensure that only one hit per layer is fit
606 cleanStripLayers(hitsForRecovery);
607 // Recovery turned out to be duplicates on the same layer
608 if (std::ranges::none_of(stripOutliers,[](const CalibratedSpacePoint* sp) {
609 return sp->fitState() == HitState::Valid;
610 })) {
611 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Outliers turned out to be all duplicates.");
612 break;
613 }
614 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Start fit without the outliers.");
615 stripOutliers.clear();
616 recovered = callLineFit(cctx, toRecover.parameters, localToGlobal, std::move(hitsForRecovery));
617 if (!betterResult(recovered, toRecover)) {
618 break;
619 }
620 recovered.nIter += toRecover.nIter;
621 toRecover = std::move(recovered);
622 }
623 } else{
624 for (HitVec_t::value_type& hit : candidateHits) {
625 hit->setFitState(HitState::Outlier);
626 toRecover.measurements.push_back(std::move(hit));
627 }
628 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<": Reject refitted segment. Append hits as outliers: "
629 <<std::endl<<print(copyAndSort(toRecover.measurements)));
630 }
631 eraseWrongHits(toRecover);
632 return true;
633 }
#define ATH_MSG_DEBUG(x)
static Double_t sp
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.
std::vector< Hit_t > HitVec_t
Collection of space points.
double signedDistance(const Amg::Vector3D &posA, const Amg::Vector3D &dirA, const Amg::Vector3D &posB, const Amg::Vector3D &dirB)
Calculates the signed distance between two lines in 3D space.
MdtDriftCircle_v1 MdtDriftCircle

◆ removeOutliers()

bool MuonR4::SegmentFit::SegmentLineFitter::removeOutliers ( const Acts::CalibrationContext & cctx,
const SegmentSeed & seed,
const Amg::Transform3D & localToGlobal,
const LinePar_t & startPars,
Result_t & fitResult ) const
private

Cleans the fitted segment from the most outlier hit and then attempts to refit the segment.

The outlier removal is not run if the segment has already a chi2 / nDoF better than <outlierRemovalCut>. Returns false if the recovery lead to the destruction of all nDoF

Parameters
cctxCalibration context to fetch later the measurement's calib constants from StoreGate (It's a packed EventContext*)
seedParent seed from which the segment fit is actually triggered The seed is mainly used for visualization purposes
localToGlobalTransform to align the spectrometer sector within ATLAS mainly used for the t0 fit
startParsThe initial parameters from which the fit shall be launched In case of out of bound parameters, the start parameters are returned otherwise the last obtained fit parameters
fitResultPreviously achieved fit result to be checked. The measurements on the result and the paramters are updated accordingly

Remove a priori the beamspot constaint as it never should pose any problem and another one will be added anyway in the next iteration

Next sort the measurements by ascending chi2

Move the outliers to the front

Check again the available DOF and number of precision hits after hit removal

Refit the segment line without the measurement

Definition at line 254 of file SegmentLineFitter.cxx.

258 {
259
260 if (!checkPrecHitCount(fitResult.measurements) ||
261 fitResult.nIter > m_fitter.config().maxIter) {
262 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__
263 <<": No degree of freedom available. What shall be removed?!. nDoF: "
264 <<fitResult.nDoF<<", n-meas: "<<countPrecHits(fitResult.measurements)
265 <<std::endl<<print(fitResult.measurements));
266 return false;
267 }
268 if (fitResult.converged && calcRedChi2(fitResult) < m_cfg.outlierRemovalCut) {
269 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": The segment "<<toString(fitResult.parameters)
270 <<" is already of good quality "<< calcRedChi2(fitResult)<<". Don't remove outliers");
271 return true;
272 }
273 if (fitResult.nDoF == 0u){
274 return false;
275 }
276 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Segment "
277 <<toString(fitResult.parameters)<<", nIter: "<<fitResult.nIter
278 <<" is of badish quality. "<<print(fitResult.measurements)
279 <<std::endl<<"Remove worst hit");
280
283 if (m_cfg.doBeamSpot) {
284 removeBeamSpot(fitResult.measurements);
285 }
286
288 std::ranges::sort(fitResult.measurements,
289 [](const HitVec_t::value_type& a, const HitVec_t::value_type& b){
291 if (isGoodHit(*a) != isGoodHit(*b)) {
292 return !isGoodHit(*a);
293 }
294 return a->chi2Term() < b->chi2Term();
295 });
296 fitResult.measurements.back()->setFitState(HitState::Outlier);
297 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" Mark "<<(*fitResult.measurements.back())<<" as outlier");
298
300 if (!checkPrecHitCount(fitResult.measurements)) {
301 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__
302 <<": No degree of freedom available after outlier removal. n-meas: "
303 <<countPrecHits(fitResult.measurements)<<std::endl<<print(fitResult.measurements));
304 return false;
305 }
306
308 Result_t newAttempt = callLineFit(cctx, startPars, localToGlobal,
309 std::move(fitResult.measurements));
310 if (newAttempt.converged) {
311 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__<<" The outlier removal converged.");
312 newAttempt.nIter+=fitResult.nIter;
313 fitResult = std::move(newAttempt);
314 if (m_cfg.visionTool) {
315 const EventContext& ctx{*cctx.get<const EventContext*>()};
316 auto seedCopy = convertToSegment(localToGlobal, &seed, Result_t{fitResult});
317 m_cfg.visionTool->visualizeSegment(ctx, *seedCopy, "Bad fit recovery");
318 }
319 } else {
320 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__
321 <<" Outlier removal fit did not converge. Needed iterations: "<<newAttempt.nIter);
322 if (newAttempt.nIter == 0ul) {
323 return false;
324 }
325 fitResult.nIter+=newAttempt.nIter;
326 fitResult.measurements = std::move(newAttempt.measurements);
327 }
328 return removeOutliers(cctx, seed, localToGlobal,
329 fitResult.converged ? fitResult.parameters : startPars,
330 fitResult);
331 }

◆ setLevel()

void AthMessaging::setLevel ( MSG::Level lvl)
inherited

Change the current logging level.

Use this rather than msg().setLevel() for proper operation with MT.

Definition at line 28 of file AthMessaging.cxx.

29{
30 m_lvl = lvl;
31}

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::atomic_flag m_initialized AthMessaging::ATLAS_THREAD_SAFE = ATOMIC_FLAG_INIT
mutableprivateinherited

Messaging initialized (initMessaging).

Definition at line 141 of file AthMessaging.h.

◆ m_cfg

ConfigSwitches MuonR4::SegmentFit::SegmentLineFitter::m_cfg {}
private

Configuration switches of the ATLAS fitter implementation.

Definition at line 108 of file SegmentLineFitter.h.

108{};

◆ m_fitter

Fitter_t MuonR4::SegmentFit::SegmentLineFitter::m_fitter
private

Actual implementation of the straight line fit.

Definition at line 106 of file SegmentLineFitter.h.

◆ m_goodHitSel

Selector_t MuonR4::SegmentFit::SegmentLineFitter::m_goodHitSel {}
private

Selector to identify the valid hits.

Definition at line 110 of file SegmentLineFitter.h.

110{};

◆ m_imsg

std::atomic<IMessageSvc*> AthMessaging::m_imsg { nullptr }
mutableprivateinherited

MessageSvc pointer.

Definition at line 135 of file AthMessaging.h.

135{ nullptr };

◆ m_lvl

std::atomic<MSG::Level> AthMessaging::m_lvl { MSG::NIL }
mutableprivateinherited

Current logging level.

Definition at line 138 of file AthMessaging.h.

138{ MSG::NIL };

◆ m_msg_tls

boost::thread_specific_ptr<MsgStream> AthMessaging::m_msg_tls
mutableprivateinherited

MsgStream instance (a std::cout like with print-out levels).

Definition at line 132 of file AthMessaging.h.

◆ m_nm

std::string AthMessaging::m_nm
privateinherited

Message source name.

Definition at line 129 of file AthMessaging.h.


The documentation for this class was generated from the following files: