20#include "Acts/Utilities/RangeXD.hpp"
26 double yCross = (y0 + loc.
location().
z() * tanBeta);
27 return (loc.
minY() < yCross && yCross < loc. maxY());
44 const std::array<double, 2>& chambEdges) {
46 if (chambEdges[0] <= seedEdges[0] && chambEdges[1] >= seedEdges[1]) {
50 else if (chambEdges[0]<= seedEdges[0]) {
51 return (chambEdges[1] - seedEdges[0]) / (seedEdges[1] - seedEdges[0]);
54 else if (chambEdges[1] >= seedEdges[1]) {
55 return (seedEdges[1] - chambEdges[0]) / (seedEdges[1] - seedEdges[0]);
58 else if (seedEdges[0] <= chambEdges[0] && seedEdges[1] >= chambEdges[1]) {
59 return (chambEdges[1] - chambEdges[0]) / (seedEdges[1] - seedEdges[0]);
70 return StatusCode::SUCCESS;
80 ATH_CHECK(writeMaxima.
record(std::make_unique<EtaHoughMaxContainer>()));
93 for (
auto& [station, stationHoughBuckets] :
data.houghSetups) {
95 for (
auto& bucket : stationHoughBuckets) {
99 writeMaxima->push_back(std::make_unique<HoughMaximum>(std::move(
max)));
105 return (*a->parentBucket()) < (*b->parentBucket());
107 return StatusCode::SUCCESS;
114 ATH_MSG_DEBUG(
"Load " << spacePoints.size() <<
" space point buckets");
119 std::vector<HoughSetupForBucket>& buckets =
data.houghSetups[bucket->front()->msSector()];
121 const Amg::Transform3D globToLoc{hs.bucket->msSector()->globalToLocalTrans(gctx)};
122 Amg::Vector3D leftSide = globToLoc.translation() - (hs.bucket->coveredMin() * Amg::Vector3D::UnitY());
123 Amg::Vector3D rightSide = globToLoc.translation() - (hs.bucket->coveredMax() * Amg::Vector3D::UnitY());
126 double zmin{1.e9}, zmax{-1.e9};
127 for (
const std::shared_ptr<MuonR4::SpacePoint> &
sp : *bucket) {
128 zmin = std::min(zmin,
sp->localPosition().z());
129 zmax = std::max(zmax,
sp->localPosition().z());
131 const double z = 0.5*(zmin + zmax);
136 hs.searchWindowTanAngle = {tanThetaLeft, tanThetaRight};
141 for (
const std::shared_ptr<MuonR4::SpacePoint> & hit : *bucket){
143 double y0l = hit->localPosition().y() - hit->localPosition().z() * tanThetaLeft;
144 double y0r = hit->localPosition().y() - hit->localPosition().z() * tanThetaRight;
149 hs.searchWindowIntercept = {
ymin,
ymax};
153 switch (hit->
type()){
156 return dc->status() == Muon::MdtDriftCircleStatus::MdtStatusDriftTime;
171 HoughPlaneConfig cfg;
178 data.houghPlane = std::make_unique<HoughPlane>(cfg);
179 data.peakFinder = std::make_unique<ActsPeakFinderForMuon>(peakFinderCfg);
185 int expectedPrecisionChambers{0}, seenPrecisionChambers{0};
186 bool hasTrig =
false;
188 std::unordered_set<const MuonGMR4::MuonReadoutElement*> seenChambers{};
189 std::set<std::pair<int,int>> seenLayers;
192 std::array<double, 2> tubeExtend{halfX, -halfX};
194 auto addSeenHit = [&tubeExtend, &seenLayers, &seenChambers](
const SpacePoint&
sp,
196 const double sensorL,
197 const int mL,
const int layer){
198 seenLayers.emplace(mL, layer);
199 seenChambers.insert(
re);
200 tubeExtend[0] = std::min(tubeExtend[0],
sp.localPosition().x() - sensorL);
201 tubeExtend[1] = std::max(tubeExtend[1],
sp.localPosition().x() + sensorL);
203 for (
const SpacePoint* SP : maximum.hitIdentifiers){
204 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
" Maximum has associated hit in "
211 addSeenHit(*SP,
re, 0.5*
re->activeTubeLength(dc->measurementHash()),
212 re->multilayer(), dc->tubeLayer());
216 addSeenHit(*SP,
re, 0.5*
re->stripLayer(clust->measurementHash()).design().stripLength(clust->channelNumber()),
217 re->multilayer(), clust->gasGap());
221 addSeenHit(*SP,
re, 0.5*
re->stripLayer(clust->measurementHash()).design().stripLength(clust->channelNumber()),
222 re->multilayer(), clust->gasGap());
232 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
" maximum does not cross "
233 <<
m_idHelperSvc->toStringDetEl(muonChamber.readoutEle()->identify()));
237 <<
m_idHelperSvc->toStringDetEl(muonChamber.readoutEle()->identify())<<
", "
238 <<(*muonChamber.bounds())<<
", @: "<<
Amg::toString(muonChamber.location()));
243 const bool hasHit = seenChambers.count(muonChamber.readoutEle());
249 ++seenPrecisionChambers;
254 }
else if (precTech) {
257 const double lowL = muonChamber.width(maximum.y + muonChamber.location().z() * maximum.x);
258 const std::array<double, 2> chambEdges{muonChamber.location().x() - lowL,
259 muonChamber.location().x() + lowL};
262 if (coverage < 0.95){
263 ATH_MSG_VERBOSE(__func__<<
"() - "<<__LINE__<<
" Reject chamber due to partial coverage: "<<coverage
264 <<
", chamb extend: "<<chambEdges[0]<<
"-"<<chambEdges[1]
265 <<
", tube extend: "<<tubeExtend[0]<<
"-"<<tubeExtend[1]
266 <<
", "<<(*muonChamber.readoutEle()->msSector()->bounds()));
272 ++expectedPrecisionChambers;
276 int minLayers = seenLayers.size() / 2 + 1;
278 int minSeenPrecisionChambers = (expectedPrecisionChambers > 1) + 1;
282 minSeenPrecisionChambers = 1;
285 ", seen prec: "<<seenPrecisionChambers<<
", required: "<<minSeenPrecisionChambers
286 <<
" -- layers: "<<seenLayers.size()<<
", required: "<<
minLayers);
287 return seenPrecisionChambers >= minSeenPrecisionChambers && (int)seenLayers.size() >=
minLayers;
296 double chamberCenter = 0.5 * (bucket.searchWindowIntercept.first +
297 bucket.searchWindowIntercept.second);
304 searchStart = std::min(searchStart, bucket.searchWindowIntercept.first -
306 searchEnd = std::max(searchEnd, bucket.searchWindowIntercept.second +
309 double tanThetaMean = 0.5 * (bucket.searchWindowTanAngle.first +
310 bucket.searchWindowTanAngle.second);
313 searchStartTanTheta = std::min(searchStartTanTheta, bucket.searchWindowTanAngle.first -
315 searchEndTanTheta = std::max(searchEndTanTheta, bucket.searchWindowTanAngle.second +
318 data.currAxisRanges = Acts::HoughTransformUtils::HoughAxisRanges{
319 searchStartTanTheta, searchEndTanTheta, searchStart, searchEnd};
321 data.houghPlane->reset();
322 for (
const SpacePointBucket::value_type& hit : *(bucket.bucket)) {
325 auto maxima =
data.peakFinder->findPeaks(*(
data.houghPlane),
data.currAxisRanges);
328 "#eta Hough accumulator");
330 if (maxima.empty()) {
332 <<
":\n Mean tanBeta was "<<tanThetaMean
333 <<
" and my intercept "<<chamberCenter
334 <<
", with hits in the bucket in "<< bucket.bucket->
coveredMin()
336 <<
". The bucket found a search range of ("
337 <<bucket.searchWindowTanAngle.first<<
" - "
338 <<bucket.searchWindowTanAngle.second<<
") and ("
339 <<bucket.searchWindowIntercept.first<<
" - "
340 <<bucket.searchWindowIntercept.second
341 <<
") , and my final search range is ["
342 <<searchStartTanTheta<<
" - "<<searchEndTanTheta
343 <<
"] and ["<<searchStart<<
" - "<<searchEnd
351 std::set<HoughHitType> seenHits;
354 for (
const auto&
max : maxima) {
357 unsigned int nPrec{0};
358 auto toBins = [&
data](
double x,
double y){
359 return std::make_pair(
360 Acts::HoughTransformUtils::binIndex(
data.currAxisRanges.xMin,
data.currAxisRanges.xMax,
data.houghPlane->nBinsX(),
x),
361 Acts::HoughTransformUtils::binIndex(
data.currAxisRanges.yMin,
data.currAxisRanges.yMax,
data.houghPlane->nBinsY(),
y)
364 auto accumulatorBins = toBins(
max.x,
max.y);
365 for (
const HoughHitType& hit :
data.houghPlane->hitIds(accumulatorBins.first, accumulatorBins.second)) {
366 auto res = seenHits.emplace(hit);
377 std::vector<HoughHitType> hitList{
max.hitIdentifiers.begin(),
max.hitIdentifiers.end()};
383 const HoughMaximum& houghMax{
max.x,
max.y, 1. *hitList.size(), std::move(hitList), bucket.bucket};
389 chamber.maxY(), chamber.maxZ(), kGray+2));
390 const Identifier detId{chamber.readoutEle()->identify()};
392 std::string chLabel = std::format(
"{:}{:1d}{:}{:2d}",
m_idHelperSvc->stationNameString(detId),
394 switch (chamber.readoutEle()->detectorType()) {
396 chLabel += std::format(
"M{:1d}",
m_idHelperSvc->mdtIdHelper().multilayer(detId));
403 primitives.push_back(
MuonValR4::drawLabel(std::format(
"Missed seed - score {}, layer score {}, comprising {} measurements ",
data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),
data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size()),0.05,0.03,12));
405 primitivesForAcc.push_back(
MuonValR4::drawLabel(std::format(
"Missed seed - score {}, layer score {}, comprising {} measurements ",
data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),
data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size()),0.05,0.03,12));
407 "MissedAccumulator", std::move(primitivesForAcc));
408 m_visionTool->visualizeSeed(ctx, seed,
"Missed seed",std::move(primitives));
414 size_t nHits = hitList.size();
419 std::ranges::stable_sort(hitList, sorter);
429 primitives.push_back(
MuonValR4::drawBox(chamber.minY(), chamber.minZ(), chamber.maxY(), chamber.maxZ(), kGray+2));
431 primitives.push_back(
MuonValR4::drawLabel(std::format(
"score {}, layer score {}, comprising {} measurements. wx = {:.2f}, wy = {:.1f} ",
data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),
data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size(),
max.wx,
max.wy),0.05,0.03,12));
432 primitivesForAcc.push_back(
MuonValR4::drawLabel(std::format(
"score {}, layer score {}, comprising {} measurements. wx = {:.2f}, wy = {:.1f} ",
data.houghPlane->nHits(accumulatorBins.first, accumulatorBins.second),
data.houghPlane->nLayers(accumulatorBins.first, accumulatorBins.second),hitList.size(),
max.wx /
m_targetResoTanTheta,
max.wy /
m_targetResoIntercept),0.05,0.03,12));
434 m_visionTool->visualizeAccumulator(ctx, *
data.houghPlane,
data.currAxisRanges, {max},
"#eta Hough accumulator", std::move(primitivesForAcc));
435 m_visionTool->visualizeSeed(ctx, seed,
"#eta-HoughSeed", std::move(primitives));
441 using namespace std::placeholders;
456 const unsigned precisionLayerIndex = (dc->readoutElement()->multilayer() * 10 + dc->tubeLayer());
471 const double tanBeta,
472 const double interceptY)
const {
473 const Amg::Vector3D maxPos = interceptY * Amg::Vector3D::UnitY();
474 const Amg::Vector3D maxDir = Acts::makeDirectionFromAxisTangents(0., tanBeta);
476 for (
const SpacePointBucket::value_type& hit : *bucket.bucket) {
477 if (hit->measuresEta()){
483 const double distAlongStrip = std::abs(dir.dot(SeedingAux::extrapolateToPlane(maxPos,maxDir, *hit) - pos));
484 const double stripL = std::sqrt(hit->covariance()[Acts::toUnderlying(AxisDefs::etaCov)]);
486 hitList.push_back(hit.get());
const boost::regex re(r_e)
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
char data[hepevt_bytes_allocation_ATLAS]
std::pair< std::vector< unsigned int >, bool > res
static const uint32_t nHits
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
std::string identString() const
Returns a string encoding the chamber index & the sector of the MS sector.
double halfXLong() const
Long-extend of the chamber in the x-direction at positive Y.
Data class to represent an eta maximum in hough space.
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
: The muon space point bucket represents a collection of points that will bre processed together in t...
const MuonGMR4::SpectrometerSector * msSector() const
returns th associated muonChamber
double coveredMin() const
lower interval value covered by the bucket
double coveredMax() const
upper interval value covered by the bucket
MuonGMR4::SpectrometerSector::chamberLocation chamberLocation
const std::vector< chamberLocation > & chamberLocations() const
returns the list of all tracking chambers in the bucket for fast navigation
The SpacePointPerLayerSorter sort two given space points by their layer Identifier.
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
bool measuresEta() const
: Does the space point contain an eta measurement
unsigned nEtaInstanceCounts() const
How many space points have been built in total with the same eta prd.
const Identifier & identify() const
: Identifier of the primary measurement
xAOD::UncalibMeasType type() const
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual xAOD::UncalibMeasType type() const =0
Returns the type of the measurement type as a simple enumeration.
DetectorType
Simple enum to Identify the Type of the ACTS sub detector.
@ Mm
Maybe not needed in the migration.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
double houghWidthStrip(double tanBeta, const MuonR4::HoughHitType &strip, double targetReso)
Uncertainty parametrisation for strip measurements.
double houghParamMdtRight(double tanBeta, const MuonR4::HoughHitType &dc)
right-side straight line parametrisation for drift circles
double houghParamStrip(double tanBeta, const MuonR4::HoughHitType &strip)
straight line parametrisation for strip detector measurements
double houghWidthMdt(double tanBeta, const MuonR4::HoughHitType &dc, double targetReso)
uncertainty parametrisation for drift circles
double houghParamMdtLeft(double tanBeta, const MuonR4::HoughHitType &dc)
left-side straight line parametrisation for drift circles
This header ties the generic definitions in this package.
double proximity(const SpacePoint *dc, double y0, double tanBeta)
constexpr double chamberCoverage(const std::array< double, 2 > &seedEdges, const std::array< double, 2 > &chambEdges)
Calculates how much of the unkknown coordinate along the tube range is covered by the chamber of inte...
bool passesThrough(const SpacePointBucket::chamberLocation &loc, double y0, double tanBeta)
constexpr unsigned minLayers
HoughEventData_impl< ActsPeakFinderForMuon, ActsPeakFinderForMuonCfg > HoughEventData
Acts::HoughTransformUtils::PeakFinders::IslandsAroundMaxConfig ActsPeakFinderForMuonCfg
const SpacePoint * HoughHitType
DataVector< SpacePointBucket > SpacePointContainer
Abrivation of the space point container type.
std::unique_ptr< TLatex > drawLabel(const std::string &text, const double xPos, const double yPos, const unsigned int fontSize=18)
Create a TLatex label,.
std::unique_ptr< TBox > drawBox(const Amg::Vector3D &boxCenter, const double boxWidth, const double boxHeight, const int color=kGreen+2, const int fillStyle=hollowFilling, const int view=objViewEta)
Creates a box for drawing, e.g strip measurements.
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
void stable_sort(DataModel_detail::iterator< DVL > beg, DataModel_detail::iterator< DVL > end)
Specialization of stable_sort for DataVector/List.
MdtDriftCircle_v1 MdtDriftCircle
const MuonGMR4::MuonReadoutElement * muonReadoutElement(const UncalibratedMeasurement *meas)
Returns the associated readout element to the measurement.
sTgcMeasurement_v1 sTgcMeasurement
double minY() const
Returns the minimum y covered by the chamber location.
const Amg::Vector3D & location() const
Returns the location.