22struct CoincidenceQualityCounts {
23 std::size_t nThreeOfThree{0};
24 std::size_t nTwoOfThree{0};
25 std::size_t nOneOfThree{0};
26 std::size_t nTwoOfTwo{0};
27 std::size_t nOneOfTwo{0};
30void countCoincidenceQuality(
32 CoincidenceQualityCounts& counts) {
59 const std::string calibrationDirectory =
61 if (calibrationDirectory.empty()) {
62 ATH_MSG_ERROR(
"Could not resolve the GroupData development directory");
63 return StatusCode::FAILURE;
65 const std::string ptCalibrationPath =
71 return StatusCode::FAILURE;
74 <<
m_ptLut->version() <<
" from " << ptCalibrationPath
75 <<
" (eta bins=" <<
m_ptLut->etaBins()
76 <<
", folded-phi bins=" <<
m_ptLut->phiBinsPerFold()
77 <<
", knots=" <<
m_ptLut->knotCount()
79 << (
m_ptLut->isDevelopmentPayload() ?
"development"
83 const std::string goodMagMapPath =
89 return StatusCode::FAILURE;
94 <<
", folded-phi bins=" <<
m_goodMagMap->phiBinsPerFold()
95 <<
", poor bins=" <<
m_goodMagMap->poorBinCount() <<
")");
96 return StatusCode::SUCCESS;
101 const EventContext& ctx)
const {
102 return build(rdos, candidates,
nullptr, ctx);
114 if (!detectorManagerHandle.
isValid()) {
116 return StatusCode::FAILURE;
119 detectorManagerHandle.
cptr();
125 hitGroups, statistics));
143 std::move(segmentConfig)};
145 segmentStatistics, segments));
149 overlapClassification.
classify(candidates, overlapStatistics);
151 std::size_t nValidPtEstimates = 0U;
154 m_ptLut->evaluate(candidate.eta, candidate.phi, candidate.deltaTheta);
156 candidate.eta, candidate.phi,
m_ptLut->absEtaMin(),
160 candidate.preInnerCoincidenceThreshold = evaluation.
thresholdCode;
164 const std::size_t nInvalidPtEstimates =
165 candidates.size() - nValidPtEstimates;
166 ATH_MSG_DEBUG(
"Floating-pT evaluation: valid=" << nValidPtEstimates
168 << nInvalidPtEstimates);
170 CoincidenceQualityCounts totalCounts;
171 CoincidenceQualityCounts m1WireCounts;
172 CoincidenceQualityCounts m1StripCounts;
173 CoincidenceQualityCounts m2WireCounts;
174 CoincidenceQualityCounts m2StripCounts;
175 CoincidenceQualityCounts m3WireCounts;
176 CoincidenceQualityCounts m3StripCounts;
179 countCoincidenceQuality(coincidence, totalCounts);
181 CoincidenceQualityCounts* stationCounts{
nullptr};
183 stationCounts = coincidence.
isStrip ? &m1StripCounts : &m1WireCounts;
185 stationCounts = coincidence.
isStrip ? &m2StripCounts : &m2WireCounts;
187 stationCounts = coincidence.
isStrip ? &m3StripCounts : &m3WireCounts;
189 if (stationCounts !=
nullptr) {
190 countCoincidenceQuality(coincidence, *stationCounts);
195 << statistics.
nRawData <<
" raw-data words in "
196 << hitGroups.size() <<
" groups: wire="
199 << statistics.
nM1Hits <<
", M2="
200 << statistics.
nM2Hits <<
", M3="
201 << statistics.
nM3Hits <<
", inner="
204 <<
", mapping failures="
206 <<
"; station coincidences="
207 << coincidences.size() <<
" (3/3="
208 << totalCounts.nThreeOfThree <<
", 2/3="
209 << totalCounts.nTwoOfThree <<
", 1/3="
210 << totalCounts.nOneOfThree <<
", 2/2="
211 << totalCounts.nTwoOfTwo <<
", 1/2="
212 << totalCounts.nOneOfTwo <<
")");
215 << m1WireCounts.nThreeOfThree <<
", 2/3="
216 << m1WireCounts.nTwoOfThree <<
", 1/3="
217 << m1WireCounts.nOneOfThree <<
"), M1 strip=(2/2="
218 << m1StripCounts.nTwoOfTwo <<
", 1/2="
219 << m1StripCounts.nOneOfTwo <<
"), M2 wire=(2/2="
220 << m2WireCounts.nTwoOfTwo <<
", 1/2="
221 << m2WireCounts.nOneOfTwo <<
"), M2 strip=(2/2="
222 << m2StripCounts.nTwoOfTwo <<
", 1/2="
223 << m2StripCounts.nOneOfTwo <<
"), M3 wire=(2/2="
224 << m3WireCounts.nTwoOfTwo <<
", 1/2="
225 << m3WireCounts.nOneOfTwo <<
"), M3 strip=(2/2="
226 << m3StripCounts.nTwoOfTwo <<
", 1/2="
227 << m3StripCounts.nOneOfTwo <<
")");
232 << candidates.size() <<
" (M1M2M3="
243 <<
"), projectionRejected="
245 <<
", projectionDuplicates="
247 <<
", projectionLimited="
250 <<
", candidateDuplicates="
252 <<
", localDuplicates="
254 <<
", candidateLimited="
258 << overlapStatistics.
nGroups <<
", candidates="
259 << overlapStatistics.
nCandidates <<
", maxMultiplicity="
262 for (std::size_t groupId = 1U;
263 groupId <= overlapStatistics.
nGroups; ++groupId) {
264 std::vector<std::size_t> memberIndices;
266 if (candidates[
index].overlapGroupId == groupId) {
267 memberIndices.emplace_back(
index);
270 if (memberIndices.empty())
continue;
271 std::ostringstream members;
272 for (std::size_t position = 0U; position < memberIndices.size(); ++position) {
273 if (position != 0U) members <<
",";
274 members << memberIndices[position];
277 << groupId <<
", multiplicity=" << memberIndices.size()
278 <<
", members=[" << members.str() <<
"]");
281 for (std::size_t candidateIndex = 0; candidateIndex < candidates.size();
285 << candidateIndex <<
", bcTag=" << candidate.
bcTag
287 <<
", triggerSector=" << candidate.
sectorId
290 <<
static_cast<unsigned int>(candidate.
stationMask)
291 <<
", wireStationMask="
293 <<
", stripStationMask="
295 <<
", positionStationMask="
296 <<
static_cast<unsigned int>(
298 <<
", eta=" << candidate.
eta <<
", phi="
299 << candidate.
phi <<
", deltaTheta="
301 << candidate.
deltaPhi <<
", preInnerCoincidencePt="
303 <<
", preInnerCoincidenceThreshold="
304 <<
static_cast<unsigned int>(
306 <<
", charge=" <<
static_cast<int>(candidate.
charge)
307 <<
", goodMagneticField="
310 <<
static_cast<unsigned int>(candidate.
wireQuality)
311 <<
", wireQualities=("
317 <<
"), stripQualities=("
335 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_INFO(x,...)
static std::unique_ptr< TgcL0FloatingPtLut > loadAscii(const std::string &calibrationPath, std::string &error)
Load the human-readable calibration payload.
Tag nearby candidates from distinct chamber paths.
void classify(TgcL0CandidateContainer &candidates, OverlapClassificationStatistics &statistics) const
Reconstruct same-BC inter-station segments and transient candidates.
StatusCode build(const StationCoincidenceContainer &coincidences, TgcL0CandidateContainer &candidates, SegmentStatistics &statistics, TgcL0SegmentContainer *validationSegments=nullptr) const
Build station representative points from layer-level TGC hits.
StatusCode build(const HitGroups &hitGroups, StationCoincidenceContainer &coincidences) const
static std::unique_ptr< TgcL0GoodMagMap > loadAscii(const std::string &calibrationPath, std::string &error)
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
static std::string find_calib_directory(const std::string &logical_file_name)
const_pointer_type cptr()
std::map< HitGroupKey, HitContainer > HitGroups
std::vector< StationCoincidence > StationCoincidenceContainer
std::vector< TgcL0Segment > TgcL0SegmentContainer
std::vector< TgcL0Candidate > TgcL0CandidateContainer
Event-local candidate collection.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Event-local candidate used by the TGC simulation tools.
bool inChamberOverlap
True when the candidate has a nearby partner from a different chamber path.
std::int16_t m1StationEta
Offline chamber identifiers retained for overlap diagnostics.
std::uint8_t m2StripQuality
std::uint8_t m1StripQuality
Station-coincidence qualities for strip projections.
std::int16_t m2StationEta
float preInnerCoincidencePt
TGC pT estimate before Inner Coincidence, in GeV.
float deltaPhi
Signed azimuthal-angle residual, in radians.
std::uint16_t m1StationPhi
std::uint8_t m2WireQuality
std::uint8_t positionStationMask
Alias of stationMask retained for explicit validation/debug use.
std::int16_t m3StationEta
std::uint8_t m1WireQuality
Station-coincidence qualities for wire projections.
std::uint8_t preInnerCoincidenceThreshold
Highest pT-threshold index before Inner Coincidence.
std::uint16_t readoutSector
Run-3 detector/readout sector retained for diagnostics.
std::uint16_t bcTag
Bunch-crossing tag.
std::int8_t charge
Charge sign: -1, 0, or +1.
std::uint8_t stripStationMask
Stations used by the strip projection segment.
std::uint8_t m3StripQuality
std::uint8_t m3WireQuality
std::uint8_t stationMask
Stations with a complete two-dimensional wire-and-strip position.
bool goodMagneticField
GoodMag flag.
std::uint16_t m3StationPhi
std::uint16_t sectorId
Trigger Sector identifier.
std::uint16_t m2StationPhi
std::uint8_t wireStationMask
Stations used by the wire projection segment.
float eta
Pseudorapidity at the TGC pivot plane.
std::uint8_t overlapMultiplicity
Number of candidates in the classified overlap group.
float phi
Azimuth at the TGC pivot plane, in radians.
std::uint16_t subdetectorId
Subdetector identifier.
std::uint16_t overlapGroupId
Event-local overlap group. Zero means no classified overlap partner.
float deltaTheta
Signed polar-angle residual, in radians.
std::uint8_t wireQuality
Wire quality.
std::uint8_t thresholdCode
float ptEstimateGeV
Operational pT value, saturated to the downstream 8-bit range.
std::int8_t estimatedCharge
std::size_t nUnknownStation
std::size_t nMappingFailures
std::size_t maxMultiplicity
float maxPivotWireStripDeltaEta
Common-pivot wire-strip association.
std::size_t maxCandidatesPerLocalBin
Old Floating local eta-phi-pivot candidate-bin pruning.
std::size_t maxSegmentCombinationsPerGroup
Validated Floating working-set size per side/Trigger-Sector/BC chain.
float maxPivotWireStripDeltaPhi
std::size_t nM3OnlyPositionCandidates
std::size_t nLocalDuplicateCandidates
std::size_t nStripSegments
std::size_t nDuplicateCandidates
std::size_t nWireSegments
std::size_t nM2OnlyPositionCandidates
std::size_t nM1M2M3Candidates
std::size_t nLimitedCandidates
std::size_t nM1M3Candidates
std::size_t nRejectedPairs
std::size_t nM1OnlyPositionCandidates
std::size_t nDuplicateProjectionSegments
std::size_t nRejectedProjectionCombinations
std::size_t nLimitedProjectionSegments
std::size_t nM1M2Candidates
std::size_t nM2M3Candidates
std::uint8_t observedLayers
std::uint8_t nominalLayers