ATLAS Offline Software
Loading...
Searching...
No Matches
MuonR4::FastReco::GlobalPatternFinder::PatternState Struct Reference

Pattern state object storing pattern information during construction. More...

Collaboration diagram for MuonR4::FastReco::GlobalPatternFinder::PatternState:

Public Member Functions

 PatternState (const CandidateHit &seed, const std::int8_t expSector, const double seedTheta, const Config *cfg, const AthMessaging *logger)
 Constructor taking the seed information.
 PatternState ()=delete
 Delete default destructor - ensure patterns are always constructed from a seed or another pattern.
 PatternState (PatternState &&other) noexcept=default
 Move constructor.
PatternStateoperator= (PatternState &&other) noexcept=default
 Move assignment operator.
 PatternState (const PatternState &other)=default
 Copy constructor.
PatternStateoperator= (const PatternState &other)=default
 Copy assignment operator.
 ~PatternState ()=default
 Destructor.
void addHit (const CandidateHit &hit, const double residual, const double acceptWindow)
 Add a hit to the pattern and update the internal state.
void overWriteHit (const CandidateHit &newHit, const double newResidual, const double newAcceptWindow)
 Overwrite the hits on the last layer with the new one.
LineTestRes checkLineComp (const CandidateHit &testHit, const Amg::Vector3D &beamSpot)
 Method checking line compatibility of a test hit against the pattern.
LineTestRes computeLineResidual (const CandidateHit &testHit) const
 Method to compute the residual of a test hit against the pattern line.
bool isPhiCompatible (const double testPhi) const
 Method to check the phi compatibility of a test hit with a given pattern.
bool isInPattern (const HitPayload &hit) const
 Check wheter a hit is present in the pattern.
void finalizePatternEta ()
 Finalize the pattern building in eta and update its state.
void finalizePatternPhi ()
 Finalize the pattern building in phi and update its state.
void moveLineAnchorHit (const CandidateHit &refHit)
 Move the line anchor hit given a reference hit.
void updateLineParameters (const Amg::Vector3D &beamSpot)
 Update the line parameters based on the current hits.
double getMeanResidual2 () const
 Return the mean normalized residual squared.
uint8_t nBendingHits () const
 Return the number of hits in bending coordinate.
uint8_t nBendingLayers () const
 Return the number of layers in bending coordinate.
uint8_t nStations (const bool onlyGoodStations) const
 Method returning the number of stations.
uint8_t nMDTLastLayer () const
 Gives the number of MDT hits on the last layer.
std::vector< const SpacePointBucket * > getParentBuckets () const
 Get the buckets associated with the pattern.
bool isInLastLayer (const CandidateHit &hit) const
 Check whether a given hit is in the last layer.
bool operator== (const PatternState &other) const =delete
 Patterns are considered identical if they have the same hit content.
void print (std::ostream &ostr, bool detailed) const
 Print the pattern candidate.

Public Attributes

const Configcfg {nullptr}
 Pointer to cfg option.
const AthMessaginglogger {nullptr}
 Logger.
Acts::CloneablePtr< PatternHitVisualInfovisualInfo {nullptr}
 Pointer to Visual Information for pattern visualization.
CandidateHit lastInsertedHit {}
 Pointer to the last inserted hit.
CandidateHit prevLayerHit {}
 Pointer to the last hit in the second-to-last layer.
CandidateHit lineAnchorHit {}
 Pointer to the line anchor hit.
double theta {0.}
 Average theta & average phi of the pattern.
double phi {0.}
double meanNormResidual2 {0.}
 Mean over eta hits of the square of their residual divided by acceptance window.
double lastResidual {0.}
 Residual & acceptance window of the last inserted hit (needed when replacing a hit).
double lastAcceptWindow {0.}
double lineSlope {0.}
 Simple line model: slope and associated delta Z, i.e.
double dZ_slope {0.}
double LR_factor {-1.}
 Simple line model: factor for LR correction to be applied.
double anchorZ {0.}
 Simple line model: anchor Z and R.
double anchorR {0.}
ExpandedSector expSect {static_cast<int8_t>(0)}
 expanded MS sector
uint8_t nPrecisionLayers {0u}
 Counts of precision / non-precision / phi layers.
uint8_t nTriggerLayers {0u}
uint8_t nPhiLayers {0u}
bool isFinalized {false}
 Flag to indicate if the pattern has been finalized.
bool isOverlap {false}
 Flag to indicate if the pattern is overlapping with another one, used during overlap removal.
bool useBeamspot {false}
 Whether we used the beamspot to compute the line parameters.
bool needLineUpdate {false}
 Whether we need to update the pattern line the next time we find a hit in a new layer.
std::array< uint8_t, s_nStationsnMeasurementLayers {}
 Counts of measurement layers per station.
std::array< std::vector< CandidateHit >, s_nStationshitsPerStation {}
 Map collection of hits per station.
std::vector< HitPayloadphiOnlyHits {}
 Array holding phi-only hits.

Detailed Description

Pattern state object storing pattern information during construction.

Definition at line 190 of file GlobalPatternFinder.h.

Constructor & Destructor Documentation

◆ PatternState() [1/4]

MuonR4::FastReco::GlobalPatternFinder::PatternState::PatternState ( const CandidateHit & seed,
const std::int8_t expSector,
const double seedTheta,
const Config * cfg,
const AthMessaging * logger )

Constructor taking the seed information.

Parameters
seedseed hit
expSectorexpanded sector coordinate
seedThetaglobal theta of the seed

Update the hit counts in bending direction

Update the phi of the pattern

Add now the new hit

Definition at line 766 of file GlobalPatternFinder.cxx.

771 : cfg{cfg},
772 logger{logger},
776 theta{seedTheta},
777 expSect{ExpandedSector{expSector}} {
778
780 nMeasurementLayers[Acts::toUnderlying(seed.station)]++;
781 if (seed->isPrecision) nPrecisionLayers++;
782 else nTriggerLayers++;
784 if (seed->sp()->measuresPhi()) {
785 phi = seed->phi;
786 nPhiLayers++;
787 }
789 hitsPerStation[Acts::toUnderlying(seed.station)].push_back(seed);
790 needLineUpdate = true;
791}
std::array< uint8_t, s_nStations > nMeasurementLayers
Counts of measurement layers per station.
double theta
Average theta & average phi of the pattern.
bool needLineUpdate
Whether we need to update the pattern line the next time we find a hit in a new layer.
CandidateHit prevLayerHit
Pointer to the last hit in the second-to-last layer.
std::array< std::vector< CandidateHit >, s_nStations > hitsPerStation
Map collection of hits per station.
CandidateHit lineAnchorHit
Pointer to the line anchor hit.
uint8_t nPrecisionLayers
Counts of precision / non-precision / phi layers.
CandidateHit lastInsertedHit
Pointer to the last inserted hit.

◆ PatternState() [2/4]

MuonR4::FastReco::GlobalPatternFinder::PatternState::PatternState ( )
delete

Delete default destructor - ensure patterns are always constructed from a seed or another pattern.

◆ PatternState() [3/4]

MuonR4::FastReco::GlobalPatternFinder::PatternState::PatternState ( PatternState && other)
defaultnoexcept

Move constructor.

Parameters
otherother pattern state to move from

◆ PatternState() [4/4]

MuonR4::FastReco::GlobalPatternFinder::PatternState::PatternState ( const PatternState & other)
default

Copy constructor.

Parameters
otherother pattern state to copy from

◆ ~PatternState()

MuonR4::FastReco::GlobalPatternFinder::PatternState::~PatternState ( )
default

Destructor.

Member Function Documentation

◆ addHit()

void MuonR4::FastReco::GlobalPatternFinder::PatternState::addHit ( const CandidateHit & hit,
const double residual,
const double acceptWindow )

Add a hit to the pattern and update the internal state.

Parameters
hithit to be added
residualresidual of the hit
acceptWindowacceptance window

Update the pointers to previous layer hit

Update the hit counts in bending direction

Update the phi of the pattern if there are no phi hits yet

Add now the new hit

Update the residual. Since we can also add consecutive MDT hits without updating the residual, we need to check the accept window

Definition at line 1004 of file GlobalPatternFinder.cxx.

1006 {
1007
1008 if (hit.globLayer != lastInsertedHit.globLayer) {
1011
1013 nMeasurementLayers[Acts::toUnderlying(hit.station)]++;
1014 if (hit->isPrecision) nPrecisionLayers++;
1015 else nTriggerLayers++;
1017 if (hit.sp()->measuresPhi()) {
1018 if (nPhiLayers == 0) phi = hit->phi;
1019 nPhiLayers++;
1020 }
1021 }
1023 hitsPerStation[Acts::toUnderlying(hit.station)].push_back(hit);
1024 lastInsertedHit = hit;
1025
1027 if (acceptWindow > 0.) {
1028 meanNormResidual2 += Acts::square(residual / acceptWindow);
1029 lastAcceptWindow = acceptWindow;
1031 }
1032 // If the new compatible hit is in a different station, update the line anchor
1033 if (hit.station != lastInsertedHit.station) {
1034 moveLineAnchorHit(hit);
1035 }
1036 needLineUpdate = true;
1037}
void moveLineAnchorHit(const CandidateHit &refHit)
Move the line anchor hit given a reference hit.
double lastResidual
Residual & acceptance window of the last inserted hit (needed when replacing a hit).
double meanNormResidual2
Mean over eta hits of the square of their residual divided by acceptance window.

◆ checkLineComp()

GlobalPatternFinder::LineTestRes MuonR4::FastReco::GlobalPatternFinder::PatternState::checkLineComp ( const CandidateHit & testHit,
const Amg::Vector3D & beamSpot )

Method checking line compatibility of a test hit against the pattern.

Parameters
testHittest hit information
beamSpotBeam spot position, needed to update the pattern line
Returns
: result of the test, including the computed line residual and acceptance window

Helper function to make the result

Parameters
decisionThe decision for the test result if the residual is within the acceptance window
Returns
The test result

Sanity check: Test hit coincides with the last inserted hit

We add the test hit to the pattern if they are consecutive MDT hits

If they are not consecutive MDT hits && all insterted hits are on the same layer

If the primary measurement is the same and both measure phi, we keep the most compatibble in phi

sTGCs: we can have trigger hits (Pad) and precision hits (strip) on the same layer

Test hit is a trigger hit and last inserted is precision, keep the precision hit

Test hit is a precision hit and last inserted is trigger, if compatible we overwrite the last inserted hit

Definition at line 793 of file GlobalPatternFinder.cxx.

794 {
795 // We test hits in the same **expanded** sector, so we need just to compare hit's phi with the pattern's phi, if both available
796 if (nPhiLayers) {
797 const double maxPhiDiff {testHit.sp()->measuresPhi() ?
798 cfg->phiTolerance : sectorMap.sectorWidth(testHit.sector)};
799 if (std::abs(CxxUtils::deltaPhi(phi, static_cast<double>(testHit->phi))) > maxPhiDiff) {
800 PRINT_VERBOSE(__func__<<"() The pattern with phi = "<<inDegrees(phi)
801 <<" is not compatible with the test hit with phi "<<inDegrees(testHit->phi) << " - reject.");
802 return LineTestRes{};
803 }
804 }
805
809 auto makeResult = [&testHit, this](const LineTestDecision decision) -> LineTestRes {
810 LineTestRes res{computeLineResidual(testHit)};
811 if (res.residual < res.accWindow) {
812 res.result = decision;
813 }
814 if (visualInfo) {
815 visualInfo->hitLineInfo[testHit.sp()] = std::make_pair(lineSlope, res.accWindow);
816 }
817 return res;
818 };
819
820 /*************** Test hit is on a new layer — draw line from line anchor to lastHit */
821 if(testHit.globLayer != lastInsertedHit.globLayer) {
822 updateLineParameters(beamSpot);
823 return makeResult(LineTestDecision::eAddHit);
824 }
825 /*************** Test hit is on the same layer as the last inserted hit ***************/
827 if (testHit == lastInsertedHit) {
828 PRINT_VERBOSE(__func__<<"() Test hit is the same as last inserted hit - reject.");
829 return LineTestRes{};
830 }
832 if (areConsecutiveMdt(testHit, lastInsertedHit)) {
833 return LineTestRes{LineTestDecision::eConsecutiveMdt, -1., -1.};
834 }
836 if (lineAnchorHit.globLayer == lastInsertedHit.globLayer) {
837 PRINT_VERBOSE(__func__<<"() Test hit on same layer as seed with no prior hits, but not consecutive MDT hits - reject.");
838 return LineTestRes{};
839 }
841 if (testHit.sp()->primaryMeasurement() == lastInsertedHit.sp()->primaryMeasurement()) {
842 if (testHit.sp()->measuresPhi() && !lastInsertedHit.sp()->measuresPhi()) {
843 return makeResult(LineTestDecision::eOverwriteLastHit);
844 }
845 if (!testHit.sp()->measuresPhi() && lastInsertedHit.sp()->measuresPhi()) {
846 return LineTestRes{};
847 }
848 if (nPhiLayers && std::abs(CxxUtils::deltaPhi(phi, static_cast<double>(testHit->phi))) <
849 std::abs(CxxUtils::deltaPhi(phi, static_cast<double>(lastInsertedHit->phi)))) {
850 return makeResult(LineTestDecision::eOverwriteLastHit);
851 }
852 return LineTestRes{};
853 }
855 if (testHit->isPrecision != lastInsertedHit->isPrecision) {
856 if (lastInsertedHit->isPrecision) {
858 PRINT_VERBOSE(__func__<<"() Test hit is a trigger hit and last inserted hit is precision on the same layer - keep the precision hit.");
859 return LineTestRes{};
860 }
862 PRINT_VERBOSE(__func__<<"() Test hit is a precision hit and last inserted hit is trigger on the same layer - check residual...");
863 return makeResult(LineTestDecision::eOverwriteLastHit);
864 }
865 return makeResult(LineTestDecision::eBranchPattern);
866}
std::pair< std::vector< unsigned int >, bool > res
#define PRINT_VERBOSE(MSG)
Helper macro for printing verbose messages for debugging.
static bool areConsecutiveMdt(const CandidateHit &hit1, const CandidateHit &hit2)
Helper function to check whether two hits are consecutive MDT measurements.
LineTestDecision
: Enum for possible outcomes of pattern line compatibility test
@ eBranchPattern
Test successfull with multiple pattern hits on same layer, branch the pattern.
T deltaPhi(T phiA, T phiB)
Return difference phiA - phiB in range [-pi, pi].
Definition phihelper.h:42
Acts::CloneablePtr< PatternHitVisualInfo > visualInfo
Pointer to Visual Information for pattern visualization.
LineTestRes computeLineResidual(const CandidateHit &testHit) const
Method to compute the residual of a test hit against the pattern line.
void updateLineParameters(const Amg::Vector3D &beamSpot)
Update the line parameters based on the current hits.
double lineSlope
Simple line model: slope and associated delta Z, i.e.

◆ computeLineResidual()

GlobalPatternFinder::LineTestRes MuonR4::FastReco::GlobalPatternFinder::PatternState::computeLineResidual ( const CandidateHit & testHit) const

Method to compute the residual of a test hit against the pattern line.

Parameters
testHittest hit information
Returns
: Test result holding the residual and acceptance window. The decision is set later.

The dynamic acceptance window is defined using the error propagation law for the residual. We have two contributions: the line extrapolation distance (propagation factor) and the uncertainty on the line slope (geometrical factor)

Alpha parameter determining the propagation/ line extrapolation magnitude

Loosen the window when using the beamspot as reference, as the line slope is less well defined

Apply LR correction if needed

Definition at line 945 of file GlobalPatternFinder.cxx.

945 {
946 LineTestRes res{};
947
948 // Compute the residual
949 const double dZ_res {testHit.Z - anchorZ};
950 res.residual = (testHit.R - anchorR) - lineSlope * dZ_res;
951
955 const double geoFactor {1.+ Acts::square(lineSlope)};
956 const double alpha {dZ_res / dZ_slope};
957 const double propFactor {1. - alpha + Acts::square(alpha)};
958 res.accWindow = cfg->baseRWindow * std::sqrt(2*geoFactor * propFactor);
960 if (useBeamspot) res.accWindow *= 1.5;
961 if (testHit->station != lastInsertedHit.station ||
962 (testHit->station != prevLayerHit.station && testHit.globLayer == lastInsertedHit.globLayer)) {
963 res.accWindow *= 2.;
964 }
965
967 if (LR_factor > 0.) {
968 const double LRcorrection {dZ_res * geoFactor * LR_factor};
969 PRINT_VERBOSE(__func__<<"() signed residual: " << res.residual << " -> Apply LR correction: " << LRcorrection);
970 res.residual = std::min(std::abs(res.residual-LRcorrection), std::abs(res.residual+LRcorrection));
971 } else {
972 res.residual = std::abs(res.residual);
973 }
974
975 PRINT_VERBOSE(__func__<<"() "<< brief(*this) << "\nUse beamspot: " << useBeamspot << ", Slope: " << lineSlope
976 << ", Residual: " << res.residual << ", Window: " << res.accWindow << ", Geometrical Factor: "
977 << std::sqrt(geoFactor) << ", Propagation Factor: " << std::sqrt(propFactor));
978 return res;
979}
static PatternPrintView brief(const PatternState &p)
Print the pattern candidate and stream operator.
bool useBeamspot
Whether we used the beamspot to compute the line parameters.
double LR_factor
Simple line model: factor for LR correction to be applied.
double anchorZ
Simple line model: anchor Z and R.

◆ finalizePatternEta()

void MuonR4::FastReco::GlobalPatternFinder::PatternState::finalizePatternEta ( )

Finalize the pattern building in eta and update its state.

This method is called at the end of pattern building in eta, so we don't have phi-only hits yet

Definition at line 1089 of file GlobalPatternFinder.cxx.

1089 {
1091 theta = 0.;
1092 for (const std::vector<CandidateHit>& hits : hitsPerStation) {
1093 for (const auto& hit : hits) {
1094 theta += atan2(hit.R, hit.Z);
1095 }
1096 }
1097 theta /= nBendingHits();
1098}
uint8_t nBendingHits() const
Return the number of hits in bending coordinate.

◆ finalizePatternPhi()

void MuonR4::FastReco::GlobalPatternFinder::PatternState::finalizePatternPhi ( )

Finalize the pattern building in phi and update its state.

If there are no phi hits, we just use the central phi of the sector/overlap region

Definition at line 1099 of file GlobalPatternFinder.cxx.

1099 {
1100 if (!nPhiLayers) {
1102 phi = sectorMap.sectorOverlapPhi(expSect.msSector(), expSect.adjacentMsSector());
1103 return;
1104 }
1105 double deltaPhiAcc {0.};
1106 std::optional<double> centralPhi {};
1107 auto processPhiHit = [&deltaPhiAcc, &centralPhi](const HitPayload& hit){
1108 if (!hit->measuresPhi()) {
1109 return;
1110 }
1111 if (!centralPhi) {
1112 centralPhi = hit.phi;
1113 }
1114 deltaPhiAcc += CxxUtils::deltaPhi(static_cast<double>(hit.phi), *centralPhi);
1115 };
1116 for (const std::vector<CandidateHit>& hits : hitsPerStation) {
1117 for (const auto& hit : hits) {
1118 processPhiHit(*hit);
1119 }
1120 }
1121 for (const HitPayload& hit : phiOnlyHits) {
1122 processPhiHit(hit);
1123 }
1124 phi = CxxUtils::wrapToPi(centralPhi.value_or(0.) + deltaPhiAcc / nPhiLayers);
1125}
T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
Definition phihelper.h:24
std::vector< HitPayload > phiOnlyHits
Array holding phi-only hits.

◆ getMeanResidual2()

double MuonR4::FastReco::GlobalPatternFinder::PatternState::getMeanResidual2 ( ) const

Return the mean normalized residual squared.

Definition at line 1143 of file GlobalPatternFinder.cxx.

1143 {
1144 if (isFinalized) {
1145 return meanNormResidual2;
1146 }
1148}
bool isFinalized
Flag to indicate if the pattern has been finalized.
uint8_t nBendingLayers() const
Return the number of layers in bending coordinate.

◆ getParentBuckets()

std::vector< const SpacePointBucket * > MuonR4::FastReco::GlobalPatternFinder::PatternState::getParentBuckets ( ) const

Get the buckets associated with the pattern.

Definition at line 1160 of file GlobalPatternFinder.cxx.

1160 {
1161 std::vector<const SpacePointBucket*> buckets{};
1162 for (const std::vector<CandidateHit>& hits : hitsPerStation) {
1163 for (const auto& hit : hits) {
1164 if (std::ranges::find(buckets, hit->bucket) == buckets.end()) {
1165 buckets.push_back(hit->bucket);
1166 }
1167 }
1168 }
1169 return buckets;
1170}

◆ isInLastLayer()

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::isInLastLayer ( const CandidateHit & hit) const

Check whether a given hit is in the last layer.

Definition at line 1171 of file GlobalPatternFinder.cxx.

1171 {
1172 if (lastInsertedHit.globLayer != hit.globLayer) {
1173 return false;
1174 }
1175 if (hit.isStraw) {
1176 const auto& stationHits {hitsPerStation[Acts::toUnderlying(hit.station)]};
1177 for (auto it = stationHits.rbegin(); it != stationHits.rend(); ++it) {
1178 if (it->globLayer != hit.globLayer) {
1179 return false;
1180 }
1181 if (*it == hit) {
1182 return true;
1183 }
1184 }
1185 return false;
1186 }
1187 return lastInsertedHit == hit;
1188}

◆ isInPattern()

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::isInPattern ( const HitPayload & hit) const

Check wheter a hit is present in the pattern.

Parameters
hithit to be checked
Returns
: boolean indicating if the hit is in the pattern

Definition at line 1084 of file GlobalPatternFinder.cxx.

1084 {
1085 const auto& hits {hitsPerStation[Acts::toUnderlying(hit.station)]};
1086 return std::ranges::find_if(hits,
1087 [&hit](const CandidateHit& c){ return *c == hit; }) != hits.end();
1088}

◆ isPhiCompatible()

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::isPhiCompatible ( const double testPhi) const

Method to check the phi compatibility of a test hit with a given pattern.

Parameters
testPhitest global phi
Returns
: true if the test hit is phi compatible with the pattern, false otherwise

We check that the test hit is compatible with the pattern phi, if available, which is given by the first phi measurement in the pattern. If the pattern doesn't have a phi yet, we check that the test hit is in the same pattern sector(s)

Definition at line 980 of file GlobalPatternFinder.cxx.

980 {
984 if (nPhiLayers) {
985 if (std::abs(CxxUtils::deltaPhi(phi, testPhi)) > cfg->phiTolerance) {
986 PRINT_VERBOSE(__func__<<"() The pattern with phi = "<<inDegrees(phi)
987 <<" is not compatible with the test hit with phi "<<inDegrees(testPhi));
988 return false;
989 }
990 } else {
991 const unsigned sector1 {expSect.msSector()};
992 const unsigned sector2 {expSect.adjacentMsSector()};
993 const bool isCompatible {sector1 == sector2
994 ? sectorMap.insideSector(sector1, testPhi)
995 : sectorMap.insideSector(sector1, testPhi) && sectorMap.insideSector(sector2, testPhi)};
996 if (!isCompatible) {
997 PRINT_VERBOSE(__func__<<"() The test hit with phi = "<<inDegrees(testPhi)
998 <<" is not inside the pattern sectors: "<<sector1<<" and "<<sector2);
999 return false;
1000 }
1001 }
1002 return true;
1003}

◆ moveLineAnchorHit()

void MuonR4::FastReco::GlobalPatternFinder::PatternState::moveLineAnchorHit ( const CandidateHit & refHit)

Move the line anchor hit given a reference hit.

The anchor is defined as the closest hit in the closest station to the referece hit,

Definition at line 867 of file GlobalPatternFinder.cxx.

867 {
868 // Treat first the special case where we have only one station
869 if (nStations(/*onlyGoodStations=*/ false) < 2) {
870 // If we call this method with only one station, it means that we inverted the hit search direction without
871 // finding any hit in other stations beside the initial one. So the anchor is the last added hit.
873 return;
874 }
875 // Find first the closest station to the reference station among the pattern stations
876 const auto& closestStIt = std::ranges::min_element(hitsPerStation, std::ranges::less{},
877 [&refHit](const auto& hits){
878 if (hits.empty() || hits.front().station == refHit.station) {
879 return std::numeric_limits<int>::max();
880 }
881 return std::abs(hits.front().globLayer - refHit.globLayer);
882 });
883
884 // Then find the closest hit in that station to the reference hit
885 const auto& hits {*closestStIt};
886 auto it {std::ranges::min_element(hits, std::ranges::less{},
887 [&refHit](const CandidateHit& hit){
888 return std::abs(hit.globLayer - refHit.globLayer); })};
889
890 // Find how many hits in the same layer we have, to be able to set the line anchor at the central hit
891 uint8_t nSameLayer {1u};
892 for (auto jt = std::next(it); jt != hits.end() && jt->globLayer == it->globLayer; ++jt) {
893 ++nSameLayer;
894 }
895 lineAnchorHit = *std::next(it, (nSameLayer - 1u) / 2u);
896}
uint8_t nStations(const bool onlyGoodStations) const
Method returning the number of stations.

◆ nBendingHits()

uint8_t MuonR4::FastReco::GlobalPatternFinder::PatternState::nBendingHits ( ) const

Return the number of hits in bending coordinate.

Definition at line 1135 of file GlobalPatternFinder.cxx.

1135 {
1136 return std::accumulate(hitsPerStation.begin(), hitsPerStation.end(), uint8_t{0u},
1137 [](uint8_t acc, const auto& hits){
1138 return acc + hits.size(); });
1139}

◆ nBendingLayers()

uint8_t MuonR4::FastReco::GlobalPatternFinder::PatternState::nBendingLayers ( ) const

Return the number of layers in bending coordinate.

Definition at line 1140 of file GlobalPatternFinder.cxx.

1140 {
1142}

◆ nMDTLastLayer()

uint8_t MuonR4::FastReco::GlobalPatternFinder::PatternState::nMDTLastLayer ( ) const

Gives the number of MDT hits on the last layer.

Definition at line 1149 of file GlobalPatternFinder.cxx.

1149 {
1150 const auto& stationHits {hitsPerStation[Acts::toUnderlying(lastInsertedHit.station)]};
1151 uint8_t nMdtLastayer {0u};
1152 for (auto it = stationHits.rbegin(); it != stationHits.rend(); ++it) {
1153 if (it->globLayer != lastInsertedHit.globLayer) {
1154 break;
1155 }
1156 nMdtLastayer++;
1157 }
1158 return nMdtLastayer;
1159}
@ u
Enums for curvilinear frames.
Definition ParamDefs.h:77

◆ nStations()

uint8_t MuonR4::FastReco::GlobalPatternFinder::PatternState::nStations ( const bool onlyGoodStations) const

Method returning the number of stations.

Parameters
onlyGoodStationsflag to indicate if only good stations should be counted, i.e. having a minimum number of hits

Definition at line 1126 of file GlobalPatternFinder.cxx.

1126 {
1127 uint8_t nStations {0u};
1128 for (uint8_t st{0u}; st < s_nStations; ++st) {
1129 if (!hitsPerStation[st].empty() && (!onlyGoodStations || nMeasurementLayers[st] >= cfg->minStationLayers)) {
1130 nStations++;
1131 }
1132 }
1133 return nStations;
1134}
static const Attributes_t empty

◆ operator=() [1/2]

PatternState & MuonR4::FastReco::GlobalPatternFinder::PatternState::operator= ( const PatternState & other)
default

Copy assignment operator.

Parameters
otherother pattern state to copy from

◆ operator=() [2/2]

PatternState & MuonR4::FastReco::GlobalPatternFinder::PatternState::operator= ( PatternState && other)
defaultnoexcept

Move assignment operator.

Parameters
otherother pattern state to move from

◆ operator==()

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::operator== ( const PatternState & other) const
delete

Patterns are considered identical if they have the same hit content.

However, map comparison is very expensive

◆ overWriteHit()

void MuonR4::FastReco::GlobalPatternFinder::PatternState::overWriteHit ( const CandidateHit & newHit,
const double newResidual,
const double newAcceptWindow )

Overwrite the hits on the last layer with the new one.

Parameters
newHitnew hit to replace with
newResidualresidual of the new hit
newAcceptWindowacceptance window of the new hit
beamSpotneeded to update line parameters

Update the phi counts

Update the residual

Add now the new hit

Definition at line 1038 of file GlobalPatternFinder.cxx.

1040 {
1041 const StIndex st {newHit.station};
1042 if (st != lastInsertedHit.station || lastInsertedHit.globLayer != newHit.globLayer) {
1043 throw std::runtime_error(std::format(
1044 "Trying to overwrite a hit in station/layer {}/{} with another one from station/layer {}/{}",
1045 stName(lastInsertedHit.station), lastInsertedHit.globLayer, stName(st), newHit.globLayer));
1046 }
1047 /* We expect to overwrite hits of the same type (precision/trigger), since we only branch when we have
1048 * compatible hits in the same layer, except for sTGC hits, where we have pad and strips in the same layer */
1049 if (lastInsertedHit->isPrecision != newHit->isPrecision) {
1050 if (/*lastInsertedHit->isPrecision ||*/ newHit.sp()->type() != xAOD::UncalibMeasType::sTgcStripType) {
1051 std::stringstream ss {};
1052 ss << "Trying to overwrite a hit with incompatible type\n";
1053 ss << "Old hit: " << **lastInsertedHit << ", isPrecision: " << lastInsertedHit->isPrecision << ", measuresEta: " << lastInsertedHit.sp()->measuresEta() << "\n";
1054 ss << "New hit: " << **newHit << ", isPrecision: " << newHit->isPrecision << ", measuresEta: " << newHit.sp()->measuresEta();
1055 throw std::runtime_error(ss.str());
1056 }
1059 }
1061 if (lastInsertedHit.sp()->measuresPhi()) nPhiLayers--;
1062 if (newHit.sp()->measuresPhi()) {
1063 if (nPhiLayers == 0) phi = newHit->phi;
1064 nPhiLayers++;
1065 }
1067 meanNormResidual2 += Acts::square(newResidual / newAcceptWindow) - Acts::square(lastResidual / lastAcceptWindow);
1068 lastAcceptWindow = newAcceptWindow;
1069 lastResidual = newResidual;
1070
1071 auto& stHits {hitsPerStation[Acts::toUnderlying(st)]};
1072 /* Remove ALL hits in the same layer */
1073 while (!stHits.empty()) {
1074 if (stHits.back().globLayer != lastInsertedHit.globLayer) {
1075 break;
1076 }
1077 stHits.pop_back();
1078 }
1080 hitsPerStation[Acts::toUnderlying(st)].push_back(newHit);
1081 lastInsertedHit = newHit;
1082 needLineUpdate = true;
1083}
static Double_t ss
Muon::MuonStationIndex::StIndex StIndex
Type alias for the station index.
const std::string & stName(StIndex index)
convert StIndex into a string

◆ print()

void MuonR4::FastReco::GlobalPatternFinder::PatternState::print ( std::ostream & ostr,
bool detailed ) const

Print the pattern candidate.

Definition at line 1292 of file GlobalPatternFinder.cxx.

1292 {
1293 ostr<<"Pattern state, Exp Sector: "<<(int)expSect.sector()<<", Theta: "<<inDegrees(theta) << ", Phi: "<<inDegrees(phi);
1294 ostr<<", nPrec: "<<(int)nPrecisionLayers<<", nEtaNonPrec: "<<(int)nTriggerLayers<<", nPhi: "<<(int)nPhiLayers;
1295 ostr<<", mean norma res sq: "<<getMeanResidual2();
1296 ostr<<", Hit per station: \n";
1297 for (uint8_t st{0u}; st < s_nStations; ++st) {
1298 const auto& hits {hitsPerStation[st]};
1299 if (hits.empty()) continue;
1300
1301 ostr<<" Station "<<Muon::MuonStationIndex::stName(static_cast<StIndex>(st))<<" has "<<hits.size()<<" hits ";
1302 if (detailed) {
1303 ostr<<"\n";
1304 for (const auto& hit : hits) {
1305 ostr<<" "<<**hit<<", R: "<<hit.R<<", Z: "<<hit.Z<<", Phi: "<<inDegrees(hit->phi)<<", loc/glob lay: "<<(int)hit->locLayer<<"/"<<(int)hit.globLayer<<"\n";
1306 }
1307 }
1308 }
1309 if (!detailed) {
1310 ostr <<"\n Last hit: "<<**lastInsertedHit<<"\n prevLayerHit: "<<**prevLayerHit << "\n lineAnchorHit: "<<**lineAnchorHit;
1311 }
1312}
static PatternPrintView detailed(const PatternState &p)
double getMeanResidual2() const
Return the mean normalized residual squared.

◆ updateLineParameters()

void MuonR4::FastReco::GlobalPatternFinder::PatternState::updateLineParameters ( const Amg::Vector3D & beamSpot)

Update the line parameters based on the current hits.

Parameters
beamSpotposition of the beam spot, needed when there are not enough hits

Definition at line 897 of file GlobalPatternFinder.cxx.

897 {
898 if (!needLineUpdate) {
899 return;
900 }
901 const StIndex lastSt {lastInsertedHit.station};
902 auto& hitsLastSt {hitsPerStation[Acts::toUnderlying(lastSt)]};
903 // Check whether we have to use the beamspot instead of the last pattern hit to draw the line with the line anchor.
904 const bool new_useBeamspot {lastSt == lineAnchorHit.station &&
905 (isBarrel(lastSt) ? std::abs(lastInsertedHit.R - lineAnchorHit.R)
906 : std::abs(lastInsertedHit.Z - lineAnchorHit.Z)) <= cfg->minLayerSeparation};
907
908 const double new_anchorR {new_useBeamspot ? beamSpot.perp() : lineAnchorHit.R};
909 const double new_anchorZ {new_useBeamspot ? beamSpot.z() : lineAnchorHit.Z};
910
911 /* Determine the (average) coordinates of the last added hit(s). If it is a straw, find
912 * the consecutive (MDT) hits on the same layer and return use average position
913 * for next computations — gives a more central reference for the line direction */
914 double refR {0.}, refZ {0.};
915 uint8_t nSameLayer {0u};
916 for (const auto& hit : hitsLastSt) {
917 if (hit.globLayer != lastInsertedHit.globLayer) continue;
918 refR += hit.R;
919 refZ += hit.Z;
920 ++nSameLayer;
921 }
922 refR /= nSameLayer;
923 refZ /= nSameLayer;
924
925 const double new_dZ_slope {refZ - new_anchorZ};
926 if (std::abs(new_dZ_slope) < 1.) {
927 PRINT_VERBOSE("updateLineParameters() Couldn't update the line parameters.");
928 return;
929 }
930 const double dR_slope {refR - new_anchorR};
931 PRINT_VERBOSE("updateLineParameters() Update line parameters dZ/slope: "<<dZ_slope<<", " << lineSlope
932 << " --> " << new_dZ_slope << ", " << dR_slope / new_dZ_slope);
933
934 lineSlope = dR_slope / new_dZ_slope;
935 dZ_slope = new_dZ_slope;
936 anchorR = new_anchorR;
937 anchorZ = new_anchorZ;
938 useBeamspot = new_useBeamspot;
939 // If we have only one hit and it is a straw, store the LR correction factor
940 LR_factor = (nSameLayer == 1u && lastInsertedHit.isStraw) ?
941 lastInsertedHit.sp()->driftRadius()/ Acts::fastHypot(dZ_slope, dR_slope) : -1.;
942 needLineUpdate = false;
943}
bool isBarrel(const ChIndex index)
Returns true if the chamber index points to a barrel chamber.
AthConfigFlags beamSpot(AthConfigFlags flags, str instanceName, str recoMode)

Member Data Documentation

◆ anchorR

double MuonR4::FastReco::GlobalPatternFinder::PatternState::anchorR {0.}

Definition at line 303 of file GlobalPatternFinder.h.

303{0.};

◆ anchorZ

double MuonR4::FastReco::GlobalPatternFinder::PatternState::anchorZ {0.}

Simple line model: anchor Z and R.

Same as lineAnchorHit, except when using beamspot

Definition at line 302 of file GlobalPatternFinder.h.

302{0.};

◆ cfg

const Config* MuonR4::FastReco::GlobalPatternFinder::PatternState::cfg {nullptr}

Pointer to cfg option.

Definition at line 277 of file GlobalPatternFinder.h.

277{nullptr};

◆ dZ_slope

double MuonR4::FastReco::GlobalPatternFinder::PatternState::dZ_slope {0.}

Definition at line 298 of file GlobalPatternFinder.h.

298{0.};

◆ expSect

ExpandedSector MuonR4::FastReco::GlobalPatternFinder::PatternState::expSect {static_cast<int8_t>(0)}

expanded MS sector

Definition at line 305 of file GlobalPatternFinder.h.

305{static_cast<int8_t>(0)};

◆ hitsPerStation

std::array<std::vector<CandidateHit>, s_nStations> MuonR4::FastReco::GlobalPatternFinder::PatternState::hitsPerStation {}

Map collection of hits per station.

A pattern is determined by the hits belonging to it.

Definition at line 322 of file GlobalPatternFinder.h.

322{};

◆ isFinalized

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::isFinalized {false}

Flag to indicate if the pattern has been finalized.

Definition at line 311 of file GlobalPatternFinder.h.

311{false};

◆ isOverlap

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::isOverlap {false}

Flag to indicate if the pattern is overlapping with another one, used during overlap removal.

Definition at line 313 of file GlobalPatternFinder.h.

313{false};

◆ lastAcceptWindow

double MuonR4::FastReco::GlobalPatternFinder::PatternState::lastAcceptWindow {0.}

Definition at line 295 of file GlobalPatternFinder.h.

295{0.};

◆ lastInsertedHit

CandidateHit MuonR4::FastReco::GlobalPatternFinder::PatternState::lastInsertedHit {}

Pointer to the last inserted hit.

Needed to speed-up lookup

Definition at line 283 of file GlobalPatternFinder.h.

283{};

◆ lastResidual

double MuonR4::FastReco::GlobalPatternFinder::PatternState::lastResidual {0.}

Residual & acceptance window of the last inserted hit (needed when replacing a hit).

Definition at line 294 of file GlobalPatternFinder.h.

294{0.};

◆ lineAnchorHit

CandidateHit MuonR4::FastReco::GlobalPatternFinder::PatternState::lineAnchorHit {}

Pointer to the line anchor hit.

Definition at line 287 of file GlobalPatternFinder.h.

287{};

◆ lineSlope

double MuonR4::FastReco::GlobalPatternFinder::PatternState::lineSlope {0.}

Simple line model: slope and associated delta Z, i.e.

the distance in Z between the two points defining the line

Definition at line 297 of file GlobalPatternFinder.h.

297{0.};

◆ logger

const AthMessaging* MuonR4::FastReco::GlobalPatternFinder::PatternState::logger {nullptr}

Logger.

Definition at line 279 of file GlobalPatternFinder.h.

279{nullptr};

◆ LR_factor

double MuonR4::FastReco::GlobalPatternFinder::PatternState::LR_factor {-1.}

Simple line model: factor for LR correction to be applied.

Definition at line 300 of file GlobalPatternFinder.h.

300{-1.};

◆ meanNormResidual2

double MuonR4::FastReco::GlobalPatternFinder::PatternState::meanNormResidual2 {0.}

Mean over eta hits of the square of their residual divided by acceptance window.

Definition at line 292 of file GlobalPatternFinder.h.

292{0.};

◆ needLineUpdate

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::needLineUpdate {false}

Whether we need to update the pattern line the next time we find a hit in a new layer.

Definition at line 317 of file GlobalPatternFinder.h.

317{false};

◆ nMeasurementLayers

std::array<uint8_t, s_nStations> MuonR4::FastReco::GlobalPatternFinder::PatternState::nMeasurementLayers {}

Counts of measurement layers per station.

Definition at line 320 of file GlobalPatternFinder.h.

320{};

◆ nPhiLayers

uint8_t MuonR4::FastReco::GlobalPatternFinder::PatternState::nPhiLayers {0u}

Definition at line 309 of file GlobalPatternFinder.h.

309{0u};

◆ nPrecisionLayers

uint8_t MuonR4::FastReco::GlobalPatternFinder::PatternState::nPrecisionLayers {0u}

Counts of precision / non-precision / phi layers.

Definition at line 307 of file GlobalPatternFinder.h.

307{0u};

◆ nTriggerLayers

uint8_t MuonR4::FastReco::GlobalPatternFinder::PatternState::nTriggerLayers {0u}

Definition at line 308 of file GlobalPatternFinder.h.

308{0u};

◆ phi

double MuonR4::FastReco::GlobalPatternFinder::PatternState::phi {0.}

Definition at line 290 of file GlobalPatternFinder.h.

290{0.};

◆ phiOnlyHits

std::vector<HitPayload> MuonR4::FastReco::GlobalPatternFinder::PatternState::phiOnlyHits {}

Array holding phi-only hits.

Definition at line 324 of file GlobalPatternFinder.h.

324{};

◆ prevLayerHit

CandidateHit MuonR4::FastReco::GlobalPatternFinder::PatternState::prevLayerHit {}

Pointer to the last hit in the second-to-last layer.

Definition at line 285 of file GlobalPatternFinder.h.

285{};

◆ theta

double MuonR4::FastReco::GlobalPatternFinder::PatternState::theta {0.}

Average theta & average phi of the pattern.

Definition at line 289 of file GlobalPatternFinder.h.

289{0.};

◆ useBeamspot

bool MuonR4::FastReco::GlobalPatternFinder::PatternState::useBeamspot {false}

Whether we used the beamspot to compute the line parameters.

Definition at line 315 of file GlobalPatternFinder.h.

315{false};

◆ visualInfo

Acts::CloneablePtr<PatternHitVisualInfo> MuonR4::FastReco::GlobalPatternFinder::PatternState::visualInfo {nullptr}

Pointer to Visual Information for pattern visualization.

Definition at line 281 of file GlobalPatternFinder.h.

281{nullptr};

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