 |
ATLAS Offline Software
|
Go to the documentation of this file.
10 #include <Acts/Utilities/Enumerate.hpp>
11 #include <Acts/Definitions/Units.hpp>
12 #include <Acts/Utilities/UnitVectors.hpp>
18 using namespace Acts::UnitLiterals;
22 constexpr
auto covIdx = Acts::toUnderlying(AxisDefs::etaCov);
53 ostr<<
"two circle solution with ";
54 ostr<<
"theta: "<<(
theta / 1._degree) <<
" pm "<<(dTheta / 1._degree)<<
", ";
55 ostr<<
"y0: "<<y0<<
" pm "<<dY0;
62 MdtSegmentSeedGenerator::~MdtSegmentSeedGenerator() =
default;
63 MdtSegmentSeedGenerator::MdtSegmentSeedGenerator(
const std::string&
name,
65 const Config& configuration):
68 m_segmentSeed{segmentSeed} {
70 if (m_hitLayers.mdtHits().empty())
return;
72 if (std::ranges::any_of(m_hitLayers.mdtHits(), [
this](
const HitVec&
vec){
73 return vec.size() > m_cfg.busyLayerLimit;
75 m_cfg.startWithPattern =
false;
78 m_upperLayer = m_hitLayers.mdtHits().size()-1;
81 while (m_lowerLayer < m_upperLayer){
82 const HitVec& lower{m_hitLayers.mdtHits()[m_lowerLayer]};
83 if (lower.size() > m_cfg.busyLayerLimit || !
firstGoodHit(lower, m_lowerHitIndex)) {
91 while (m_lowerLayer < m_upperLayer){
92 const HitVec&
upper{m_hitLayers.mdtHits()[m_upperLayer]};
102 std::stringstream sstr{};
103 for (
const auto [layCount,
layer] : Acts::enumerate(m_hitLayers.mdtHits())) {
104 sstr<<
"Mdt-hits in layer "<<layCount<<
": "<<
layer.size()<<std::endl;
106 sstr<<
" **** "<<(*hit)<<std::endl;
109 for (
const auto [layCount,
layer] : Acts::enumerate(m_hitLayers.stripHits())) {
110 sstr<<
"Hits in layer "<<layCount<<
": "<<
layer.size()<<std::endl;
112 sstr<<
" **** "<<(*hit)<<std::endl;
115 ATH_MSG_VERBOSE(
"SeedGenerator - sorting of hits done. Mdt layers: "<<m_hitLayers.mdtHits().size()
116 <<
", strip layers: "<<m_hitLayers.stripHits().size()<<std::endl<<sstr.str()<<std::endl<<std::endl);
189 std::optional<MdtSegmentSeedGenerator::DriftCircleSeed>
191 std::optional<DriftCircleSeed>
found = std::nullopt;
194 found = std::make_optional<DriftCircleSeed>();
203 return hit->type() == xAOD::UncalibMeasType::MdtDriftCircleType;
220 <<
" ("<<
upper.size()<<
") - ambiguity "
234 Line_t::ParamVector
pars{};
235 pars[Acts::toUnderlying(ParamDefs::y0)] = y0;
252 <<(solution.theta / 1._degree)
268 std::optional<MdtSegmentSeedGenerator::DriftCircleSeed>
276 THROW_EXCEPTION(
"Bad hit detected, despite that should have been captured upstream "
282 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Attempt to construct seed from "<<idHelperSvc->toString(bottomHit->
identify())
283 <<
" && top tube "<<idHelperSvc->toString(topHit->
identify()));
286 static_cast<TangentLine&
>(solCandidate) = LineSeeder_t::constructTangentLine(*topHit, *bottomHit, ambi);
289 solCandidate.theta = flipedDir.theta();
295 std::unique_ptr<CalibratedSpacePoint> calibBottom{}, calibTop{};
304 static_cast<TangentLine&
>(solCandidate) = LineSeeder_t::constructTangentLine(*calibTop, *calibBottom, ambi);
306 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Recalibrated segment seed is invalid");
315 const double deltaY = std::abs(seen.y0 - solCandidate.y0);
316 const double limitY = std::hypot(seen.dY0, solCandidate.dY0);
317 const double dTheta = std::abs(seen.theta - solCandidate.theta);
318 const double limitTh = std::hypot(seen.dTheta, solCandidate.dTheta);
321 <<
std::format(
" delta theta: {:.2f} {:} {:.2f}", dTheta, dTheta < limitTh ?
'<' :
'>', limitTh) );
322 return deltaY < limitY && dTheta < limitTh;;
324 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Reject due to similarity");
331 const auto finalSeedPars =
constructLinePars(solCandidate.theta,solCandidate.y0);
332 m_line.updateParameters(finalSeedPars);
335 ATH_MSG_VERBOSE( __func__<<
"() "<<__LINE__<<
": "<<hitsInLayer.size()<<
" hits in layer "<<(layerNr +1));
336 bool hadGoodHit{
false};
338 using namespace Acts::detail::LineHelper;
341 const double pull = Acts::abs(
distance - testMe->driftRadius()) / std::sqrt(testMe->covariance()[
covIdx]);
343 const auto*
re =
static_cast<const xAOD::MdtDriftCircle*
>(testMe->primaryMeasurement())->readoutElement();
345 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Test hit "<<idHelperSvc->toString(testMe->identify())
349 solCandidate.seedHits.emplace_back(testMe);
350 candidateSeed.nMdt +=
isGoodDC(*testMe);
352 else if (hadGoodHit) {
361 if (1.*candidateSeed.nMdt < hitCut) {
362 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Too few hits associated "<<candidateSeed.nMdt<<
", expect: "<<hitCut<<
" hits.");
367 solCandidate.solutionSigns = SeedingAux::strawSigns(
m_line, solCandidate.seedHits);
368 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Circle solutions for seed "
369 <<idHelperSvc->toStringChamber(bottomHit->
identify())<<
" - "<<solCandidate);
373 unsigned int nOverlap{0};
374 std::vector<int> corridor = SeedingAux::strawSigns(
m_line, accepted.
seedHits);
375 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Test seed against accepted "<<accepted<<
", updated signs: "<<corridor);
377 for (
unsigned int l = 0;
l < accepted.
seedHits.size(); ++
l){
382 if (nOverlap == corridor.size() && accepted.
seedHits.size() >= solCandidate.seedHits.size()) {
383 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Same set of hits collected within the same corridor");
390 candidateSeed.parameters[Acts::toUnderlying(
p)] = finalSeedPars[Acts::toUnderlying(
p)];
396 if (hit == bottomHit && calibBottom) {
397 candidateSeed.measurements.emplace_back(std::move(calibBottom));
401 else if (hit == topHit && calibTop) {
402 candidateSeed.measurements.emplace_back(std::move(calibTop));
417 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": In event "<<ctx.eventID().event_number()<<
" found new seed solution "<<
toString(candidateSeed.parameters));
421 HoughHitType bestHitLoc0{
nullptr}, bestHitLoc1{
nullptr};
424 const double pull = std::sqrt(SeedingAux::chi2Term(
m_line, *testMe));
425 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
": Test hit "<<idHelperSvc->toString(testMe->identify())
427 if (testMe->measuresLoc0() &&
pull < bestPullLoc0) {
429 bestHitLoc0 = testMe;
431 if (testMe->measuresLoc1() &&
pull < bestPullLoc1) {
433 bestHitLoc1 = testMe;
440 if (bestHitLoc1 && bestHitLoc1 != bestHitLoc0) {
446 return candidateSeed;
const SpacePointBucket * parentBucket() const
Returns the bucket out of which the seed was formed.
const MuonGMR4::SpectrometerSector * msSector() const
const HitLayVec & stripHits() const
Returns the sorted strip hits.
bool startWithPattern
Try at the first time the pattern seed as candidate.
Amg::Vector3D localPosition() const
Returns the position of the seed in the sector frame.
Scalar phi() const
phi method
LineSeeder_t::TangentAmbi TangentAmbi
const Amg::Vector3D & planeNormal() const
Returns the vector pointing out of the measurement plane.
std::vector< HitVec > HitLayVec
std::optional< DriftCircleSeed > nextSeed(const EventContext &ctx)
returns the next seed in the row
Scalar theta() const
theta method
std::vector< ALFA_RawData_p1 > t0
Helper to simultaneously calculate sin and cos of the same angle.
MdtDriftCircleStatus
Enum to represent the 'status' of Mdt measurements e.g.
std::optional< DriftCircleSeed > buildSeed(const EventContext &ctx, const HoughHitType &topHit, const HoughHitType &bottomHit, const TangentAmbi ambi)
Tries to build the seed from the two hits.
std::vector< size_t > vec
virtual CalibSpacePointPtr calibrate(const EventContext &ctx, const SpacePoint *spacePoint, const Amg::Vector3D &seedPosInChamb, const Amg::Vector3D &seedDirInChamb, const double timeDelay) const =0
Calibrates a single space point.
#define ATH_MSG_VERBOSE(x)
double hitPullCut
Upper cut on the hit chi2 w.r.t.
@ MdtStatusDriftTime
The tube produced a vaild measurement.
unsigned int busyLayerLimit
How many drift circles may be on a layer to be used for seeding.
const MuonR4::ISpacePointCalibrator * calibrator
Pointer to the space point calibrator.
SpacePointPerLayerSplitter::HitLayVec HitLayerVec
double nMdtLayHitCut
Hit cut based on the fraction of collected tube layers.
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
HitVec seedHits
Used hits in the seed.
double tanAlpha() const
Returns the angle from the phi extension.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
bool tightenHitCut
Once a seed with even more than initially required hits is found, reject all following seeds with les...
unsigned int firstLayerFrom2ndMl() const
Returns the layer index with hits from the second multilayer
virtual xAOD::UncalibMeasType type() const =0
Returns the type of the measurement type as a simple enumeration.
Configuration switches of the module
SpacePointPerLayerSplitter m_hitLayers
SpacePointPerLayerSplitter::HitVec HitVec
unsigned int m_nGenSeeds
Counter on how many seeds have been generated.
std::vector< int > solutionSigns
Vector of radial signs of the valid hits.
double interceptY() const
Returns the intercept coordinate of the eta transform.
const std::vector< HitType > & getHitsInMax() const
Returns the list of assigned hits.
std::size_t m_upperHitIndex
Explicit hit to pick in the selected top layer.
LineSeeder_t::TwoCircleTangentPars TangentLine
Class to provide easy MsgStream access and capabilities.
std::size_t m_upperLayer
Considered layer to pick the top drift circle from.
std::string toString(const Parameters &pars)
Dumps the parameters into a string with labels in front of each number.
static constexpr std::array< TangentAmbi, 4 > s_signCombos
const SpacePointBucket * parentBucket
Pointer to the parent bucket.
const SpacePoint * HoughHitType
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
bool isGoodDC(const SpacePoint &dc)
Returns whether the Mdt measurement has a valid space point.
void print(char *figname, TCanvas *c1)
bool recalibSeedCircles
Recalibrate the seed drift circles from the initial estimate
std::array< double, 2 > thetaRange
Cut on the theta angle.
std::size_t m_lowerHitIndex
Explicit hit to pick in the selected bottom layer.
Cache of all solutions seen thus far.
Muon::MdtDriftCircleStatus dcStatus(const SpacePoint &dc)
bool firstGoodHit(const HitVec &hits, std::size_t &hitIdx)
Find the first good hit in a layer.
const Muon::IMuonIdHelperSvc * idHelperSvc() const
Returns the IdHelpeSvc.
const HitLayVec & mdtHits() const
Returns the sorted Mdt hits.
bool overlapCorridor
Check whether a new seed candidate shares the same left-right solution with already accepted ones Rej...
Helper struct from a generated Mdt seed.
Line_t m_line
Line to instantiate the seed parameters.
double tanBeta() const
Returns the angular coordinate of the eta transform.
double interceptX() const
Returns the intercept from the phi extension.
Eigen::Matrix< double, 3, 1 > Vector3D
#define THROW_EXCEPTION(MESSAGE)
void moveToNextCandidate()
Prepares the generator to generate the seed from the next pair of drift circles.
bool moveToNextHit(const HitVec &hits, std::size_t &hitIdx)
Move to the next space point with valid drift radius.
std::vector< SeedSolution > m_seenSolutions
Vector caching equivalent solutions to avoid double seeding.
bool isValidLine(const TangentLine &solution) const
Checks whether the intercept and the angle are witihn the allowed ranges.
Amg::Vector3D localDirection() const
Returns the direction of the seed in the sector frame.
const boost::regex re(r_e)
Representation of a segment seed (a fully processed hough maximum) produced by the hough transform.
Interface for Helper service that creates muon Identifiers and can be used to print Identifiers.
const Parameters & parameters() const
Returns the parameter array.
double signedDistance(const Amg::Vector3D &posA, const Amg::Vector3D &dirA, const Amg::Vector3D &posB, const Amg::Vector3D &dirB)
Calculates the signed distance between two lines in 3D space.
@ MdtStatusUnDefined
Undefined.
Eigen::AngleAxisd AngleAxis3D
https://gitlab.cern.ch/atlas/athena/-/blob/master/MuonSpectrometer/MuonReconstruction/MuonRecEvent/Mu...
const SegmentSeed * m_segmentSeed
std::size_t m_signComboIndex
Index of the left-right ambiguity between the circles.
SpacePointPerLayerSplitter::HitVec HitVec
unsigned int nMdtHitCut
How many drift circle hits needs the seed to contain in order to be valid.
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
std::size_t m_lowerLayer
Considered layer to pick the bottom drift circle from.
Line_t::ParamVector constructLinePars(const double theta, const double y0) const
Construct the 3D-Line parameters from the estimates theta & y0 from the tangent line.
unsigned int numGenerated() const
Returns how many seeds have been generated.
std::array< double, 2 > interceptRange
Cut on the intercept range.
const Identifier & identify() const
: Identifier of the primary measurement
const Amg::Vector3D & sensorDirection() const