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

#include <NswSegmentFinderAlg.h>

Inheritance 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 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
 Get filter decision:
virtual void setFilterPassed (bool state, const EventContext &ctx) const
 Set filter decision:
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 resolveAmbiguities (const ActsTrk::GeometryContext &gctx, SegmentVec_t &segmentCandidates) const
 Resolve the ambiguities of the segments per chamber and return the surviving segments.
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"}
ActsTrk::GeoContextReadKey_t m_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 {}
std::unique_ptr< SegmentFit::SegmentAmbiSolverm_ambiSolver {}
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 35 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 114 of file NswSegmentFinderAlg.h.

◆ HitLayVec

◆ HitVec

◆ InitialSeed_t

Abbrivation of the initial seed.

Definition at line 120 of file NswSegmentFinderAlg.h.

◆ InitialSeedVec_t

Vector of initial seeds.

Definition at line 122 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 127 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 129 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 116 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 118 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 136 of file NswSegmentFinderAlg.h.

136 {tooLow,
137 inside,
138 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 47 of file NswSegmentFinderAlg.h.

47 {
48 U,
49 V,
50 X,
51 P,
52 C,
54 };
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 611 of file NswSegmentFinderAlg.cxx.

617 {
618
619 //go through the layers and build seeds from the combinations of hits
620 SegmentSeedVec_t seeds{};
621 SegmentVec_t segments{};
622 std::size_t layerSize = hitLayers.size();
623
624 if(layerSize < minLayers){
625 ATH_MSG_VERBOSE("Not enough layers to build a seed");
626 return {std::move(seeds), std::move(segments)};
627 }
628
629 //lamda helper to find the first unused strip hit on the layer
630 auto unusedStripHit = [&](const HitVec& layerHits, unsigned int layIdx) -> const SpacePoint* {
631 //in case of MM only combinatorial seeding - we consider only MM strip hits for seeding
632 bool isMM = useOnlyMM ? layerHits.front()->type() == xAOD::UncalibMeasType::MMClusterType : true;
633 for (auto [idx, hit] : Acts::enumerate(layerHits)) {
634 auto spOrient = classifyStrip(*hit);
635 bool isStrip = spOrient == StripOrient::X || spOrient == StripOrient::U || spOrient == StripOrient::V;
636 bool isUnused = usedHits[layIdx].at(idx) <= m_maxUsed;
637 if (isStrip && isUnused && isMM) {
638 return hit;
639 }
640 }
641 return nullptr;
642 };
643
644 std::array<const SpacePoint*, 4> seedHits{};
645 InitialSeedVec_t preLimSeeds{};
646
647 for (std::size_t i = 0; i < layerSize - 3; ++i) {
648 seedHits[0] = unusedStripHit(hitLayers[i], i);
649 if(!seedHits[0]) {
650 continue;
651 }
652 for (std::size_t j = i + 1; j < layerSize - 2; ++j) {
653 seedHits[1] = unusedStripHit(hitLayers[j], j);
654 if(!seedHits[1]){
655 continue;
656 }
657 for (std::size_t l = layerSize - 1; l > j+1; --l) {
658 seedHits[3] = unusedStripHit(hitLayers[l], l);
659 if(!seedHits[3]){
660 continue;
661 }
662 for (std::size_t k = l-1; k > j ; --k) {
663 seedHits[2] = unusedStripHit(hitLayers[k], k);
664 if(!seedHits[2]){
665 continue;
666 }
667
668 const HitLaySpan_t layers{hitLayers[i], hitLayers[j], hitLayers[k], hitLayers[l]};
669 //skip combination with at least one too busy layer
670 bool tooBusy = std::ranges::any_of(layers,
671 [this](const auto& layer) {
672 return layer.get().size() > m_maxClustersInLayer;
673 });
674 if (tooBusy) {
675 continue; // skip this combination
676 }
677
678 AmgSymMatrix(2) bMatrix = betaMatrix(seedHits);
679
680 if (std::abs(bMatrix.determinant()) < 1.e-6) {
681 continue;
682 }
683 ATH_MSG_DEBUG("Space point positions for seed layers: \n"
684 <<(*seedHits[0]) << ",\n"
685 <<(*seedHits[1]) << ",\n"
686 <<(*seedHits[2]) << ",\n"
687 <<(*seedHits[3]));
688
689
690 UsedHitSpan_t usedHitsSpan{usedHits[i], usedHits[j], usedHits[k], usedHits[l]};
691 // each layer may have more than one hit - take the hit combinations
692 constructPreliminarySeeds(beamSpotPos, layers, usedHitsSpan, preLimSeeds);
693
694 //the layers not participated in the seed build - gonna be used for the extension
695 HitLaySpan_t extensionLayers{};
696 UsedHitSpan_t usedExtensionHits{};
697 usedExtensionHits.reserve(hitLayers.size());
698 extensionLayers.reserve(hitLayers.size());
699 for (std::size_t e = 0 ; e < hitLayers.size(); ++e) {
700 if (!(e == i || e == j || e == k || e == l)){
701 extensionLayers.emplace_back(hitLayers[e]);
702 usedExtensionHits.emplace_back(usedHits[e]);
703 }
704 }
705 // we have made sure to have hits from all the four layers -
706 // start by 4 hits for the seed and try to build the extended seed for the combinatorics found
707 for (auto &combinatoricHits : preLimSeeds) {
708 auto seed = constructCombinatorialSeed(combinatoricHits, bMatrix, max, extensionLayers, usedExtensionHits);
709 if(!seed){
710 continue;
711 }
712 if (seed->getHitsInMax().size() < m_minSeedHits) {
713 seeds.push_back(std::move(seed));
714 continue;
715 }
716 std::unique_ptr<Segment> segment = fitSegmentSeed(ctx, gctx, seed.get());
717 processSegment(std::move(segment), seed->getHitsInMax(), hitLayers, usedHits, segments);
718 seeds.push_back(std::move(seed));
719
720 }
721 }
722 }
723 }
724 }
725 return std::make_pair(std::move(seeds),std::move(segments));
726}
#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 499 of file NswSegmentFinderAlg.cxx.

504 {
505
506 //go through the layers and build seeds from the combinations of hits
507 //starting from the outermost layers with 2D measurements (excluding pads)
508 SegmentSeedVec_t seeds{};
509 SegmentVec_t segments{};
510 std::size_t layerSize = hitLayers.size();
511 double thetaWindowCut{std::cos(2*m_windowTheta)};
512
513 // lamda helper to check if the spacepoint is combined (but not pad) and unused in an already constructed seed
514 auto isUnusedCombined = [&](std::size_t layIdx, std::size_t hitIdx) -> bool {
515 const SpacePoint* sp = hitLayers[layIdx][hitIdx];
517 THROW_EXCEPTION("Space point is not of sTgc type: "<<sp->msSector()->idHelperSvc()->toString(sp->identify()));
518 }
519 if(sp->dimension() != 2){
520 ATH_MSG_VERBOSE("Ignoring the 1D measurement for seeding: "<<m_idHelperSvc->toString(sp->identify()));
521 return false;
522 }
523 const auto* prdPrim = static_cast<const xAOD::sTgcMeasurement*>(sp->primaryMeasurement());
524 const auto* prdSec = static_cast<const xAOD::sTgcMeasurement*>(sp->secondaryMeasurement());
525 //we know we have a 2D spacepoint can be: pad, strip+pad, strip+wire, wire+pad and we dont want pads appearing in this seeding stage
526 bool hasPad = prdSec ? prdSec->channelType()==sTgcIdHelper::sTgcChannelTypes::Pad : prdPrim->channelType()==sTgcIdHelper::sTgcChannelTypes::Pad;
527 if(hasPad){
528 ATH_MSG_VERBOSE("Ignoring the 2D pad measurement for seeding because of pads: "<<m_idHelperSvc->toString(sp->identify()));
529 return false;
530 }
531 bool isPrecision = isPrecisionHit(*sp);
532 return isPrecision && usedHits[layIdx].at(hitIdx) <= m_maxUsed;
533
534 };
535
536 // find the 2D measurements from the outermost layers - even move one layer inside
537 for(std::size_t layIdx1 = 0; layIdx1 < 2; ++layIdx1){
538 for(std::size_t layIdx2 = layerSize-1; layIdx2 >= layerSize-2; --layIdx2){
539 //in case of MM layers we stop - the layers are sorted in Z
540 if(hitLayers[layIdx1].front()->type() == xAOD::UncalibMeasType::MMClusterType ||
541 hitLayers[layIdx2].front()->type() == xAOD::UncalibMeasType::MMClusterType){
542 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<"Outermost layers are MM - stop searching for sTgc Measurements");
543 return std::make_pair(std::move(seeds), std::move(segments));
544 }
545
546 //check if we have 2D measurements on these layers that are unused (excluding the pads)
547 for(std::size_t hitIdx1 = 0; hitIdx1 < hitLayers[layIdx1].size(); ++hitIdx1) {
548 const SpacePoint* hit1 = hitLayers[layIdx1][hitIdx1];
549 if(!isUnusedCombined(layIdx1, hitIdx1)){
550 continue;
551 }
552 for(std::size_t hitIdx2 = 0; hitIdx2 < hitLayers[layIdx2].size(); ++hitIdx2) {
553 const SpacePoint* hit2 = hitLayers[layIdx2][hitIdx2];
554 if(!isUnusedCombined(layIdx2, hitIdx2)){
555 continue;
556 }
557 //test if this selection of the hits from the two layers is aligned with the beam spot
558 const Amg::Vector3D beamSpotHitDir{(beamSpotPos - hit1->localPosition()).unit()};
559 const Amg::Vector3D seedDir{(hit2->localPosition() - hit1->localPosition()).unit()};
560 const double cosAngle = beamSpotHitDir.dot(seedDir);
561 //accept the deflection of direction with a tolerance of 1 deg
562 if(std::abs(cosAngle) < thetaWindowCut){
563 continue;
564 }
565 //found 2D hits on the outermost layers - build a seed
566 HitVec seedHits{hit1, hit2};
567 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<"Attempt for STGC segment starting with the hits: " << *hit1 << ", " << *hit2);
568 //get the seed direction and position from the two 2D hits
569 const Amg::Vector3D seedPos = hit1->localPosition();
570 //express position in z=0
571 const Amg::Vector3D seedPosZ0 = seedPos + Amg::intersect<3>(seedPos, seedDir, Amg::Vector3D::UnitZ(), 0.).value_or(0.)*seedDir;
572 // extend the seed to the other layers
573 HitLaySpan_t extensionLayers{};
574 UsedHitSpan_t usedExtensionHits{};
575 extensionLayers.reserve(hitLayers.size());
576 usedExtensionHits.reserve(hitLayers.size());
577 for (std::size_t e = 0 ; e < hitLayers.size(); ++e) {
578 if (!(e == layIdx1 || e == layIdx2)){
579 extensionLayers.emplace_back(hitLayers[e]);
580 usedExtensionHits.emplace_back(usedHits[e]);
581 }
582 }
583 auto extendedHits = extendHits(seedPosZ0, seedDir, extensionLayers, usedExtensionHits);
584 std::ranges::move(extendedHits, std::back_inserter(seedHits));
585
586 //make seed
587 auto seed = std::make_unique<SegmentSeed>(houghTanBeta(seedDir), seedPosZ0.y(),
588 houghTanAlpha(seedDir), seedPosZ0.x(),
589 seedHits.size(), std::move(seedHits),
590 max.parentBucket());
591
592 //skip segment fit with less than 5 hits
593 if(seed->getHitsInMax().size() < m_minSeedHits){
594 seeds.push_back(std::move(seed));
595 continue;
596 }
597 //fit the segment seed
598 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Start to fit an STGC segment seed with "<<seed->getHitsInMax().size()<<" hits \n"<<print(seed->getHitsInMax()));
599 std::unique_ptr<Segment> segment = fitSegmentSeed(ctx, gctx, seed.get());
600 processSegment(std::move(segment), seed->getHitsInMax(), hitLayers, usedHits, segments);
601 seeds.push_back(std::move(seed));
602
603 }
604 }
605 }
606 }
607 return std::make_pair(std::move(seeds),std::move(segments));
608}
static Double_t sp
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
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.
virtual sTgcChannelTypes channelType() const =0
Returns the channel type of the measurement (Pad/Wire/Strip).
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].
bool isPrecisionHit(const SpacePoint &hit)
Returns whether the uncalibrated spacepoint is a precision hit (Mdt, micromegas, stgc strips).
std::string print(const cont_t &container)
Print a space point container to string.
double houghTanAlpha(const Amg::Vector3D &v)
: Returns the hough tanAlpha [x] / [z]
sTgcMeasurement_v1 sTgcMeasurement
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10

◆ classifyStrip()

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

Determines the orientation of the strip space point.

Definition at line 128 of file NswSegmentFinderAlg.cxx.

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

◆ 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 343 of file NswSegmentFinderAlg.cxx.

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

229 {
231 seedHitsFromLayers.clear();
232 std::size_t maxSize{1};
233 for (const HitVec& hitVec : combinatoricLayers) {
234 maxSize = maxSize * hitVec.size();
235 }
236 seedHitsFromLayers.reserve(maxSize);
237
238 unsigned iterLay0{0}, iterLay1{0}, iterLay2{0}, iterLay3{0};
239 unsigned startLay1{0}, startLay2{0}, startLay3{0};
240
241 for( ; iterLay0 < combinatoricLayers[0].get().size() ; ++iterLay0){
243 if (usedHits[0].get()[iterLay0] > m_maxUsed) {
244 continue;
245 }
246 const SpacePoint* hit0 = combinatoricLayers[0].get()[iterLay0];
248 const Amg::Vector3D initSeedDir{(beamSpot - hit0->localPosition()).unit()};
249 const Amg::Vector3D dirEstUp = Amg::dirFromAngles(initSeedDir.phi(), initSeedDir.theta() - m_windowTheta);
250 const Amg::Vector3D dirEstDn = Amg::dirFromAngles(initSeedDir.phi(), initSeedDir.theta() + m_windowTheta);
251
252 ATH_MSG_VERBOSE("Reference hit: "<<m_idHelperSvc->toString(hit0->identify())
253 <<", position: "<<Amg::toString(hit0->localPosition())
254 <<", seed dir: "<<Amg::toString(initSeedDir)
255 <<", seed plane: "<<Amg::toString(SeedingAux::extrapolateToPlane(beamSpot, initSeedDir, *hit0)));
257 for( iterLay1 = startLay1; iterLay1 < combinatoricLayers[1].get().size() ; ++iterLay1){
258 TEST_HIT_CORRIDOR(1, iterLay1, startLay1);
259 for( iterLay2 = startLay2; iterLay2 < combinatoricLayers[2].get().size() ; ++iterLay2){
260 TEST_HIT_CORRIDOR(2, iterLay2, startLay2);
261 for( iterLay3 = startLay3; iterLay3 < combinatoricLayers[3].get().size(); ++iterLay3){
262 TEST_HIT_CORRIDOR(3, iterLay3, startLay3);
263 seedHitsFromLayers.emplace_back(std::array{hit0, combinatoricLayers[1].get()[iterLay1],
264 combinatoricLayers[2].get()[iterLay2],
265 combinatoricLayers[3].get()[iterLay3]});
266 }
267 }
268 }
269 }
270}
#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 119 of file NswSegmentFinderAlg.cxx.

119 {
120 UsedHitMarker_t emptyKeeper(sortedSp.size());
121 for (std::size_t l = 0; l < sortedSp.size(); ++l) {
122 emptyKeeper[l].resize(sortedSp[l].size(), 0);
123 }
124 return emptyKeeper;
125}
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 937 of file NswSegmentFinderAlg.cxx.

937 {
938 // read the inputs
939 const EtaHoughMaxContainer *maxima{nullptr};
940 ATH_CHECK(SG::get( maxima, m_etaKey, ctx));
941
942 const ActsTrk::GeometryContext *gctx{nullptr};
943 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
944
945 // prepare our output collection
946 SG::WriteHandle writeSegments{m_writeSegmentKey, ctx};
947 ATH_CHECK(writeSegments.record(std::make_unique<SegmentContainer>()));
948
949 SG::WriteHandle writeSegmentSeeds{m_writeSegmentSeedKey, ctx};
950 ATH_CHECK(writeSegmentSeeds.record(std::make_unique<SegmentSeedContainer>()));
951
952 // we use the information from the previous eta-hough transform
953 // to get the combined hits that belong in the same maxima
954 for (const HoughMaximum *max : *maxima) {
955
956 auto [seeds, segments] = findSegmentsFromMaximum(*max, *gctx, ctx);
957
958 if (msgLvl(MSG::VERBOSE)) {
959 ATH_MSG_VERBOSE("Hits from Hough maximum");
960 for(const auto& hitMax : max->getHitsInMax()){
961 ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hitMax->identify())<<", "
962 <<Amg::toString(hitMax->localPosition())<<", dir: "
963 <<Amg::toString(hitMax->sensorDirection()));
964 }
965 }
966
967 for(auto& seed: seeds){
968
969 if (msgLvl(MSG::VERBOSE)){
970 std::stringstream sstr{};
971 sstr<<"Seed tanBeta = "<<seed->tanBeta()<<", y0 = "<<seed->interceptY()
972 <<", tanAlpha = "<<seed->tanAlpha()<<", x0 = "<<seed->interceptX()<<", hits in the seed "
973 <<seed->getHitsInMax().size()<<std::endl;
974
975 for(const auto& hit : seed->getHitsInMax()){
976 sstr<<" *** Hit "<<m_idHelperSvc->toString(hit->identify())<<", "
977 << Amg::toString(hit->localPosition())<<", dir: "<<Amg::toString(hit->sensorDirection())<<std::endl;
978 }
979 ATH_MSG_VERBOSE(sstr.str());
980 }
981 if (m_visionTool.isEnabled()) {
982 m_visionTool->visualizeSeed(ctx, *seed, "#phi-combinatorialSeed");
983 }
984
985 writeSegmentSeeds->push_back(std::move(seed));
986
987 }
988
989 //Resolve ambiguities between segments before writing them to the output
990 ATH_MSG_VERBOSE("Before ambiguity resolution, there are in total "<<segments.size()<<" segments:");
991 for(const auto& seg : segments){
992
993 if(msgLvl(MSG::VERBOSE)){
994 std::stringstream sstr{};
995 sstr<<"Segment chi2/ndof = "<<seg->chi2()/std::max(1u,seg->nDoF())<<", hits in the segment "
996 <<seg->measurements().size()<<std::endl;
997
998 const Parameters pars = localSegmentPars(*gctx, *seg);
999 sstr<<"Segment parameters : "<<toString(pars)<<std::endl;
1000 for(const auto& hit : seg->measurements()){
1001 bool hasTruth{false};
1002 if(hit->type()!=xAOD::UncalibMeasType::Other){
1003 hasTruth = (getTruthMatchedHit(*hit->spacePoint()->primaryMeasurement()) !=nullptr);
1004
1005 sstr<<" *** Hit "<<m_idHelperSvc->toString(hit->spacePoint()->identify())<<", "
1006 << Amg::toString(hit->spacePoint()->localPosition())<<", dir: "
1007 <<Amg::toString(hit->spacePoint()->sensorDirection())<<", has truth matched: "<<hasTruth<<std::endl;
1008 }
1009 }
1010 ATH_MSG_VERBOSE(sstr.str());
1011
1012 }
1013
1014 }
1015
1016
1017 resolveAmbiguities(*gctx, segments);
1018 ATH_MSG_VERBOSE("After ambiguity resolution, there are in total "<<segments.size()<<" segments:");
1019
1020 for (auto &seg : segments) {
1021 if(msgLvl(MSG::VERBOSE)){
1022 std::stringstream sstr{};
1023 sstr<<"Segment chi2/ndof = "<<seg->chi2()/std::max(1u,seg->nDoF())<<", hits in the segment "
1024 <<seg->measurements().size()<<std::endl;
1025 const Parameters pars = localSegmentPars(*gctx, *seg);
1026 sstr<<"Segment parameters : "<<toString(pars)<<std::endl;
1027
1028 for(const auto& hit : seg->measurements()){
1029 bool hasTruth{false};
1030 if(hit->type()!=xAOD::UncalibMeasType::Other){
1031 hasTruth = getTruthMatchedHit(*hit->spacePoint()->primaryMeasurement()) !=nullptr;
1032
1033 sstr<<" *** Hit "<<m_idHelperSvc->toString(hit->spacePoint()->identify())<<", "
1034 << Amg::toString(hit->spacePoint()->localPosition())<<", dir: "
1035 <<Amg::toString(hit->spacePoint()->sensorDirection())<<", has truth matched: "<<hasTruth<<std::endl;
1036 }
1037 }
1038 ATH_MSG_VERBOSE(sstr.str());
1039 }
1040
1041
1042 if (m_visionTool.isEnabled()) {
1043 m_visionTool->visualizeSegment(ctx, *seg, "#phi-segment");
1044 }
1045
1046 if(m_dumpObj){
1047 Acts::ObjVisualization3D visualHelper{};
1048 MuonValR4::drawSegmentMeasurements(gctx->context(), *seg, visualHelper);
1049 MuonValR4::drawSegmentLine(gctx->context(), *seg, visualHelper);
1050 visualHelper.write(std::format("Event_{:}_segment_{:}.obj", ctx.eventID().event_number(), seg->msSector()->identString()));
1051 }
1052
1053 writeSegments->push_back(std::move(seg));
1054
1055 }
1056
1057
1058 }
1059
1060 return StatusCode::SUCCESS;
1061}
#define ATH_CHECK
Evaluate an expression and check for errors.
Acts::GeometryContext context() const
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.
void resolveAmbiguities(const ActsTrk::GeometryContext &gctx, SegmentVec_t &segmentCandidates) const
Resolve the ambiguities of the segments per chamber and return the surviving segments.
ToolHandle< MuonValR4::IPatternVisualizationTool > m_visionTool
Pattern visualization tool.
SG::WriteHandleKey< SegmentSeedContainer > m_writeSegmentSeedKey
SG::WriteHandleKey< SegmentContainer > m_writeSegmentKey
ActsTrk::GeoContextReadKey_t 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
const xAOD::MuonSimHit * getTruthMatchedHit(const xAOD::MuonMeasurement &prdHit)
Returns the MuonSimHit, if there's any, matched to the uncalibrated muon measurement.
void drawSegmentMeasurements(const Acts::GeometryContext &tgContext, 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 Acts::GeometryContext &tgContext, 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 274 of file NswSegmentFinderAlg.cxx.

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

◆ 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 & AthCommonAlgorithm< 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 89 of file AthCommonAlgorithm.cxx.

54{
55 // If we didn't find any symlinks to add, just return the collection
56 // from the base class. Otherwise, return the extended collection.
57 if (!m_extendedExtraObjects.empty()) {
59 }
61}
Common base class for algorithms.

◆ filterPassed()

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

Get filter decision:

Definition at line 93 of file AthCommonAlgorithm.h.

93 {
94 return execState( ctx ).filterPassed();
95 }
virtual bool filterPassed(const EventContext &ctx) const
Get filter decision:

◆ finalize()

StatusCode MuonR4::NswSegmentFinderAlg::finalize ( )
overridevirtual

Definition at line 1063 of file NswSegmentFinderAlg.cxx.

1063 {
1064 if(m_seedCounter) {
1065 m_seedCounter->printTableSeedStats(msgStream());
1066 }
1067 return StatusCode::SUCCESS;
1068}

◆ 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 729 of file NswSegmentFinderAlg.cxx.

731 {
732 // first sort the hits per layer from the maximum
733 SpacePointPerLayerSplitter hitLayers{max.getHitsInMax()};
734
735 const HitLayVec& stripHitsLayers{hitLayers.stripHits()};
736 const std::size_t layerSize = stripHitsLayers.size();
737
738 //seeds and segments containers
739 SegmentSeedVec_t seeds{};
740 SegmentVec_t segments{};
741
742 const Amg::Transform3D globToLocal = max.msSector()->globalToLocalTransform(gctx);
743 //counters for the number of seeds, extented seeds and segments
744
745 if (layerSize < minLayers) {
746 ATH_MSG_VERBOSE("Not enough layers to build a seed");
747 return std::make_pair(std::move(seeds),std::move(segments));
748 }
749
750 if (m_visionTool.isEnabled()) {
752 constexpr double legX{0.2};
753 double legY{0.8};
754 for (const SpacePoint* sp : max.getHitsInMax()) {
755 const xAOD::MuonSimHit* simHit = getTruthMatchedHit(*sp->primaryMeasurement());
756 if (!simHit) {
757 continue;
758 }
759
760 const MuonGMR4::MuonReadoutElement* reEle = m_detMgr->getReadoutElement(simHit->identify());
761 const Amg::Transform3D toChamb = reEle->msSector()->globalToLocalTransform(gctx) *
762 reEle->localToGlobalTransform(gctx, sp->identify());
763
764 const Amg::Vector3D hitPos = toChamb * xAOD::toEigen(simHit->localPosition());
765 const Amg::Vector3D hitDir = toChamb.linear() * xAOD::toEigen(simHit->localDirection());
766 const double pull = std::sqrt(SeedingAux::chi2Term(hitPos, hitDir, *sp));
767
769 const auto* mmClust = static_cast<const xAOD::MMCluster*>(sp->primaryMeasurement());
770 const MuonGMR4::MmReadoutElement* mmEle = mmClust->readoutElement();
771 const auto& design = mmEle->stripLayer(mmClust->measurementHash()).design();
772 std::string stereoDesign{!design.hasStereoAngle() ? "X" : design.stereoAngle() >0 ? "U": "V"};
773 primitives.push_back(MuonValR4::drawLabel(std::format("ml: {:1d}, gap: {:1d}, {:}, pull: {:.2f}",
774 mmEle->multilayer(), mmClust->gasGap(),
775 stereoDesign, pull), legX, legY, 14));
776 } else if(sp->type() == xAOD::UncalibMeasType::sTgcStripType) {
777 const auto* sTgcMeas = static_cast<const xAOD::sTgcMeasurement*>(sp->primaryMeasurement());
778 std::string channelString = sp->secondaryMeasurement() == nullptr ?
779 sTgcChannelType(sTgcMeas->channelType()) :
780 std::format("{:}/{:}", sTgcChannelType(sTgcMeas->channelType()),
781 sTgcChannelType(static_cast<const xAOD::sTgcMeasurement*>(sp->secondaryMeasurement())->channelType()));
782 primitives.push_back(MuonValR4::drawLabel(std::format("ml: {:1d}, gap: {:1d}, type: {:}, pull: {:.2f}",
783 sTgcMeas->readoutElement()->multilayer(), sTgcMeas->gasGap(),
784 channelString, pull), legX, legY, 14));
785 }
786 legY-=0.05;
787 }
788 m_visionTool->visualizeBucket(ctx, *max.parentBucket(),
789 "truth", std::move(primitives));
790 }
791
792 //dump spacepoints associated with truth sim hits to an obj file
793 if(m_dumpObj){
794 Acts::ObjVisualization3D visualHelper{};
795 for (const SpacePoint* sp : max.getHitsInMax()) {
796 const xAOD::MuonSimHit* simHit = getTruthMatchedHit(*sp->primaryMeasurement());
797 if (!simHit) {
798 continue;
799 }
800 MuonValR4::drawSpacePoint(gctx.context(), *sp, visualHelper);
801 }
802 visualHelper.write(std::format("Event_{:}_{:}_spacepoints_truth.obj", ctx.eventID().event_number(), max.getHitsInMax().front()->chamber()->identString()));
803 }
804
805
806 UsedHitMarker_t allUsedHits = emptyBookKeeper(stripHitsLayers);
807 std::size_t nSeeds{0}, nExtSeeds{0}, nSegments{0}; //for the seed statistics
808
809 // helper lamda function to increase counters and fill the seeds and segments we want to return after we construct them
810 // the extended seeds are returned even if they did not make it to a segment and the segments only if successfully fitted
811 auto processSeedsAndSegments = [&](std::pair<SegmentSeedVec_t, SegmentVec_t>&& seedSegmentPairs, std::string_view source) {
812 auto& [returnSeeds, returnSegments] = seedSegmentPairs;
813 ATH_MSG_DEBUG("From " << source << ": built " << returnSeeds.size() << " seeds and " << returnSegments.size() << " segments.");
814 for(auto& seed : returnSeeds) {
815 ++nSeeds;
816 Acts::ObjVisualization3D visualHelper{};
817 if(seed->getHitsInMax().size() < m_minSeedHits){
818 ATH_MSG_VERBOSE("Seed with "<< seed->getHitsInMax().size() <<" hits rejected");
819 for(const auto& hit : seed->getHitsInMax()){
820 ATH_MSG_VERBOSE("Hit "<<m_idHelperSvc->toString(hit->identify())<<", "
821 <<Amg::toString(hit->localPosition())<<", dir: "
822 <<Amg::toString(hit->sensorDirection()));
823 if(m_dumpObj){
824 MuonValR4::drawSpacePoint(gctx.context(), *hit, visualHelper);
825 }
826
827 }
828 if(m_dumpObj){
829 visualHelper.write(std::format("Event_{:}_{:}_notExtendedSeed.obj", ctx.eventID().event_number(), seed->getHitsInMax().front()->chamber()->identString()));
830 }
831 continue;
832 }
833 ++nExtSeeds;
834 seeds.push_back(std::move(seed));
835 }
836 //move all the segments to the output container
837 std::ranges::move(returnSegments, std::back_inserter(segments));
838 nSegments += returnSegments.size();
839 };
840
841 //Start from outermost sTgc layers with combined 2D measurements
842 ATH_MSG_VERBOSE("Start building seed from sTgc outermost layers");
843 processSeedsAndSegments(buildSegmentsFromSTGC(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits), "sTgc segment seeds");
844
845 //continue with the combinatorial seeding for the strip measurements
847
848 ATH_MSG_VERBOSE("Start building combinatoric seeds only from Micromegas");
849 processSeedsAndSegments(buildSegmentsFromMM(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits, true), "MM combinatoric segment seeds");
850
851 }else{
852
853 ATH_MSG_VERBOSE("Start building combinatoric seeds from Micromegas and sTgc hits");
854 processSeedsAndSegments(buildSegmentsFromMM(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits, true), "MM combinatoric segment seeds");
855 processSeedsAndSegments(buildSegmentsFromMM(ctx, gctx, stripHitsLayers, max, globToLocal.translation(), allUsedHits, false), "MM and STGC combinatoric segment seeds");
856
857 }
858
859 if(m_seedCounter) {
860 m_seedCounter->addToStat(max.msSector(), nSeeds, nExtSeeds, nSegments);
861 }
862
863 return std::make_pair(std::move(seeds),std::move(segments));
864}
const StripLayer & stripLayer(const Identifier &measId) const
int multilayer() const
Returns the multi layer of the element [1-2].
const SpectrometerSector * msSector() const
Returns the pointer to the envelope volume enclosing all chambers in the sector.
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const override final
Returns the transformation from the local coordinate system of the readout element into the global AT...
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...
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 Acts::GeometryContext &tgContext, 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 402 of file NswSegmentFinderAlg.cxx.

404 {
405
406 if(patternSeed->getHitsInMax().size() < m_minSeedHits){
407 ATH_MSG_VERBOSE("Not enough hits in the SegmentSeed to fit a segment");
408 return nullptr;
409 }
410
411 ATH_MSG_VERBOSE("Fit the SegmentSeed");
412 if (msgLvl(MSG::VERBOSE)) {
413 std::stringstream hitStream{};
414 for (const auto& hit : patternSeed->getHitsInMax()) {
415 hitStream<<"**** "<< (*hit)<<std::endl;
416 }
417 ATH_MSG_VERBOSE(__func__<<"() - "<<__LINE__ <<": Uncalibrated space points for the segment fit: "<<std::endl
418 <<hitStream.str());
419 }
420
421 //Calibration of the seed spacepoints
422 CalibSpacePointVec calibratedHits = m_calibTool->calibrate(ctx, patternSeed->getHitsInMax(),
423 patternSeed->localPosition(),
424 patternSeed->localDirection(), 0.);
425
426 const Amg::Transform3D& locToGlob{patternSeed->msSector()->localToGlobalTransform(gctx)};
427
428 return m_lineFitter->fitSegment(ctx, patternSeed, patternSeed->parameters(),
429 locToGlob, std::move(calibratedHits));
430}
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 149 of file NswSegmentFinderAlg.cxx.

152 {
153
154 const Amg::Vector3D estPlaneArrivalUp = SeedingAux::extrapolateToPlane(beamSpotPos, dirEstUp, testHit);
155 const Amg::Vector3D estPlaneArrivalDn = SeedingAux::extrapolateToPlane(beamSpotPos, dirEstDn, testHit);
156
157 bool below{true}, above{true};
158 switch (classifyStrip(testHit)) {
159 using enum StripOrient;
160 case U:
161 case V:{
162 const double halfLength = 0.5* stripHalfLength(testHit);
164 const Amg::Vector3D leftEdge = testHit.localPosition() - halfLength * testHit.sensorDirection();
165 const Amg::Vector3D rightEdge = testHit.localPosition() + halfLength * testHit.sensorDirection();
166
168 below = estPlaneArrivalDn.y() > std::max(leftEdge.y(), rightEdge.y());
170 above = estPlaneArrivalUp.y() < std::min(leftEdge.y(), rightEdge.y());
171 break;
172 } case X:
173 case C: {
175 const double hY = testHit.localPosition().y();
176 below = estPlaneArrivalDn.y() > hY;
178 above = estPlaneArrivalUp.y() < hY;
179 break;
180 }
181 case P:{
182 break;
183 }
184 case Unknown:{
185 break;
186 }
187
188 }
189 ATH_MSG_VERBOSE("Hit " << m_idHelperSvc->toString(testHit.identify())
190 << (below || above ? " is outside the window" : " is inside the window"));
191 if(below) {
192 return HitWindow::tooLow;
193 }
194 if(above) {
195 return HitWindow::tooHigh;
196 }
197 return HitWindow::inside;
198};
@ 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
107 SegmentAmbiSolver::Config ambicfg{};
108 m_ambiSolver = std::make_unique<SegmentAmbiSolver>(name(), std::move(ambicfg));
109
110
112 m_seedCounter = std::make_unique<SeedStatistics>();
113 }
114
115 return StatusCode::SUCCESS;
116}
#define ATH_MSG_ERROR(x)
const ServiceHandle< StoreGateSvc > & detStore() const
std::unique_ptr< SegmentFit::SegmentAmbiSolver > m_ambiSolver

◆ 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()

virtual bool AthCommonAlgorithm< Gaudi::Algorithm >::isClonable ( ) const
inlineoverridevirtualinherited

Specify if the algorithm is clonable.

Only relevant for non-reentrant algorithms. Actual number of clones needs to be set via the "Cardinality" property.

Reimplemented in AFP_DigiTop, AlgB, AlgT, BCM_Digitization, CscDigitBuilder, CscDigitToCscRDO, G4AtlasAlg, G4RunAlg, HGTD_Digitization, HiveAlgBase, InDet::GNNSeedingTrackMaker, InDet::SCT_Clusterization, InDet::SiSPGNNTrackMaker, InDet::SiSPSeededTrackFinder, InDet::SiTrackerSpacePointFinder, ISF::SimKernelMT, ITk::StripDigitization, ITkPixelCablingAlg, ITkStripCablingAlg, LArHitEMapMaker, LArTTL1Maker, LUCID_DigiTop, LVL1::L1TopoSimulation, MergeCalibHits, MergeGenericMuonSimHitColl, MergeHijingPars, MergeMcEventCollection, MergeTrackRecordCollection, MergeTruthJets, MergeTruthParticles, MuonDigitizer, PileUpMTAlg, PixelDigitization, RoIBResultToxAOD, SCT_ByteStreamErrorsTestAlg, SCT_CablingCondAlgFromCoraCool, SCT_CablingCondAlgFromText, SCT_ConditionsParameterTestAlg, SCT_ConditionsSummaryTestAlg, SCT_ConfigurationConditionsTestAlg, SCT_Digitization, SCT_FlaggedConditionTestAlg, SCT_LinkMaskingTestAlg, SCT_MajorityConditionsTestAlg, SCT_ModuleVetoTestAlg, SCT_MonitorConditionsTestAlg, SCT_PrepDataToxAOD, SCT_RawDataToxAOD, SCT_ReadCalibChipDataTestAlg, SCT_ReadCalibDataTestAlg, SCT_RODVetoTestAlg, SCT_SensorsTestAlg, SCT_SiliconConditionsTestAlg, SCT_StripVetoTestAlg, SCT_TdaqEnabledTestAlg, SCT_TestCablingAlg, SCTEventFlagWriter, SCTRawDataProvider, SCTSiLorentzAngleTestAlg, SCTSiPropertiesTestAlg, SGInputLoader, Simulation::BeamEffectsAlg, TileHitVecToCnt, TileMuonFitter, TilePulseForTileMuonReceiver, TileRawChannelMaker, TRTDigitization, and ZDC_DigiTop.

Definition at line 68 of file AthCommonAlgorithm.h.

68 {
69 return true;
70 }

◆ 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 866 of file NswSegmentFinderAlg.cxx.

870 {
871
872 SpacePointPerLayerSorter layerSorter{};
873
874 for(const auto& sp : spacePoints){
875 // Proection against the auxiliary measurement
876 if(!sp){
877 continue;
878 }
879
880 unsigned measLayer = layerSorter.sectorLayerNum(*sp);
881
882 Amg::Vector2D spPosX{Amg::Vector2D::Zero()};
884 switch (sp->primaryMeasurement()->numDimensions()) {
885 case 1:
886 spPosX[Amg::x] = sp->primaryMeasurement()->localPosition<1>().x();
887 break;
888 case 2:
889 spPosX = xAOD::toEigen(sp->primaryMeasurement()->localPosition<2>());
890 break;
891 default:
892 THROW_EXCEPTION("Unsupported dimension");
893 }
894
895 for (std::size_t lIdx = 0; lIdx < allSortHits.size(); ++lIdx) {
896 const HitVec& hVec{allSortHits[lIdx]};
897 //check if they are not in the same layer
898 unsigned hitLayer = layerSorter.sectorLayerNum(*hVec.front());
899 if(hitLayer != measLayer) {
900 ATH_MSG_VERBOSE("Not in the same layer since measLayer = "<< measLayer << " and "<<hitLayer);
901 continue;
902 }
903 for (std::size_t hIdx = 0 ; hIdx < hVec.size(); ++hIdx) {
904 //check the dY between the measurement and the hits
905 auto testHit = hVec[hIdx];
906 if (testHit == sp) {
907 usedHitMarker[lIdx][hIdx] += incr;
908 if(!markNeighborHits){
909 break;
910 }
911 } else if (markNeighborHits) {
912 Amg::Vector2D testPosX{Amg::Vector2D::Zero()};
914 switch (testHit->primaryMeasurement()->numDimensions()) {
915 case 1:
916 testPosX[Amg::x] = testHit->primaryMeasurement()->localPosition<1>().x();
917 break;
918 case 2:
919 testPosX = xAOD::toEigen(testHit->primaryMeasurement()->localPosition<2>());
920 break;
921 default:
922 THROW_EXCEPTION("Unsupported dimension");
923 }
924 //if the hit not found let's see if it is too close to the segment's measurement
925 double deltaX = (testPosX - spPosX).mag();
926 if(deltaX < m_maxdYWindow){
927 usedHitMarker[lIdx][hIdx] += incr;
928 }
929 }
930 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<"- Marking hit "<<(*testHit)<<", used count: "
931 <<usedHitMarker[lIdx][hIdx]);
932 }
933 }
934 }
935}
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 432 of file NswSegmentFinderAlg.cxx.

436 {
437
438 if (!segment) {
439 ATH_MSG_VERBOSE("Seed Rejection: Segment fit failed");
440
441 if (m_markHitsFromSeed && seedHits.size() > m_minSeedHits) {
442 // Mark hits from extended seed (used increment by 1)
443 markHitsAsUsed(seedHits, hitLayers, usedHits, 1, false);
444 }
445 return;
446 }
447
448 // -------- success path --------
449 ATH_MSG_DEBUG("Segment built with "
450 << segment->measurements().size()
451 << " hits, chi2/ndof: "
452 << segment->chi2() / std::max(1u,segment->nDoF()));
453
454 HitVec segMeasSP;
455 segMeasSP.reserve(segment->measurements().size());
456
457 std::ranges::transform(
458 segment->measurements(),
459 std::back_inserter(segMeasSP),
460 [](const auto& m) { return m->spacePoint(); }
461 );
462
463 // Mark segment hits as fully used (used increment by 10,
464 // hits are effectively removed)
465 markHitsAsUsed(segMeasSP, hitLayers, usedHits, 10, true);
466 segments.push_back(std::move(segment));
467
468}
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 }

◆ resolveAmbiguities()

void MuonR4::NswSegmentFinderAlg::resolveAmbiguities ( const ActsTrk::GeometryContext & gctx,
SegmentVec_t & segmentCandidates ) const
private

Resolve the ambiguities of the segments per chamber and return the surviving segments.

Parameters
gctxThe reference to the geometry context
segmentCandidatesThe reference to the segments to resolve the ambiguities

Definition at line 470 of file NswSegmentFinderAlg.cxx.

471 {
472
473 if(segmentCandidates.size()<=1){
474 ATH_MSG_VERBOSE("No segments to resolve ambiguities");
475 return;
476 }
477
478 ATH_MSG_VERBOSE("Resolving ambiguities for "<<segmentCandidates.size()<<" segments");
479
480 std::map<const MuonGMR4::SpectrometerSector*, SegmentVec_t,
481 MuonGMR4::MuonDetectorManager::MSEnvelopeSorter> segmentsPerChamber{};
482
483 //sort segments per chamber and resolve ambiguities per chamber
484 for (std::unique_ptr<Segment>& seg : segmentCandidates) {
485 const MuonGMR4::SpectrometerSector* chamb = seg->msSector();
486 segmentsPerChamber[chamb].push_back(std::move(seg));
487 }
488 segmentCandidates.clear();
489 for (auto& [chamber, resolveMe] : segmentsPerChamber) {
490 SegmentVec_t resolvedSegments = m_ambiSolver->resolveAmbiguity(gctx, std::move(resolveMe));
491 segmentCandidates.insert(segmentCandidates.end(),
492 std::make_move_iterator(resolvedSegments.begin()),
493 std::make_move_iterator(resolvedSegments.end()));
494 }
495
496}

◆ setFilterPassed()

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

Set filter decision:

Reimplemented in AthFilterAlgorithm.

Definition at line 99 of file AthCommonAlgorithm.h.

99 {
101 }
virtual void setFilterPassed(bool state, const EventContext &ctx) const
Set filter decision:

◆ sysExecute()

StatusCode AthCommonAlgorithm< 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.

Reimplemented in AthAnalysisAlgorithm.

Definition at line 80 of file AthCommonAlgorithm.cxx.

41{
42 return BaseAlg::sysExecute (ctx);
43}

◆ sysInitialize()

StatusCode AthCommonAlgorithm< 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 AthAnalysisAlgorithm, AthFilterAlgorithm, AthHistogramAlgorithm, HypoBase, InputMakerBase, and PyAthena::Alg.

Definition at line 60 of file AthCommonAlgorithm.cxx.

71 {
73
74 if (sc.isFailure()) {
75 return sc;
76 }
77
78 ServiceHandle<ICondSvc> cs("CondSvc",name());
79 for (auto h : outputHandles()) {
80 if (h->isCondition() && h->mode() == Gaudi::DataHandle::Writer) {
81 // do this inside the loop so we don't create the CondSvc until needed
82 if ( cs.retrieve().isFailure() ) {
83 ATH_MSG_WARNING("no CondSvc found: won't autoreg WriteCondHandles");
85 }
86 if (cs->regHandle(this,*h).isFailure()) {
88 ATH_MSG_ERROR("unable to register WriteCondHandle " << h->fullKey()
89 << " with CondSvc");
90 }
91 }
92 }
93 return sc;
94}
virtual StatusCode sysInitialize() override
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 332 of file NswSegmentFinderAlg.h.

332{};

◆ m_ambiSolver

std::unique_ptr<SegmentFit::SegmentAmbiSolver> MuonR4::NswSegmentFinderAlg::m_ambiSolver {}
private

Definition at line 288 of file NswSegmentFinderAlg.h.

288{};

◆ m_calibTool

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

Definition at line 282 of file NswSegmentFinderAlg.h.

282{this, "Calibrator", "" };

◆ m_detMgr

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

Definition at line 334 of file NswSegmentFinderAlg.h.

334{};

◆ 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 306 of file NswSegmentFinderAlg.h.

306{this, "doOnlyMMCombinatorics", false};

◆ m_dumpObj

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

Definition at line 330 of file NswSegmentFinderAlg.h.

330{this, "dumpObj", false};

◆ m_dumpSeedStatistics

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

Definition at line 327 of file NswSegmentFinderAlg.h.

327{this, "dumpStatistics", true};

◆ m_etaKey

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

Definition at line 264 of file NswSegmentFinderAlg.h.

264{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 AthCommonAlgorithm< Gaudi::Algorithm >::m_extendedExtraObjects
privateinherited

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

Empty if no symlinks were found.

Definition at line 108 of file AthCommonAlgorithm.h.

◆ m_geoCtxKey

ActsTrk::GeoContextReadKey_t MuonR4::NswSegmentFinderAlg::m_geoCtxKey {this, "AlignmentKey", "ActsAlignment", "cond handle key"}
private

Definition at line 273 of file NswSegmentFinderAlg.h.

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

◆ m_idHelperSvc

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

Definition at line 276 of file NswSegmentFinderAlg.h.

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

◆ m_lineFitter

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

Definition at line 285 of file NswSegmentFinderAlg.h.

285{};

◆ m_markHitsFromSeed

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

Definition at line 303 of file NswSegmentFinderAlg.h.

303{this, "markHitsFromSeed", true};

◆ m_maxChi2

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

Definition at line 315 of file NswSegmentFinderAlg.h.

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

◆ m_maxClustersInLayer

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

Definition at line 318 of file NswSegmentFinderAlg.h.

318{this, "maxClustersInLayer", 8};

◆ m_maxdYWindow

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

Definition at line 321 of file NswSegmentFinderAlg.h.

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

◆ m_maxInvalidClusters

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

Definition at line 300 of file NswSegmentFinderAlg.h.

300{this, "maxInvalidClusters", 4};

◆ m_maxTanAlpha

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

Definition at line 324 of file NswSegmentFinderAlg.h.

324{this, "maxTanAlpha", 0.2};

◆ m_maxUsed

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

Definition at line 309 of file NswSegmentFinderAlg.h.

309{this, "maxHitIsUsed", 6};

◆ m_minClusSize

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

Definition at line 312 of file NswSegmentFinderAlg.h.

312{this, "minClusterSize", 1};

◆ m_minPullThreshold

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

Definition at line 294 of file NswSegmentFinderAlg.h.

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

◆ m_minSeedHits

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

Definition at line 297 of file NswSegmentFinderAlg.h.

297{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 279 of file NswSegmentFinderAlg.h.

279{this, "VisualizationTool", ""};

◆ m_windowTheta

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

Definition at line 291 of file NswSegmentFinderAlg.h.

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

◆ m_writeSegmentKey

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

Definition at line 270 of file NswSegmentFinderAlg.h.

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

◆ m_writeSegmentSeedKey

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

Definition at line 267 of file NswSegmentFinderAlg.h.

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

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