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

#include <NswSegmentFinderAlg.h>

Inheritance diagram for MuonR4::NswSegmentFinderAlg:
Collaboration diagram for MuonR4::NswSegmentFinderAlg:

Classes

class  SeedStatistics
 Seed statistics per sector to be printed in the end. More...

Public Member Functions

virtual ~NswSegmentFinderAlg ()=default
virtual StatusCode initialize () override
virtual StatusCode execute (const EventContext &ctx) const override
virtual StatusCode finalize () override
virtual StatusCode sysInitialize () override
 Override sysInitialize.
virtual bool isClonable () const override
 Specify if the algorithm is clonable.
virtual unsigned int cardinality () const override
 Cardinality (Maximum number of clones that can exist) special value 0 means that algorithm is reentrant.
virtual StatusCode sysExecute (const EventContext &ctx) override
 Execute an algorithm.
virtual const DataObjIDColl & extraOutputDeps () const override
 Return the list of extra output dependencies.
virtual bool filterPassed (const EventContext &ctx) const
virtual void setFilterPassed (bool state, const EventContext &ctx) const
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

enum class  StripOrient {
  U , V , X , P ,
  C , Unknown
}
 Enumeration to classify the orientation of a NSW strip. More...
enum class  HitWindow { tooLow , inside , tooHigh }
 To fastly check whether a hit is roughly compatible with a muon trajectory a narrow corridor is opened from the estimated beamspot to the first tested hit in the seed finding. More...
using HitVec = SpacePointPerLayerSplitter::HitVec
using HitLayVec = SpacePointPerLayerSplitter::HitLayVec
using HitLaySpan_t = std::vector<std::reference_wrapper<const HitVec>>
 Abbrivation of the space comprising multiple hit vectors without copy.
using UsedHitMarker_t = std::vector<std::vector<unsigned int>>
 Abbrivation of the container book keeping whether a hit is used or not.
using UsedHitSpan_t = std::vector<std::reference_wrapper<std::vector<unsigned int>>>
 Abbrivation of the container to pass a subset of markers wtihout copy.
using InitialSeed_t = std::array<const SpacePoint*, 4>
 Abbrivation of the initial seed.
using InitialSeedVec_t = std::vector<InitialSeed_t>
 Vector of initial seeds.
using SegmentSeedVec_t = std::vector<std::unique_ptr<SegmentSeed>>
 Abbrivation of the seed vector.
using SegmentVec_t = std::vector<std::unique_ptr<Segment>>
 Abbrivation of the final segment vector.
typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

StripOrient classifyStrip (const SpacePoint &spacePoint) const
 Determines the orientation of the strip space point.
UsedHitMarker_t emptyBookKeeper (const HitLayVec &sortedSp) const
 Constructs an empty HitMarker from the split space points.
HitWindow hitFromIPCorridor (const SpacePoint &testHit, const Amg::Vector3D &beamSpotPos, const Amg::Vector3D &dirEstUp, const Amg::Vector3D &dirEstDn) const
 The hit is above the predefined corridor.
void constructPreliminarySeeds (const Amg::Vector3D &beamSpot, const HitLaySpan_t &combinatoricLayers, const UsedHitSpan_t &usedHits, InitialSeedVec_t &outVec) const
 Construct a set of prelimnary seeds from the selected combinatoric layers.
std::unique_ptr< SegmentSeedconstructCombinatorialSeed (const InitialSeed_t &initialSeed, const AmgSymMatrix(2)&bMatrix, const HoughMaximum &max, const HitLaySpan_t &extensionLayers, const UsedHitSpan_t &usedHits) const
 Construct a combinatorial seed from the initial 4-layer seed hits.
std::pair< SegmentSeedVec_t, SegmentVec_tbuildSegmentsFromMM (const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const HitLayVec &hitLayers, const HoughMaximum &max, const Amg::Vector3D &beamSpotPos, UsedHitMarker_t &usedHits, bool useOnlyMM) const
 Build the final segment seed from strip like measurements using the combinatorial seeding for MicroMegas (or strip measurements) logic.
std::pair< SegmentSeedVec_t, SegmentVec_tbuildSegmentsFromSTGC (const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const HitLayVec &hitLayers, const HoughMaximum &max, const Amg::Vector3D &beamSpotPos, UsedHitMarker_t &usedHits) const
 Build the segment for a seed from STGC 2D measurement layers directly and then attempt to append hits from the other layers.
std::unique_ptr< SegmentfitSegmentSeed (const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const SegmentSeed *patternSeed) const
 Fit the segment seeds.
void processSegment (std::unique_ptr< Segment > segment, const HitVec &seedHits, const HitLayVec &hitLayers, UsedHitMarker_t &usedHits, SegmentVec_t &segments) const
 Process the segment and mark the hits if it is successfully built or not by differently mark the hits as used.
void markHitsAsUsed (const HitVec &spacePoints, const HitLayVec &allSortHits, UsedHitMarker_t &usedHitMarker, unsigned int increase, bool markNeighborHits) const
 Hits that are used in a good seed/segment built should be flagged as used and not contribute to other seed.
HitVec extendHits (const Amg::Vector3D &startPos, const Amg::Vector3D &direction, const HitLaySpan_t &extensionLayers, const UsedHitSpan_t &usedHits) const
 Extend the seed with the hits from the other layers.
std::pair< SegmentSeedVec_t, SegmentVec_tfindSegmentsFromMaximum (const HoughMaximum &max, const ActsTrk::GeometryContext &gctx, const EventContext &ctx) const
 Find seed and segment from an eta hough maximum.
Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Private Attributes

SG::ReadHandleKey< EtaHoughMaxContainerm_etaKey {this, "CombinatorialReadKey", "MuonHoughNswMaxima"}
SG::WriteHandleKey< SegmentSeedContainerm_writeSegmentSeedKey {this, "MuonNswSegmentSeedWriteKey", "MuonNswSegmentSeeds"}
SG::WriteHandleKey< SegmentContainerm_writeSegmentKey {this, "MuonNswSegmentWriteKey", "MuonNswSegments"}
SG::ReadHandleKey< ActsTrk::GeometryContextm_geoCtxKey {this, "AlignmentKey", "ActsAlignment", "cond handle key"}
ServiceHandle< Muon::IMuonIdHelperSvcm_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
ToolHandle< MuonValR4::IPatternVisualizationToolm_visionTool {this, "VisualizationTool", ""}
 Pattern visualization tool.
ToolHandle< ISpacePointCalibratorm_calibTool {this, "Calibrator", "" }
std::unique_ptr< SegmentFit::SegmentLineFitterm_lineFitter {}
DoubleProperty m_windowTheta {this, "thetaWindow", 2.5 * Gaudi::Units::deg}
DoubleProperty m_minPullThreshold {this, "maxPull", 5.}
UnsignedIntegerProperty m_minSeedHits {this, "minSeedHits", 6}
UnsignedIntegerProperty m_maxInvalidClusters {this, "maxInvalidClusters", 4}
BooleanProperty m_markHitsFromSeed {this, "markHitsFromSeed", true}
BooleanProperty m_doOnlyMMCombinatorics {this, "doOnlyMMCombinatorics", false}
UnsignedIntegerProperty m_maxUsed {this, "maxHitIsUsed", 6}
UnsignedIntegerProperty m_minClusSize {this, "minClusterSize", 1}
DoubleProperty m_maxChi2 {this, "maxChi2", 5.}
UnsignedIntegerProperty m_maxClustersInLayer {this, "maxClustersInLayer", 8}
DoubleProperty m_maxdYWindow {this, "maxdYWindow", 4.*Gaudi::Units::cm}
DoubleProperty m_maxTanAlpha {this, "maxTanAlpha", 0.2}
BooleanProperty m_dumpSeedStatistics {this, "dumpStatistics", true}
BooleanProperty m_dumpObj {this, "dumpObj", false}
std::unique_ptr< SeedStatistics > m_seedCounter ATLAS_THREAD_SAFE {}
const MuonGMR4::MuonDetectorManagerm_detMgr {}
DataObjIDColl m_extendedExtraObjects
 Extra output dependency collection, extended by AthAlgorithmDHUpdate to add symlinks.
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default).
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default).
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

Definition at line 33 of file NswSegmentFinderAlg.h.

Member Typedef Documentation

◆ HitLaySpan_t

using MuonR4::NswSegmentFinderAlg::HitLaySpan_t = std::vector<std::reference_wrapper<const HitVec>>
private

Abbrivation of the space comprising multiple hit vectors without copy.

Definition at line 112 of file NswSegmentFinderAlg.h.

◆ HitLayVec

◆ HitVec

◆ InitialSeed_t

Abbrivation of the initial seed.

Definition at line 118 of file NswSegmentFinderAlg.h.

◆ InitialSeedVec_t

Vector of initial seeds.

Definition at line 120 of file NswSegmentFinderAlg.h.

◆ SegmentSeedVec_t

using MuonR4::NswSegmentFinderAlg::SegmentSeedVec_t = std::vector<std::unique_ptr<SegmentSeed>>
private

Abbrivation of the seed vector.

Definition at line 125 of file NswSegmentFinderAlg.h.

◆ SegmentVec_t

using MuonR4::NswSegmentFinderAlg::SegmentVec_t = std::vector<std::unique_ptr<Segment>>
private

Abbrivation of the final segment vector.

Definition at line 127 of file NswSegmentFinderAlg.h.

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

◆ UsedHitMarker_t

using MuonR4::NswSegmentFinderAlg::UsedHitMarker_t = std::vector<std::vector<unsigned int>>
private

Abbrivation of the container book keeping whether a hit is used or not.

Definition at line 114 of file NswSegmentFinderAlg.h.

◆ UsedHitSpan_t

using MuonR4::NswSegmentFinderAlg::UsedHitSpan_t = std::vector<std::reference_wrapper<std::vector<unsigned int>>>
private

Abbrivation of the container to pass a subset of markers wtihout copy.

Definition at line 116 of file NswSegmentFinderAlg.h.

Member Enumeration Documentation

◆ HitWindow

enum class MuonR4::NswSegmentFinderAlg::HitWindow
strongprivate

To fastly check whether a hit is roughly compatible with a muon trajectory a narrow corridor is opened from the estimated beamspot to the first tested hit in the seed finding.

Hits in subsequent layers need to be within this corridor in order to be considered for seed construction. The HitWindow is the output classification of such a corridor test.

Enumerator
tooLow 
inside 

The hit is below the predefined corridor.

tooHigh 

The hit is inside the defined window and hence an initial candidate.

Definition at line 134 of file NswSegmentFinderAlg.h.

134 {tooLow,
135 inside,
136 tooHigh};

◆ StripOrient

enum class MuonR4::NswSegmentFinderAlg::StripOrient
strongprivate

Enumeration to classify the orientation of a NSW strip.

Enumerator

Stereo strips with positive angle.

Stereo strips with negative angle.

Ordinary eta strips.

Single phi measurements.

Unknown 

Combined 2D space point (sTGC wire + strip / sTgc pad).

Definition at line 45 of file NswSegmentFinderAlg.h.

45 {
46 U,
47 V,
48 X,
49 P,
50 C,
52 };
static Double_t P(Double_t *tt, Double_t *par)
@ Unknown
Definition TruthClasses.h:9
struct color C

Constructor & Destructor Documentation

◆ ~NswSegmentFinderAlg()

virtual MuonR4::NswSegmentFinderAlg::~NswSegmentFinderAlg ( )
virtualdefault

Member Function Documentation

◆ buildSegmentsFromMM()

std::pair< NswSegmentFinderAlg::SegmentSeedVec_t, NswSegmentFinderAlg::SegmentVec_t > MuonR4::NswSegmentFinderAlg::buildSegmentsFromMM ( const EventContext & ctx,
const ActsTrk::GeometryContext & gctx,
const HitLayVec & hitLayers,
const HoughMaximum & max,
const Amg::Vector3D & beamSpotPos,
UsedHitMarker_t & usedHits,
bool useOnlyMM ) const
private

Build the final segment seed from strip like measurements using the combinatorial seeding for MicroMegas (or strip measurements) logic.

Parameters
hitLayersReference to the hits of the strip layers
gctxThe geometry context
ctxThe event context
maxRefrence to the eta maximum from which the segment seed is constructed
beamSporPosThe beaspot position in the sector's frame to be used to constrain the hits selection
usedHitsRefrence to the book keeper of which of the hits on the extension was already used
useOnlyMM: Boolean to use only MM hits for the initial 4layer seed from the combinatorics

Definition at line 565 of file NswSegmentFinderAlg.cxx.

571 {
572
573 //go through the layers and build seeds from the combinations of hits
574 SegmentSeedVec_t seeds{};
575 SegmentVec_t segments{};
576 std::size_t layerSize = hitLayers.size();
577
578 if(layerSize < minLayers){
579 ATH_MSG_VERBOSE("Not enough layers to build a seed");
580 return {std::move(seeds), std::move(segments)};
581 }
582
583 //lamda helper to find the first unused strip hit on the layer
584 auto unusedStripHit = [&](const HitVec& layerHits, unsigned int layIdx) -> const SpacePoint* {
585 //in case of MM only combinatorial seeding - we consider only MM strip hits for seeding
586 bool isMM = useOnlyMM ? layerHits.front()->type() == xAOD::UncalibMeasType::MMClusterType : true;
587 for (auto [idx, hit] : Acts::enumerate(layerHits)) {
588 auto spOrient = classifyStrip(*hit);
589 bool isStrip = spOrient == StripOrient::X || spOrient == StripOrient::U || spOrient == StripOrient::V;
590 bool isUnused = usedHits[layIdx].at(idx) <= m_maxUsed;
591 if (isStrip && isUnused && isMM) {
592 return hit;
593 }
594 }
595 return nullptr;
596 };
597
598 std::array<const SpacePoint*, 4> seedHits{};
599 InitialSeedVec_t preLimSeeds{};
600
601 for (std::size_t i = 0; i < layerSize - 3; ++i) {
602 seedHits[0] = unusedStripHit(hitLayers[i], i);
603 if(!seedHits[0]) {
604 continue;
605 }
606 for (std::size_t j = i + 1; j < layerSize - 2; ++j) {
607 seedHits[1] = unusedStripHit(hitLayers[j], j);
608 if(!seedHits[1]){
609 continue;
610 }
611 for (std::size_t l = layerSize - 1; l > j+1; --l) {
612 seedHits[3] = unusedStripHit(hitLayers[l], l);
613 if(!seedHits[3]){
614 continue;
615 }
616 for (std::size_t k = l-1; k > j ; --k) {
617 seedHits[2] = unusedStripHit(hitLayers[k], k);
618 if(!seedHits[2]){
619 continue;
620 }
621
622 const HitLaySpan_t layers{hitLayers[i], hitLayers[j], hitLayers[k], hitLayers[l]};
623 //skip combination with at least one too busy layer
624 bool tooBusy = std::ranges::any_of(layers,
625 [this](const auto& layer) {
626 return layer.get().size() > m_maxClustersInLayer;
627 });
628 if (tooBusy) {
629 continue; // skip this combination
630 }
631
632 AmgSymMatrix(2) bMatrix = betaMatrix(seedHits);
633
634 if (std::abs(bMatrix.determinant()) < 1.e-6) {
635 continue;
636 }
637 ATH_MSG_DEBUG("Space point positions for seed layers: \n"
638 <<(*seedHits[0]) << ",\n"
639 <<(*seedHits[1]) << ",\n"
640 <<(*seedHits[2]) << ",\n"
641 <<(*seedHits[3]));
642
643
644 UsedHitSpan_t usedHitsSpan{usedHits[i], usedHits[j], usedHits[k], usedHits[l]};
645 // each layer may have more than one hit - take the hit combinations
646 constructPreliminarySeeds(beamSpotPos, layers, usedHitsSpan, preLimSeeds);
647
648 //the layers not participated in the seed build - gonna be used for the extension
649 HitLaySpan_t extensionLayers{};
650 UsedHitSpan_t usedExtensionHits{};
651 usedExtensionHits.reserve(hitLayers.size());
652 extensionLayers.reserve(hitLayers.size());
653 for (std::size_t e = 0 ; e < hitLayers.size(); ++e) {
654 if (!(e == i || e == j || e == k || e == l)){
655 extensionLayers.emplace_back(hitLayers[e]);
656 usedExtensionHits.emplace_back(usedHits[e]);
657 }
658 }
659 // we have made sure to have hits from all the four layers -
660 // start by 4 hits for the seed and try to build the extended seed for the combinatorics found
661 for (auto &combinatoricHits : preLimSeeds) {
662 auto seed = constructCombinatorialSeed(combinatoricHits, bMatrix, max, extensionLayers, usedExtensionHits);
663 if(!seed){
664 continue;
665 }
666 if (seed->getHitsInMax().size() < m_minSeedHits) {
667 seeds.push_back(std::move(seed));
668 continue;
669 }
670 std::unique_ptr<Segment> segment = fitSegmentSeed(ctx, gctx, seed.get());
671 processSegment(std::move(segment), seed->getHitsInMax(), hitLayers, usedHits, segments);
672 seeds.push_back(std::move(seed));
673
674 }
675 }
676 }
677 }
678 }
679 return std::make_pair(std::move(seeds),std::move(segments));
680}
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
#define AmgSymMatrix(dim)
if(pathvar)
#define max(a, b)
Definition cfImp.cxx:41
UnsignedIntegerProperty m_maxUsed
std::unique_ptr< SegmentSeed > constructCombinatorialSeed(const InitialSeed_t &initialSeed, const AmgSymMatrix(2)&bMatrix, const HoughMaximum &max, const HitLaySpan_t &extensionLayers, const UsedHitSpan_t &usedHits) const
Construct a combinatorial seed from the initial 4-layer seed hits.
UnsignedIntegerProperty m_maxClustersInLayer
std::unique_ptr< Segment > fitSegmentSeed(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const SegmentSeed *patternSeed) const
Fit the segment seeds.
std::vector< std::reference_wrapper< const HitVec > > HitLaySpan_t
Abbrivation of the space comprising multiple hit vectors without copy.
std::vector< std::unique_ptr< SegmentSeed > > SegmentSeedVec_t
Abbrivation of the seed vector.
void constructPreliminarySeeds(const Amg::Vector3D &beamSpot, const HitLaySpan_t &combinatoricLayers, const UsedHitSpan_t &usedHits, InitialSeedVec_t &outVec) const
Construct a set of prelimnary seeds from the selected combinatoric layers.
void processSegment(std::unique_ptr< Segment > segment, const HitVec &seedHits, const HitLayVec &hitLayers, UsedHitMarker_t &usedHits, SegmentVec_t &segments) const
Process the segment and mark the hits if it is successfully built or not by differently mark the hits...
SpacePointPerLayerSplitter::HitVec HitVec
std::vector< InitialSeed_t > InitialSeedVec_t
Vector of initial seeds.
StripOrient classifyStrip(const SpacePoint &spacePoint) const
Determines the orientation of the strip space point.
@ X
Stereo strips with negative angle.
@ V
Stereo strips with positive angle.
std::vector< std::unique_ptr< Segment > > SegmentVec_t
Abbrivation of the final segment vector.
UnsignedIntegerProperty m_minSeedHits
std::vector< std::reference_wrapper< std::vector< unsigned int > > > UsedHitSpan_t
Abbrivation of the container to pass a subset of markers wtihout copy.
layers(flags, cells_name, *args, **kw)
Here we define wrapper functions to set up all of the standard corrections.
constexpr unsigned minLayers
l
Printing final latex table to .tex output file.
@ layer
Definition HitInfo.h:79
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)

◆ buildSegmentsFromSTGC()

std::pair< NswSegmentFinderAlg::SegmentSeedVec_t, NswSegmentFinderAlg::SegmentVec_t > MuonR4::NswSegmentFinderAlg::buildSegmentsFromSTGC ( const EventContext & ctx,
const ActsTrk::GeometryContext & gctx,
const HitLayVec & hitLayers,
const HoughMaximum & max,
const Amg::Vector3D & beamSpotPos,
UsedHitMarker_t & usedHits ) const
private

Build the segment for a seed from STGC 2D measurement layers directly and then attempt to append hits from the other layers.

Parameters
hitLayers: Reference to the hits of the layers
gctxThe reference to the geometry context
ctxThe reference to the event context
maxRefrence to the eta maximum from which the segment seed is constructed
beamSpotPosThe beamspot position in the sector's frame to be used to constrain the hits selection
usedHitsRefrence to the book keeper of which of the hits on the extension was already used

Definition at line 465 of file NswSegmentFinderAlg.cxx.

470 {
471
472 //go through the layers and build seeds from the combinations of hits
473 //starting from the outermost layers with 2D measurements (excluding pads)
474 SegmentSeedVec_t seeds{};
475 SegmentVec_t segments{};
476 std::size_t layerSize = hitLayers.size();
477 double thetaWindowCut{std::cos(2*m_windowTheta)};
478
479 // lamda helper to check if the spacepoint is combined (but not pad) and unused in an already constructed seed
480 auto isUnusedCombined = [&](std::size_t layIdx, std::size_t hitIdx) -> bool {
481 const SpacePoint* sp = hitLayers[layIdx][hitIdx];
483 THROW_EXCEPTION("Space point is not of sTgc type: "<<sp->msSector()->idHelperSvc()->toString(sp->identify()));
484 }
485 const auto* prd = static_cast<const xAOD::sTgcMeasurement*>(sp->primaryMeasurement());
486 bool isCombined = sTgcChannelType(prd->channelType()) == "S" && sp->dimension() == 2;
487 bool isUnused = usedHits[layIdx].at(hitIdx) <= m_maxUsed;
488 return isCombined && isUnused;
489
490 };
491
492 // find the 2D measurements from the outermost layers - even move one layer inside
493 for(std::size_t layIdx1 = 0; layIdx1 < 2; ++layIdx1){
494 for(std::size_t layIdx2 = layerSize-1; layIdx2 >= layerSize-2; --layIdx2){
495 //in case of MM layers we stop - the layers are sorted in Z
496 if(hitLayers[layIdx1].front()->type() == xAOD::UncalibMeasType::MMClusterType ||
497 hitLayers[layIdx2].front()->type() == xAOD::UncalibMeasType::MMClusterType){
498 ATH_MSG_VERBOSE("Outermost layers are MM - stop searching for sTgc Measurements");
499 return std::make_pair(std::move(seeds), std::move(segments));
500 }
501
502 //check if we have 2D measurements on these layers that are unused (excluding the pads)
503 for(std::size_t hitIdx1 = 0; hitIdx1 < hitLayers[layIdx1].size(); ++hitIdx1) {
504 const SpacePoint* hit1 = hitLayers[layIdx1][hitIdx1];
505 if(!isUnusedCombined(layIdx1, hitIdx1)){
506 continue;
507 }
508 for(std::size_t hitIdx2 = 0; hitIdx2 < hitLayers[layIdx2].size(); ++hitIdx2) {
509 const SpacePoint* hit2 = hitLayers[layIdx2][hitIdx2];
510 if(!isUnusedCombined(layIdx2, hitIdx2)){
511 continue;
512 }
513 //test if this selection of the hits from the two layers is aligned with the beam spot
514 const Amg::Vector3D beamSpotHitDir{(beamSpotPos - hit1->localPosition()).unit()};
515 const Amg::Vector3D seedDir{(hit2->localPosition() - hit1->localPosition()).unit()};
516 const double cosAngle = beamSpotHitDir.dot(seedDir);
517 //accept the deflection of direction with a tolerance of 1 deg
518 if(std::abs(cosAngle) < thetaWindowCut){
519 continue;
520 }
521 //found 2D hits on the outermost layers - build a seed
522 HitVec seedHits{hit1, hit2};
523 //get the seed direction and position from the two 2D hits
524 const Amg::Vector3D seedPos = hit1->localPosition();
525 //express position in z=0
526 const Amg::Vector3D seedPosZ0 = seedPos + Amg::intersect<3>(seedPos, seedDir, Amg::Vector3D::UnitZ(), 0.).value_or(0.)*seedDir;
527 // extend the seed to the other layers
528 HitLaySpan_t extensionLayers{};
529 UsedHitSpan_t usedExtensionHits{};
530 extensionLayers.reserve(hitLayers.size());
531 usedExtensionHits.reserve(hitLayers.size());
532 for (std::size_t e = 0 ; e < hitLayers.size(); ++e) {
533 if (!(e == layIdx1 || e == layIdx2)){
534 extensionLayers.emplace_back(hitLayers[e]);
535 usedExtensionHits.emplace_back(usedHits[e]);
536 }
537 }
538 auto extendedHits = extendHits(seedPosZ0, seedDir, extensionLayers, usedExtensionHits);
539 std::ranges::move(extendedHits, std::back_inserter(seedHits));
540
541 //make seed
542 auto seed = std::make_unique<SegmentSeed>(houghTanBeta(seedDir), seedPosZ0.y(),
543 houghTanAlpha(seedDir), seedPosZ0.x(),
544 seedHits.size(), std::move(seedHits),
545 max.parentBucket());
546
547 //skip segment fit with less than 5 hits
548 if(seed->getHitsInMax().size() < m_minSeedHits){
549 seeds.push_back(std::move(seed));
550 continue;
551 }
552 //fit the segment seed
553 std::unique_ptr<Segment> segment = fitSegmentSeed(ctx, gctx, seed.get());
554 processSegment(std::move(segment), seed->getHitsInMax(), hitLayers, usedHits, segments);
555 seeds.push_back(std::move(seed));
556
557 }
558 }
559 }
560 }
561 return std::make_pair(std::move(seeds),std::move(segments));
562}
static Double_t sp
HitVec extendHits(const Amg::Vector3D &startPos, const Amg::Vector3D &direction, const HitLaySpan_t &extensionLayers, const UsedHitSpan_t &usedHits) const
Extend the seed with the hits from the other layers.
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
Eigen::Matrix< double, 3, 1 > Vector3D
double houghTanBeta(const Amg::Vector3D &v)
Returns the hough tanBeta [y] / [z].
double houghTanAlpha(const Amg::Vector3D &v)
: Returns the hough tanAlpha [x] / [z]
sTgcMeasurement_v1 sTgcMeasurement
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10

◆ cardinality()

unsigned int AthCommonReentrantAlgorithm< Gaudi::Algorithm >::cardinality ( ) const
overridevirtualinherited

Cardinality (Maximum number of clones that can exist) special value 0 means that algorithm is reentrant.

Override this to return 0 for reentrant algorithms.

Definition at line 75 of file AthCommonReentrantAlgorithm.cxx.

62{
63 return 0;
64}

◆ classifyStrip()

NswSegmentFinderAlg::StripOrient MuonR4::NswSegmentFinderAlg::classifyStrip ( const SpacePoint & spacePoint) const
private

Determines the orientation of the strip space point.

Definition at line 124 of file NswSegmentFinderAlg.cxx.

124 {
125
127 const auto& design = getDesign(sp);
128 if (!design.hasStereoAngle()) {
129 return StripOrient::X;
130 }
131 return design.stereoAngle() > 0. ? StripOrient::U : StripOrient::V;
132 } else if (sp.type() == xAOD::UncalibMeasType::sTgcStripType) {
133 const auto* prd = static_cast<const xAOD::sTgcMeasurement*>(sp.primaryMeasurement());
134 if (sp.dimension() == 2) {
135 return StripOrient::C;
136 }
137 //check if we have strip only or wire only measurements
139
140 }
141 ATH_MSG_WARNING("Cannot classify orientation of "<<m_idHelperSvc->toString(sp.identify()));
143}
#define ATH_MSG_WARNING(x)
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
@ Unknown
Combined 2D space point (sTGC wire + strip / sTgc pad).
virtual sTgcChannelTypes channelType() const =0
Returns the channel type of the measurement (Pad/Wire/Strip).

◆ constructCombinatorialSeed()

std::unique_ptr< SegmentSeed > MuonR4::NswSegmentFinderAlg::constructCombinatorialSeed ( const InitialSeed_t & initialSeed,
const AmgSymMatrix(2)& bMatrix,
const HoughMaximum & max,
const HitLaySpan_t & extensionLayers,
const UsedHitSpan_t & usedHits ) const
private

Construct a combinatorial seed from the initial 4-layer seed hits.

Parameters
initialSeedReference to the hit quadruplet that may form a seed
bMatrixKernel matrix calculated from the layer configuration to construct the seed
maxRefrence to the eta maximum from which the segment seed is constructed
extensionLayersReference to the hits on the remaining layers of the detector
usedHitsRefrence to the book keeper of which of the hits on the extension was already used

Definition at line 337 of file NswSegmentFinderAlg.cxx.

341 {
342 bool allValid = std::any_of(initialSeed.begin(), initialSeed.end(),
343 [this](const auto& hit){
344 if (hit->type() == xAOD::UncalibMeasType::MMClusterType) {
345 const auto* mmClust = static_cast<const xAOD::MMCluster*>(hit->primaryMeasurement());
346 return mmClust->stripNumbers().size() >= m_minClusSize;
347 }
348 return true;
349 });
350
351 if (!allValid) {
352 ATH_MSG_VERBOSE("Seed rejection: Not all clusters meet minimum strip size");
353 return nullptr;
354 }
355
356
357 std::array<double, 4> params = defineParameters(bMatrix, initialSeed);
358
359 const auto [segPos, direction] = seedSolution(initialSeed, params);
360
361 // check the consistency of the parameters - expected to lay in the strip's
362 // length
363 for (std::size_t i = 0; i < 4; ++i) {
364 const double halfLength = stripHalfLength(*initialSeed[i]);
365
366 if (std::abs(params[i]) > halfLength) {
367 ATH_MSG_VERBOSE("Seed Rejection: Invalid seed - outside of the strip's length "<< m_idHelperSvc->toString(initialSeed[i]->identify())
368 <<", param: "<<params[i]<<", halfLength: "<<halfLength);
369 return nullptr;
370 }
371 }
372 double tanAlpha = houghTanAlpha(direction);
373 double tanBeta = houghTanBeta(direction);
374
375 double interceptX = segPos.x();
376 double interceptY = segPos.y();
377
378 //seed quality check - we expect the tanAlpha not to be too big which would mean big deflection along the strip layers
379 if(std::abs(tanAlpha) > m_maxTanAlpha){
380 ATH_MSG_VERBOSE("Seed Rejection: Invalid seed - tanAlpha "<<tanAlpha<<" above threshold "<<m_maxTanAlpha);
381 return nullptr;
382 }
383
384
385 // extend the seed to the segment -- include hits from the other layers too
386 auto extendedHits = extendHits(segPos, direction, extensionLayers, usedHits);
387 HitVec hits{initialSeed.begin(),initialSeed.end()};
388 std::ranges::move(extendedHits, std::back_inserter(hits));
389
390 return std::make_unique<SegmentSeed>(tanBeta, interceptY, tanAlpha,
391 interceptX, hits.size(),
392 std::move(hits), max.parentBucket());
393}
const Amg::Vector3D & direction() const
Method to retrieve the direction at the Intersection.

◆ constructPreliminarySeeds()

void MuonR4::NswSegmentFinderAlg::constructPreliminarySeeds ( const Amg::Vector3D & beamSpot,
const HitLaySpan_t & combinatoricLayers,
const UsedHitSpan_t & usedHits,
InitialSeedVec_t & outVec ) const
private

Construct a set of prelimnary seeds from the selected combinatoric layers.

Quadruplets of hits, one from each layer, are formed if they are all within the the corridor as described above

Parameters
beamSpotPosition of the beam spot in the sector's frame
combinatoricLayersQuadruplet of four hit vectors from which the hits are retrieved
usedHitsMask marking hits that were already successfully added to a seed
outVecReference to the output vector where the initial seeds are stored. The vector is cleared at the beginning and capacity is allocated accordingly

Assign enough memory to the vector

The hit is alrady in a good seed. Don't consider again

Construct the beamspot to first hit connection to guestimate the angle

Apply cut window on theta of the seed.

Definition at line 222 of file NswSegmentFinderAlg.cxx.

225 {
227 seedHitsFromLayers.clear();
228 std::size_t maxSize{1};
229 for (const HitVec& hitVec : combinatoricLayers) {
230 maxSize = maxSize * hitVec.size();
231 }
232 seedHitsFromLayers.reserve(maxSize);
233
234 unsigned iterLay0{0}, iterLay1{0}, iterLay2{0}, iterLay3{0};
235 unsigned startLay1{0}, startLay2{0}, startLay3{0};
236
237 for( ; iterLay0 < combinatoricLayers[0].get().size() ; ++iterLay0){
239 if (usedHits[0].get()[iterLay0] > m_maxUsed) {
240 continue;
241 }
242 const SpacePoint* hit0 = combinatoricLayers[0].get()[iterLay0];
244 const Amg::Vector3D initSeedDir{(beamSpot - hit0->localPosition()).unit()};
245 const Amg::Vector3D dirEstUp = Amg::dirFromAngles(initSeedDir.phi(), initSeedDir.theta() - m_windowTheta);
246 const Amg::Vector3D dirEstDn = Amg::dirFromAngles(initSeedDir.phi(), initSeedDir.theta() + m_windowTheta);
247
248 ATH_MSG_VERBOSE("Reference hit: "<<m_idHelperSvc->toString(hit0->identify())
249 <<", position: "<<Amg::toString(hit0->localPosition())
250 <<", seed dir: "<<Amg::toString(initSeedDir)
251 <<", seed plane: "<<Amg::toString(SeedingAux::extrapolateToPlane(beamSpot, initSeedDir, *hit0)));
253 for( iterLay1 = startLay1; iterLay1 < combinatoricLayers[1].get().size() ; ++iterLay1){
254 TEST_HIT_CORRIDOR(1, iterLay1, startLay1);
255 for( iterLay2 = startLay2; iterLay2 < combinatoricLayers[2].get().size() ; ++iterLay2){
256 TEST_HIT_CORRIDOR(2, iterLay2, startLay2);
257 for( iterLay3 = startLay3; iterLay3 < combinatoricLayers[3].get().size(); ++iterLay3){
258 TEST_HIT_CORRIDOR(3, iterLay3, startLay3);
259 seedHitsFromLayers.emplace_back(std::array{hit0, combinatoricLayers[1].get()[iterLay1],
260 combinatoricLayers[2].get()[iterLay2],
261 combinatoricLayers[3].get()[iterLay3]});
262 }
263 }
264 }
265 }
266}
#define TEST_HIT_CORRIDOR(LAYER, HIT_ITER, START_LAYER)
Macro to check whether a hit is compatible with the hit corridor.
size_t size() const
Number of registered mappings.
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Amg::Vector3D dirFromAngles(const double phi, const double theta)
Constructs a direction vector from the azimuthal & polar angles.
size_t maxSize() const
Return the maximum size of the map.
AthConfigFlags beamSpot(AthConfigFlags flags, str instanceName, str recoMode)

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ emptyBookKeeper()

NswSegmentFinderAlg::UsedHitMarker_t MuonR4::NswSegmentFinderAlg::emptyBookKeeper ( const HitLayVec & sortedSp) const
private

Constructs an empty HitMarker from the split space points.

Parameters
sortedSpList of space points sorted by layer

Definition at line 115 of file NswSegmentFinderAlg.cxx.

115 {
116 UsedHitMarker_t emptyKeeper(sortedSp.size());
117 for (std::size_t l = 0; l < sortedSp.size(); ++l) {
118 emptyKeeper[l].resize(sortedSp[l].size(), 0);
119 }
120 return emptyKeeper;
121}
std::vector< std::vector< unsigned int > > UsedHitMarker_t
Abbrivation of the container book keeping whether a hit is used or not.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ execute()

StatusCode MuonR4::NswSegmentFinderAlg::execute ( const EventContext & ctx) const
overridevirtual

Definition at line 889 of file NswSegmentFinderAlg.cxx.

889 {
890 // read the inputs
891 const EtaHoughMaxContainer *maxima{nullptr};
892 ATH_CHECK(SG::get( maxima, m_etaKey, ctx));
893
894 const ActsTrk::GeometryContext *gctx{nullptr};
895 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
896
897 // prepare our output collection
898 SG::WriteHandle writeSegments{m_writeSegmentKey, ctx};
899 ATH_CHECK(writeSegments.record(std::make_unique<SegmentContainer>()));
900
901 SG::WriteHandle writeSegmentSeeds{m_writeSegmentSeedKey, ctx};
902 ATH_CHECK(writeSegmentSeeds.record(std::make_unique<SegmentSeedContainer>()));
903
904 // we use the information from the previous eta-hough transform
905 // to get the combined hits that belong in the same maxima
906 for (const HoughMaximum *max : *maxima) {
907
908 auto [seeds, segments] = findSegmentsFromMaximum(*max, *gctx, ctx);
909
910 if (msgLvl(MSG::VERBOSE)) {
911 ATH_MSG_VERBOSE("Hits from Hough maximum");
912 for(const auto& hitMax : max->getHitsInMax()){
913 ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hitMax->identify())<<", "
914 <<Amg::toString(hitMax->localPosition())<<", dir: "
915 <<Amg::toString(hitMax->sensorDirection()));
916 }
917 }
918
919 for(auto& seed: seeds){
920
921 if (msgLvl(MSG::VERBOSE)){
922 std::stringstream sstr{};
923 sstr<<"Seed tanBeta = "<<seed->tanBeta()<<", y0 = "<<seed->interceptY()
924 <<", tanAlpha = "<<seed->tanAlpha()<<", x0 = "<<seed->interceptX()<<", hits in the seed "
925 <<seed->getHitsInMax().size()<<std::endl;
926
927 for(const auto& hit : seed->getHitsInMax()){
928 sstr<<" *** Hit "<<m_idHelperSvc->toString(hit->identify())<<", "
929 << Amg::toString(hit->localPosition())<<", dir: "<<Amg::toString(hit->sensorDirection())<<std::endl;
930 }
931 ATH_MSG_VERBOSE(sstr.str());
932 }
933 if (m_visionTool.isEnabled()) {
934 m_visionTool->visualizeSeed(ctx, *seed, "#phi-combinatorialSeed");
935 }
936
937 writeSegmentSeeds->push_back(std::move(seed));
938
939 }
940
941 for (auto &seg : segments) {
942 const Parameters pars = localSegmentPars(*gctx, *seg);
943
944 ATH_MSG_VERBOSE("Segment parameters : "<<toString(pars));
945
946 if (m_visionTool.isEnabled()) {
947 m_visionTool->visualizeSegment(ctx, *seg, "#phi-segment");
948 }
949
950 if(m_dumpObj){
951 Acts::ObjVisualization3D visualHelper{};
952 MuonValR4::drawSegmentMeasurements(*gctx, *seg, visualHelper);
953 MuonValR4::drawSegmentLine(*gctx, *seg, visualHelper);
954 visualHelper.write(std::format("Event_{:}_segment_{:}.obj", ctx.eventID().event_number(), seg->msSector()->identString()));
955 }
956
957 writeSegments->push_back(std::move(seg));
958
959 }
960 }
961
962 return StatusCode::SUCCESS;
963}
#define ATH_CHECK
Evaluate an expression and check for errors.
bool msgLvl(const MSG::Level lvl) const
std::pair< SegmentSeedVec_t, SegmentVec_t > findSegmentsFromMaximum(const HoughMaximum &max, const ActsTrk::GeometryContext &gctx, const EventContext &ctx) const
Find seed and segment from an eta hough maximum.
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
SG::WriteHandleKey< SegmentSeedContainer > m_writeSegmentSeedKey
SG::WriteHandleKey< SegmentContainer > m_writeSegmentKey
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
SG::ReadHandleKey< EtaHoughMaxContainer > m_etaKey
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
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.
DataVector< HoughMaximum > EtaHoughMaxContainer
void drawSegmentMeasurements(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw all uncalibrated measurements associated to the segment.
void drawSegmentLine(const ActsTrk::GeometryContext &gctx, const xAOD::MuonSegment &segment, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewLine, const double standardLength=1.*Gaudi::Units::m)
Draw a segment line inside the obj file.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.

◆ extendHits()

NswSegmentFinderAlg::HitVec MuonR4::NswSegmentFinderAlg::extendHits ( const Amg::Vector3D & startPos,
const Amg::Vector3D & direction,
const HitLaySpan_t & extensionLayers,
const UsedHitSpan_t & usedHits ) const
private

Extend the seed with the hits from the other layers.

Parameters
startPosThe seed position
directionThe seed direction
extensionLayersThe layers to which the seed is extended by extrapolation
usedHitsThe book keeping of the used hits to be skipped

Definition at line 270 of file NswSegmentFinderAlg.cxx.

273 {
274
275 //the hits we need to return to extend the segment seed
276 HitVec combinatoricHits;
277
278 for (std::size_t i = 0; i < extensionLayers.size(); ++i) {
279 const HitVec& layer{extensionLayers[i].get()};
280 const Amg::Vector3D extrapPos = SeedingAux::extrapolateToPlane(startPos, direction, *layer.front());
281
282
283 unsigned triedHit{0};
284 HitCandidate precisionHit, noPrecisionHit;
285 ATH_MSG_VERBOSE("Moving to next layer");
286
287 for (unsigned j = 0; j < layer.size(); ++j) {
288 if (usedHits[i].get().at(j) > m_maxUsed) {
289 continue;
290 }
291 auto hit = layer.at(j);
292 const double pull = std::sqrt(SeedingAux::chi2Term(extrapPos, direction, *hit));
293 ATH_MSG_VERBOSE("Trying extension with hit " << m_idHelperSvc->toString(hit->identify())<<" and pull "<<pull);
294 bool isPrecision = isPrecisionHit(*hit);
295 double minPull = isPrecision ? precisionHit.minPull : noPrecisionHit.minPull;
296 //find the hit with the minimum pull (check at least three hits after we have increasing pulls)
297 if (pull > minPull) {
298 triedHit+=1;
299 continue;
300 }
301
302 if(triedHit>3){
303 break;
304 }
305
306 if(isPrecision){
307 precisionHit.spacePoint = hit;
308 precisionHit.minPull = pull;
309 continue;
310 }
311
312 noPrecisionHit.spacePoint = hit;
313 noPrecisionHit.minPull = pull;
314 }
315
316 // complete the seed with the extended hits
317 //we first choose the precision hit and if does not exist then we pick the non precision hit
318 const SpacePoint* bestCand{nullptr};
319 if(precisionHit.minPull < m_minPullThreshold){
320 bestCand = precisionHit.spacePoint;
321 }else if(noPrecisionHit.minPull < m_minPullThreshold){
322 bestCand = noPrecisionHit.spacePoint;
323 }else{
324 ATH_MSG_VERBOSE("No hit found in layer "<<i<<" with pull below threshold "<<m_minPullThreshold);
325 continue;
326 }
327 ATH_MSG_VERBOSE("Extension successfull - hit" << m_idHelperSvc->toString(bestCand->identify())
328 <<", pos: "<<Amg::toString(bestCand->localPosition())
329 <<", dir: "<<Amg::toString(bestCand->sensorDirection()));
330 combinatoricHits.push_back(bestCand);
331 }
332
333 return combinatoricHits;
334}
mapped_type at(key_type key) const
Look up an element in the map.
bool isPrecisionHit(const SpacePoint &hit)
Returns whether the uncalibrated spacepoint is a precision hit (Mdt, micromegas, stgc strips).

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ extraOutputDeps()

const DataObjIDColl & AthCommonReentrantAlgorithm< Gaudi::Algorithm >::extraOutputDeps ( ) const
overridevirtualinherited

Return the list of extra output dependencies.

This list is extended to include symlinks implied by inheritance relations.

Definition at line 94 of file AthCommonReentrantAlgorithm.cxx.

88{
89 // If we didn't find any symlinks to add, just return the collection
90 // from the base class. Otherwise, return the extended collection.
91 if (!m_extendedExtraObjects.empty()) {
93 }
95}
An algorithm that can be simultaneously executed in multiple threads.

◆ filterPassed()

virtual bool AthCommonReentrantAlgorithm< Gaudi::Algorithm >::filterPassed ( const EventContext & ctx) const
inlinevirtualinherited

Definition at line 96 of file AthCommonReentrantAlgorithm.h.

96 {
97 return execState( ctx ).filterPassed();
98 }
virtual bool filterPassed(const EventContext &ctx) const

◆ finalize()

StatusCode MuonR4::NswSegmentFinderAlg::finalize ( )
overridevirtual

Definition at line 965 of file NswSegmentFinderAlg.cxx.

965 {
966 if(m_seedCounter) {
967 m_seedCounter->printTableSeedStats(msgStream());
968 }
969 return StatusCode::SUCCESS;
970}

◆ findSegmentsFromMaximum()

std::pair< NswSegmentFinderAlg::SegmentSeedVec_t, NswSegmentFinderAlg::SegmentVec_t > MuonR4::NswSegmentFinderAlg::findSegmentsFromMaximum ( const HoughMaximum & max,
const ActsTrk::GeometryContext & gctx,
const EventContext & ctx ) const
private

Find seed and segment from an eta hough maximum.

Parameters
maxThe maximum from the eta hough transform
gctxThe geometry Context
ctxThe event context

Definition at line 683 of file NswSegmentFinderAlg.cxx.

685 {
686 // first sort the hits per layer from the maximum
687 SpacePointPerLayerSplitter hitLayers{max.getHitsInMax()};
688
689 const HitLayVec& stripHitsLayers{hitLayers.stripHits()};
690 const std::size_t layerSize = stripHitsLayers.size();
691
692 //seeds and segments containers
693 SegmentSeedVec_t seeds{};
694 SegmentVec_t segments{};
695
696 const Amg::Transform3D globToLocal = max.msSector()->globalToLocalTransform(gctx);
697 //counters for the number of seeds, extented seeds and segments
698
699 if (layerSize < minLayers) {
700 ATH_MSG_VERBOSE("Not enough layers to build a seed");
701 return std::make_pair(std::move(seeds),std::move(segments));
702 }
703
704 if (m_visionTool.isEnabled()) {
706 constexpr double legX{0.2};
707 double legY{0.8};
708 for (const SpacePoint* sp : max.getHitsInMax()) {
709 const xAOD::MuonSimHit* simHit = getTruthMatchedHit(*sp->primaryMeasurement());
710 if (!simHit) {
711 continue;
712 }
713
714 const MuonGMR4::MuonReadoutElement* reEle = m_detMgr->getReadoutElement(simHit->identify());
715 const Amg::Transform3D toChamb = reEle->msSector()->globalToLocalTransform(gctx) *
716 reEle->localToGlobalTransform(gctx, sp->identify());
717
718 const Amg::Vector3D hitPos = toChamb * xAOD::toEigen(simHit->localPosition());
719 const Amg::Vector3D hitDir = toChamb.linear() * xAOD::toEigen(simHit->localDirection());
720 const double pull = std::sqrt(SeedingAux::chi2Term(hitPos, hitDir, *sp));
721
723 const auto* mmClust = static_cast<const xAOD::MMCluster*>(sp->primaryMeasurement());
724 const MuonGMR4::MmReadoutElement* mmEle = mmClust->readoutElement();
725 const auto& design = mmEle->stripLayer(mmClust->measurementHash()).design();
726 std::string stereoDesign{!design.hasStereoAngle() ? "X" : design.stereoAngle() >0 ? "U": "V"};
727 primitives.push_back(MuonValR4::drawLabel(std::format("ml: {:1d}, gap: {:1d}, {:}, pull: {:.2f}",
728 mmEle->multilayer(), mmClust->gasGap(),
729 stereoDesign, pull), legX, legY, 14));
730 } else if(sp->type() == xAOD::UncalibMeasType::sTgcStripType) {
731 const auto* sTgcMeas = static_cast<const xAOD::sTgcMeasurement*>(sp->primaryMeasurement());
732 std::string channelString = sp->secondaryMeasurement() == nullptr ?
733 sTgcChannelType(sTgcMeas->channelType()) :
734 std::format("{:}/{:}", sTgcChannelType(sTgcMeas->channelType()),
735 sTgcChannelType(static_cast<const xAOD::sTgcMeasurement*>(sp->secondaryMeasurement())->channelType()));
736 primitives.push_back(MuonValR4::drawLabel(std::format("ml: {:1d}, gap: {:1d}, type: {:}, pull: {:.2f}",
737 sTgcMeas->readoutElement()->multilayer(), sTgcMeas->gasGap(),
738 channelString, pull), legX, legY, 14));
739 }
740 legY-=0.05;
741 }
742 m_visionTool->visualizeBucket(ctx, *max.parentBucket(),
743 "truth", std::move(primitives));
744 }
745
746 //dump spacepoints associated with truth sim hits to an obj file
747 if(m_dumpObj){
748 Acts::ObjVisualization3D visualHelper{};
749 for (const SpacePoint* sp : max.getHitsInMax()) {
750 const xAOD::MuonSimHit* simHit = getTruthMatchedHit(*sp->primaryMeasurement());
751 if (!simHit) {
752 continue;
753 }
754 MuonValR4::drawSpacePoint(gctx, *sp, visualHelper);
755 }
756 visualHelper.write(std::format("Event_{:}_{:}_spacepoints_truth.obj", ctx.eventID().event_number(), max.getHitsInMax().front()->chamber()->identString()));
757 }
758
759
760 UsedHitMarker_t allUsedHits = emptyBookKeeper(stripHitsLayers);
761 std::size_t nSeeds{0}, nExtSeeds{0}, nSegments{0}; //for the seed statistics
762
763 // helper lamda function to increase counters and fill the seeds and segments we want to return after we construct them
764 // the extended seeds are returned even if they did not make it to a segment and the segments only if successfully fitted
765 auto processSeedsAndSegments = [&](std::pair<SegmentSeedVec_t, SegmentVec_t>&& seedSegmentPairs, std::string_view source) {
766 auto& [returnSeeds, returnSegments] = seedSegmentPairs;
767 ATH_MSG_DEBUG("From " << source << ": built " << returnSeeds.size() << " seeds and " << returnSegments.size() << " segments.");
768 for(auto& seed : returnSeeds) {
769 ++nSeeds;
770 Acts::ObjVisualization3D visualHelper{};
771 if(seed->getHitsInMax().size() < m_minSeedHits){
772 ATH_MSG_VERBOSE("Seed with "<< seed->getHitsInMax().size() <<" hits rejected");
773 for(const auto& hit : seed->getHitsInMax()){
774 ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hit->identify())<<", "
775 <<Amg::toString(hit->localPosition())<<", dir: "
776 <<Amg::toString(hit->sensorDirection()));
777 if(m_dumpObj){
778 MuonValR4::drawSpacePoint(gctx, *hit, visualHelper);
779 }
780
781 }
782 if(m_dumpObj){
783 visualHelper.write(std::format("Event_{:}_{:}_notExtendedSeed.obj", ctx.eventID().event_number(), seed->getHitsInMax().front()->chamber()->identString()));
784 }
785 continue;
786 }
787 ++nExtSeeds;
788 seeds.push_back(std::move(seed));
789 }
790 //move all the segments to the output container
791 std::ranges::move(returnSegments, std::back_inserter(segments));
792 nSegments += returnSegments.size();
793 };
794
795 //Start from outermost sTgc layers with combined 2D measurements
796 ATH_MSG_VERBOSE("Start building seed from sTgc outermost layers");
797 processSeedsAndSegments(buildSegmentsFromSTGC(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits), "sTgc segment seeds");
798
799 //continue with the combinatorial seeding for the strip measurements
801
802 ATH_MSG_VERBOSE("Start building combinatoric seeds only from Micromegas");
803 processSeedsAndSegments(buildSegmentsFromMM(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits, true), "MM combinatoric segment seeds");
804
805 }else{
806
807 ATH_MSG_VERBOSE("Start building combinatoric seeds from Micromegas and sTgc hits");
808 processSeedsAndSegments(buildSegmentsFromMM(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits, true), "MM combinatoric segment seeds");
809 processSeedsAndSegments(buildSegmentsFromMM(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits, false), "MM and STGC combinatoric segment seeds");
810
811 }
812
813 if(m_seedCounter) {
814 m_seedCounter->addToStat(max.msSector(), nSeeds, nExtSeeds, nSegments);
815 }
816
817 return std::make_pair(std::move(seeds),std::move(segments));
818}
const StripLayer & stripLayer(const Identifier &measId) const
int multilayer() const
Returns the multi layer of the element [1-2].
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the local coordinate system of the readout element into the global AT...
const SpectrometerSector * msSector() const
Returns the pointer to the envelope volume enclosing all chambers in the sector.
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
const StripDesign & design(bool phiView=false) const
Returns the underlying strip design.
const MuonGMR4::MuonDetectorManager * m_detMgr
std::pair< SegmentSeedVec_t, SegmentVec_t > buildSegmentsFromMM(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const HitLayVec &hitLayers, const HoughMaximum &max, const Amg::Vector3D &beamSpotPos, UsedHitMarker_t &usedHits, bool useOnlyMM) const
Build the final segment seed from strip like measurements using the combinatorial seeding for MicroMe...
std::pair< SegmentSeedVec_t, SegmentVec_t > buildSegmentsFromSTGC(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const HitLayVec &hitLayers, const HoughMaximum &max, const Amg::Vector3D &beamSpotPos, UsedHitMarker_t &usedHits) const
Build the segment for a seed from STGC 2D measurement layers directly and then attempt to append hits...
UsedHitMarker_t emptyBookKeeper(const HitLayVec &sortedSp) const
Constructs an empty HitMarker from the split space points.
SpacePointPerLayerSplitter::HitLayVec HitLayVec
const MuonGMR4::MmReadoutElement * readoutElement() const override final
Retrieve the associated MmReadoutElement.
ConstVectorMap< 3 > localDirection() const
Returns the local direction of the traversing particle.
Identifier identify() const
Returns the global ATLAS identifier of the SimHit.
ConstVectorMap< 3 > localPosition() const
Returns the local postion of the traversing particle.
Eigen::Affine3d Transform3D
const
helper method to get the collection index (into m_inputCollectionsName) and tuple index (into m_tuple...
const xAOD::MuonSimHit * getTruthMatchedHit(const xAOD::MuonMeasurement &prdHit)
Returns the MuonSimHit, if there's any, matched to the uncalibrated muon measurement.
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const double textSize=18, const bool useNDC=true, const int color=kBlack)
Create a TLatex label,.
void drawSpacePoint(const ActsTrk::GeometryContext &gctx, const MuonR4::SpacePoint &spacePoint, Acts::ObjVisualization3D &visualHelper, const Acts::ViewConfig &viewConfig=Acts::s_viewSensitive)
Draw an uncalibrated space point inside the obj file.
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12
MMCluster_v1 MMCluster

◆ fitSegmentSeed()

std::unique_ptr< Segment > MuonR4::NswSegmentFinderAlg::fitSegmentSeed ( const EventContext & ctx,
const ActsTrk::GeometryContext & gctx,
const SegmentSeed * patternSeed ) const
private

Fit the segment seeds.

Parameters
ctxThe reference to the event context
gctxThe reference to the Geometry Context
patternSeedThe pointer to the seed of which we fit the calibrated space points

Definition at line 396 of file NswSegmentFinderAlg.cxx.

398 {
399
400 if(patternSeed->getHitsInMax().size() < m_minSeedHits){
401 ATH_MSG_VERBOSE("Not enough hits in the SegmentSeed to fit a segment");
402 return nullptr;
403 }
404
405 ATH_MSG_VERBOSE("Fit the SegmentSeed");
406 if (msgLvl(MSG::VERBOSE)) {
407 std::stringstream hitStream{};
408 for (const auto& hit : patternSeed->getHitsInMax()) {
409 hitStream<<"**** "<< (*hit)<<std::endl;
410 }
411 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Uncalibrated space points for the segment fit: "<<std::endl
412 <<hitStream.str());
413 }
414
415 //Calibration of the seed spacepoints
416 CalibSpacePointVec calibratedHits = m_calibTool->calibrate(ctx, patternSeed->getHitsInMax(),
417 patternSeed->localPosition(),
418 patternSeed->localDirection(), 0.);
419
420 const Amg::Transform3D& locToGlob{patternSeed->msSector()->localToGlobalTransform(gctx)};
421
422 return m_lineFitter->fitSegment(ctx, patternSeed, patternSeed->parameters(),
423 locToGlob, std::move(calibratedHits));
424}
std::unique_ptr< SegmentFit::SegmentLineFitter > m_lineFitter
ToolHandle< ISpacePointCalibrator > m_calibTool
ISpacePointCalibrator::CalibSpacePointVec CalibSpacePointVec

◆ hitFromIPCorridor()

NswSegmentFinderAlg::HitWindow MuonR4::NswSegmentFinderAlg::hitFromIPCorridor ( const SpacePoint & testHit,
const Amg::Vector3D & beamSpotPos,
const Amg::Vector3D & dirEstUp,
const Amg::Vector3D & dirEstDn ) const
inlineprivate

The hit is above the predefined corridor.

Tests whether a hit is inside the corridor defined by line connecting the centre of the first candidate hit in the seed and the beam spot. The theta angle is varied by m_windowTheta to define the lower & upper direction etimate. The function tests whether the strip then crosses the corridor.

Parameters
testHitReference to the hit to test
beamSpotPosPosition of the beam spot serving as starting point
dirEstUpDirection vector defining the upper limit of the corridor
dirEstDnDirection vector defining the lower limit of the corridor

Calculate the strip edges

Check whether the both edges are below the lower estimated muon arrival

Analogous check for the upper edge

No extrapolation needed

Analogous check for the upper edge

Definition at line 145 of file NswSegmentFinderAlg.cxx.

148 {
149
150 const Amg::Vector3D estPlaneArrivalUp = SeedingAux::extrapolateToPlane(beamSpotPos, dirEstUp, testHit);
151 const Amg::Vector3D estPlaneArrivalDn = SeedingAux::extrapolateToPlane(beamSpotPos, dirEstDn, testHit);
152
153 bool below{true}, above{true};
154 switch (classifyStrip(testHit)) {
155 using enum StripOrient;
156 case U:
157 case V:{
158 const double halfLength = 0.5* stripHalfLength(testHit);
160 const Amg::Vector3D leftEdge = testHit.localPosition() - halfLength * testHit.sensorDirection();
161 const Amg::Vector3D rightEdge = testHit.localPosition() + halfLength * testHit.sensorDirection();
162
164 below = estPlaneArrivalDn.y() > std::max(leftEdge.y(), rightEdge.y());
166 above = estPlaneArrivalUp.y() < std::min(leftEdge.y(), rightEdge.y());
167 break;
168 } case X:
169 case C: {
171 const double hY = testHit.localPosition().y();
172 below = estPlaneArrivalDn.y() > hY;
174 above = estPlaneArrivalUp.y() < hY;
175 break;
176 }
177 case P:{
178 break;
179 }
180 case Unknown:{
181 break;
182 }
183
184 }
185 ATH_MSG_VERBOSE("Hit " << m_idHelperSvc->toString(testHit.identify())
186 << (below || above ? " is outside the window" : " is inside the window"));
187 if(below) {
188 return HitWindow::tooLow;
189 }
190 if(above) {
191 return HitWindow::tooHigh;
192 }
193 return HitWindow::inside;
194};
@ inside
The hit is below the predefined corridor.
@ tooHigh
The hit is inside the defined window and hence an initial candidate.
StripOrient
Enumeration to classify the orientation of a NSW strip.

◆ initialize()

StatusCode MuonR4::NswSegmentFinderAlg::initialize ( )
overridevirtual

Definition at line 83 of file NswSegmentFinderAlg.cxx.

83 {
84 ATH_CHECK(m_geoCtxKey.initialize());
85 ATH_CHECK(m_etaKey.initialize());
86 ATH_CHECK(m_writeSegmentKey.initialize());
87 ATH_CHECK(m_writeSegmentSeedKey.initialize());
88 ATH_CHECK(m_idHelperSvc.retrieve());
89 ATH_CHECK(m_calibTool.retrieve());
90 ATH_CHECK(m_visionTool.retrieve(DisableTool{m_visionTool.empty()}));
91 ATH_CHECK(detStore()->retrieve(m_detMgr));
92
93 if (!(m_idHelperSvc->hasMM() || m_idHelperSvc->hasSTGC())) {
94 ATH_MSG_ERROR("MM or STGC not part of initialized detector layout");
95 return StatusCode::FAILURE;
96 }
97
98 SegmentLineFitter::Config fitCfg{};
99 fitCfg.calibrator = m_calibTool.get();
100 fitCfg.visionTool = m_visionTool.get();
101 fitCfg.calcAlongStrip = false;
102 fitCfg.idHelperSvc = m_idHelperSvc.get();
103 fitCfg.parsToUse = {ParamDefs::x0, ParamDefs::y0, ParamDefs::theta, ParamDefs::phi};
104
105 m_lineFitter = std::make_unique<SegmentFit::SegmentLineFitter>(name(), std::move(fitCfg));
106
108 m_seedCounter = std::make_unique<SeedStatistics>();
109 }
110
111 return StatusCode::SUCCESS;
112}
#define ATH_MSG_ERROR(x)
const ServiceHandle< StoreGateSvc > & detStore() const

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ isClonable()

◆ markHitsAsUsed()

void MuonR4::NswSegmentFinderAlg::markHitsAsUsed ( const HitVec & spacePoints,
const HitLayVec & allSortHits,
UsedHitMarker_t & usedHitMarker,
unsigned int increase,
bool markNeighborHits ) const
private

Hits that are used in a good seed/segment built should be flagged as used and not contribute to other seed.

Parameters
spacePointsThe space points to be marked as used
allSortHitsAll the available hits
usedHitMarkerThe book keeping of the hits
increaseThe hit counter increase
markNeighborHitsFlag wether to mark hits on the layer in the vicinity
Todo
use the localMeasurementPos of the measurement?
Todo
use the localMeasurementPos of the measurement?

Definition at line 820 of file NswSegmentFinderAlg.cxx.

824 {
825
826 SpacePointPerLayerSorter layerSorter{};
827
828 for(const auto& sp : spacePoints){
829 // Proection against the auxiliary measurement
830 if(!sp){
831 continue;
832 }
833
834 unsigned measLayer = layerSorter.sectorLayerNum(*sp);
835
836 Amg::Vector2D spPosX{Amg::Vector2D::Zero()};
838 switch (sp->primaryMeasurement()->numDimensions()) {
839 case 1:
840 spPosX[Amg::x] = sp->primaryMeasurement()->localPosition<1>().x();
841 break;
842 case 2:
843 spPosX = xAOD::toEigen(sp->primaryMeasurement()->localPosition<2>());
844 break;
845 default:
846 THROW_EXCEPTION("Unsupported dimension");
847 }
848
849 for (std::size_t lIdx = 0; lIdx < allSortHits.size(); ++lIdx) {
850 const HitVec& hVec{allSortHits[lIdx]};
851 //check if they are not in the same layer
852 unsigned hitLayer = layerSorter.sectorLayerNum(*hVec.front());
853 if(hitLayer != measLayer) {
854 ATH_MSG_VERBOSE("Not in the same layer since measLayer = "<< measLayer << " and "<<hitLayer);
855 continue;
856 }
857 for (std::size_t hIdx = 0 ; hIdx < hVec.size(); ++hIdx) {
858 //check the dY between the measurement and the hits
859 auto testHit = hVec[hIdx];
860 if (testHit == sp) {
861 usedHitMarker[lIdx][hIdx] += incr;
862 if(!markNeighborHits){
863 break;
864 }
865 } else if (markNeighborHits) {
866 Amg::Vector2D testPosX{Amg::Vector2D::Zero()};
868 switch (testHit->primaryMeasurement()->numDimensions()) {
869 case 1:
870 testPosX[Amg::x] = testHit->primaryMeasurement()->localPosition<1>().x();
871 break;
872 case 2:
873 testPosX = xAOD::toEigen(testHit->primaryMeasurement()->localPosition<2>());
874 break;
875 default:
876 THROW_EXCEPTION("Unsupported dimension");
877 }
878 //if the hit not found let's see if it is too close to the segment's measurement
879 double deltaX = (testPosX - spPosX).mag();
880 if(deltaX < m_maxdYWindow){
881 usedHitMarker[lIdx][hIdx] += incr;
882 }
883 }
884 }
885 }
886 }
887}
Scalar mag() const
mag method
#define x
Eigen::Matrix< double, 2, 1 > Vector2D

◆ msg()

MsgStream & AthCommonMsg< Gaudi::Algorithm >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< Gaudi::Algorithm >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ processSegment()

void MuonR4::NswSegmentFinderAlg::processSegment ( std::unique_ptr< Segment > segment,
const HitVec & seedHits,
const HitLayVec & hitLayers,
UsedHitMarker_t & usedHits,
SegmentVec_t & segments ) const
private

Process the segment and mark the hits if it is successfully built or not by differently mark the hits as used.

Parameters
segmentThe segment to process
seedHitsThe seed hits which the segments is constructed from
hitLayersThe layers contributed to the seed
usedHitsThe reference of the book keeper for the hits to mark as used
segmentsReference to the segments otuput vector where the successfully built segments are stored

Definition at line 426 of file NswSegmentFinderAlg.cxx.

430 {
431
432 if (!segment) {
433 ATH_MSG_VERBOSE("Seed Rejection: Segment fit failed");
434
435 if (m_markHitsFromSeed && seedHits.size() > m_minSeedHits) {
436 // Mark hits from extended seed (used increment by 1)
437 markHitsAsUsed(seedHits, hitLayers, usedHits, 1, false);
438 }
439 return;
440 }
441
442 // -------- success path --------
443 ATH_MSG_DEBUG("Segment built with "
444 << segment->measurements().size()
445 << " hits, chi2/ndof: "
446 << segment->chi2() / std::max(1u,segment->nDoF()));
447
448 HitVec segMeasSP;
449 segMeasSP.reserve(segment->measurements().size());
450
451 std::ranges::transform(
452 segment->measurements(),
453 std::back_inserter(segMeasSP),
454 [](const auto& m) { return m->spacePoint(); }
455 );
456
457 // Mark segment hits as fully used (used increment by 10,
458 // hits are effectively removed)
459 markHitsAsUsed(segMeasSP, hitLayers, usedHits, 10, true);
460 segments.push_back(std::move(segment));
461
462}
void markHitsAsUsed(const HitVec &spacePoints, const HitLayVec &allSortHits, UsedHitMarker_t &usedHitMarker, unsigned int increase, bool markNeighborHits) const
Hits that are used in a good seed/segment built should be flagged as used and not contribute to other...

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ setFilterPassed()

virtual void AthCommonReentrantAlgorithm< Gaudi::Algorithm >::setFilterPassed ( bool state,
const EventContext & ctx ) const
inlinevirtualinherited

Definition at line 100 of file AthCommonReentrantAlgorithm.h.

100 {
102 }
virtual void setFilterPassed(bool state, const EventContext &ctx) const

◆ sysExecute()

StatusCode AthCommonReentrantAlgorithm< Gaudi::Algorithm >::sysExecute ( const EventContext & ctx)
overridevirtualinherited

Execute an algorithm.

We override this in order to work around an issue with the Algorithm base class storing the event context in a member variable that can cause crashes in MT jobs.

Definition at line 85 of file AthCommonReentrantAlgorithm.cxx.

75{
76 return BaseAlg::sysExecute (ctx);
77}

◆ sysInitialize()

StatusCode AthCommonReentrantAlgorithm< Gaudi::Algorithm >::sysInitialize ( )
overridevirtualinherited

Override sysInitialize.

Override sysInitialize from the base class.

Loop through all output handles, and if they're WriteCondHandles, automatically register them and this Algorithm with the CondSvc

Scan through all outputHandles, and if they're WriteCondHandles, register them with the CondSvc

Reimplemented from AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >.

Reimplemented in HypoBase, and InputMakerBase.

Definition at line 61 of file AthCommonReentrantAlgorithm.cxx.

105 {
107
108 if (sc.isFailure()) {
109 return sc;
110 }
111
112 ServiceHandle<ICondSvc> cs("CondSvc",name());
113 for (auto h : outputHandles()) {
114 if (h->isCondition() && h->mode() == Gaudi::DataHandle::Writer) {
115 // do this inside the loop so we don't create the CondSvc until needed
116 if ( cs.retrieve().isFailure() ) {
117 ATH_MSG_WARNING("no CondSvc found: won't autoreg WriteCondHandles");
118 return StatusCode::SUCCESS;
119 }
120 if (cs->regHandle(this,*h).isFailure()) {
122 ATH_MSG_ERROR("unable to register WriteCondHandle " << h->fullKey()
123 << " with CondSvc");
124 }
125 }
126 }
127 return sc;
128}
virtual std::vector< Gaudi::DataHandle * > outputHandles() const override

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }

Member Data Documentation

◆ ATLAS_THREAD_SAFE

std::unique_ptr<SeedStatistics> m_seedCounter MuonR4::NswSegmentFinderAlg::ATLAS_THREAD_SAFE {}
private

Definition at line 321 of file NswSegmentFinderAlg.h.

321{};

◆ m_calibTool

ToolHandle<ISpacePointCalibrator> MuonR4::NswSegmentFinderAlg::m_calibTool {this, "Calibrator", "" }
private

Definition at line 274 of file NswSegmentFinderAlg.h.

274{this, "Calibrator", "" };

◆ m_detMgr

const MuonGMR4::MuonDetectorManager* MuonR4::NswSegmentFinderAlg::m_detMgr {}
private

Definition at line 323 of file NswSegmentFinderAlg.h.

323{};

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default).

Definition at line 393 of file AthCommonDataStore.h.

◆ m_doOnlyMMCombinatorics

BooleanProperty MuonR4::NswSegmentFinderAlg::m_doOnlyMMCombinatorics {this, "doOnlyMMCombinatorics", false}
private

Definition at line 295 of file NswSegmentFinderAlg.h.

295{this, "doOnlyMMCombinatorics", false};

◆ m_dumpObj

BooleanProperty MuonR4::NswSegmentFinderAlg::m_dumpObj {this, "dumpObj", false}
private

Definition at line 319 of file NswSegmentFinderAlg.h.

319{this, "dumpObj", false};

◆ m_dumpSeedStatistics

BooleanProperty MuonR4::NswSegmentFinderAlg::m_dumpSeedStatistics {this, "dumpStatistics", true}
private

Definition at line 316 of file NswSegmentFinderAlg.h.

316{this, "dumpStatistics", true};

◆ m_etaKey

SG::ReadHandleKey<EtaHoughMaxContainer> MuonR4::NswSegmentFinderAlg::m_etaKey {this, "CombinatorialReadKey", "MuonHoughNswMaxima"}
private

Definition at line 256 of file NswSegmentFinderAlg.h.

256{this, "CombinatorialReadKey", "MuonHoughNswMaxima"};

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default).

Definition at line 390 of file AthCommonDataStore.h.

◆ m_extendedExtraObjects

DataObjIDColl AthCommonReentrantAlgorithm< Gaudi::Algorithm >::m_extendedExtraObjects
privateinherited

Extra output dependency collection, extended by AthAlgorithmDHUpdate to add symlinks.

Empty if no symlinks were found.

Definition at line 114 of file AthCommonReentrantAlgorithm.h.

◆ m_geoCtxKey

SG::ReadHandleKey<ActsTrk::GeometryContext> MuonR4::NswSegmentFinderAlg::m_geoCtxKey {this, "AlignmentKey", "ActsAlignment", "cond handle key"}
private

Definition at line 265 of file NswSegmentFinderAlg.h.

265{this, "AlignmentKey", "ActsAlignment", "cond handle key"};

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> MuonR4::NswSegmentFinderAlg::m_idHelperSvc {this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"}
private

Definition at line 268 of file NswSegmentFinderAlg.h.

268{this, "MuonIdHelperSvc", "Muon::MuonIdHelperSvc/MuonIdHelperSvc"};

◆ m_lineFitter

std::unique_ptr<SegmentFit::SegmentLineFitter> MuonR4::NswSegmentFinderAlg::m_lineFitter {}
private

Definition at line 277 of file NswSegmentFinderAlg.h.

277{};

◆ m_markHitsFromSeed

BooleanProperty MuonR4::NswSegmentFinderAlg::m_markHitsFromSeed {this, "markHitsFromSeed", true}
private

Definition at line 292 of file NswSegmentFinderAlg.h.

292{this, "markHitsFromSeed", true};

◆ m_maxChi2

DoubleProperty MuonR4::NswSegmentFinderAlg::m_maxChi2 {this, "maxChi2", 5.}
private

Definition at line 304 of file NswSegmentFinderAlg.h.

304{this, "maxChi2", 5.};

◆ m_maxClustersInLayer

UnsignedIntegerProperty MuonR4::NswSegmentFinderAlg::m_maxClustersInLayer {this, "maxClustersInLayer", 8}
private

Definition at line 307 of file NswSegmentFinderAlg.h.

307{this, "maxClustersInLayer", 8};

◆ m_maxdYWindow

DoubleProperty MuonR4::NswSegmentFinderAlg::m_maxdYWindow {this, "maxdYWindow", 4.*Gaudi::Units::cm}
private

Definition at line 310 of file NswSegmentFinderAlg.h.

310{this, "maxdYWindow", 4.*Gaudi::Units::cm};

◆ m_maxInvalidClusters

UnsignedIntegerProperty MuonR4::NswSegmentFinderAlg::m_maxInvalidClusters {this, "maxInvalidClusters", 4}
private

Definition at line 289 of file NswSegmentFinderAlg.h.

289{this, "maxInvalidClusters", 4};

◆ m_maxTanAlpha

DoubleProperty MuonR4::NswSegmentFinderAlg::m_maxTanAlpha {this, "maxTanAlpha", 0.2}
private

Definition at line 313 of file NswSegmentFinderAlg.h.

313{this, "maxTanAlpha", 0.2};

◆ m_maxUsed

UnsignedIntegerProperty MuonR4::NswSegmentFinderAlg::m_maxUsed {this, "maxHitIsUsed", 6}
private

Definition at line 298 of file NswSegmentFinderAlg.h.

298{this, "maxHitIsUsed", 6};

◆ m_minClusSize

UnsignedIntegerProperty MuonR4::NswSegmentFinderAlg::m_minClusSize {this, "minClusterSize", 1}
private

Definition at line 301 of file NswSegmentFinderAlg.h.

301{this, "minClusterSize", 1};

◆ m_minPullThreshold

DoubleProperty MuonR4::NswSegmentFinderAlg::m_minPullThreshold {this, "maxPull", 5.}
private

Definition at line 283 of file NswSegmentFinderAlg.h.

283{this, "maxPull", 5.};

◆ m_minSeedHits

UnsignedIntegerProperty MuonR4::NswSegmentFinderAlg::m_minSeedHits {this, "minSeedHits", 6}
private

Definition at line 286 of file NswSegmentFinderAlg.h.

286{this, "minSeedHits", 6};

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.

◆ m_visionTool

ToolHandle<MuonValR4::IPatternVisualizationTool> MuonR4::NswSegmentFinderAlg::m_visionTool {this, "VisualizationTool", ""}
private

Pattern visualization tool.

Definition at line 271 of file NswSegmentFinderAlg.h.

271{this, "VisualizationTool", ""};

◆ m_windowTheta

DoubleProperty MuonR4::NswSegmentFinderAlg::m_windowTheta {this, "thetaWindow", 2.5 * Gaudi::Units::deg}
private

Definition at line 280 of file NswSegmentFinderAlg.h.

280{this, "thetaWindow", 2.5 * Gaudi::Units::deg};

◆ m_writeSegmentKey

SG::WriteHandleKey<SegmentContainer> MuonR4::NswSegmentFinderAlg::m_writeSegmentKey {this, "MuonNswSegmentWriteKey", "MuonNswSegments"}
private

Definition at line 262 of file NswSegmentFinderAlg.h.

262{this, "MuonNswSegmentWriteKey", "MuonNswSegments"};

◆ m_writeSegmentSeedKey

SG::WriteHandleKey<SegmentSeedContainer> MuonR4::NswSegmentFinderAlg::m_writeSegmentSeedKey {this, "MuonNswSegmentSeedWriteKey", "MuonNswSegmentSeeds"}
private

Definition at line 259 of file NswSegmentFinderAlg.h.

259{this, "MuonNswSegmentSeedWriteKey", "MuonNswSegmentSeeds"};

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