12#include "Acts/Surfaces/StrawSurface.hpp"
14#include "Acts/Geometry/TrackingGeometry.hpp"
15#include "Acts/Surfaces/PlaneSurface.hpp"
16#include "Acts/Definitions/Units.hpp"
20 using namespace Acts::UnitLiterals;
30 return StatusCode::SUCCESS;
35 DataShip& ship)
const {
37 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(ctx);
40 xAOD::MuonSegment* convertedSeg = ship.segmentContainer->push_back(std::make_unique<xAOD::MuonSegment>());
44 convertedSeg->
setPosition(pos.x(), pos.y(), pos.z());
55 if (ship.dec_localSegPars) {
57 SegPars_t& localPars{ship.dec_localSegPars(*convertedSeg)};
63 localPars[Acts::toUnderlying(x0)] = locPos.x();
64 localPars[Acts::toUnderlying(y0)] = locPos.y();
65 localPars[Acts::toUnderlying(
theta)] = locDir.theta();
66 localPars[Acts::toUnderlying(
phi)] = locDir.phi();
67 localPars[Acts::toUnderlying(
t0)] = inSegment.
segementT0();
70 if (ship.dec_localSegCov) {
71 using SegCov_t =
xAOD::PosAccessor<Acts::sumUpToN(Acts::toUnderlying(SegmentFit::ParamDefs::nPars))>::element_type;
72 SegCov_t& localCov{ship.dec_localSegCov(*convertedSeg)};
73 constexpr std::size_t n = Acts::toUnderlying(SegmentFit::ParamDefs::nPars);
74 for (std::size_t p = 1; p < n; ++p) {
75 for (std::size_t p1 = 0 ; p1 <=p;++p1) {
76 localCov[Acts::vecIdxFromSymMat<n>(p,p1)] = inSegment.
covariance()(p, p1);
81 if (
linkMeasurements(tgContext, inSegment, *convertedSeg, ship) != StatusCode::SUCCESS) {
83 ship.segmentContainer->pop_back();
93 DataShip& ship)
const {
94 if (!ship.dec_prdLinks || !ship.dec_prdStates || !ship.prdCombContainer.hasHandle()) {
95 ATH_MSG_DEBUG(
"Decorators for the prd links and states are not initialized");
96 return StatusCode::SUCCESS;
101 std::vector< std::tuple<const xAOD::MuonMeasurement*, State, std::size_t>> combineMap{};
102 std::vector< std::tuple<const xAOD::UncalibratedMeasurement*, State, std::size_t>> linkMap{};
104 using PrdLinkVec_t = std::vector<ElementLink<xAOD::UncalibratedMeasurementContainer>>;
106 std::vector<char>& linkStates = ship.dec_prdStates(targetSegment);
114 auto cmbMeas = ship.prdCombContainer->push_back(std::make_unique<xAOD::CombinedMuonStrip>());
116 cmbMeas->setPrimaryStrip(m1);
117 cmbMeas->setSecondaryStrip(m2);
121 const Identifier id1{m1->identify()}, id2{m2->identify()};
134 for (
const auto [segIdx, meas] : Acts::enumerate(inSegment.
measurements())) {
137 if (!ship.beamSpotMeasCreator.ok()) {
141 if (!ship.beamSpot) {
142 if (!ship.beamSpotMeasCreator.ok()) {
144 return StatusCode::FAILURE;
148 meas->localPosition();
152 covariance(0,0) = meas->covariance()[Acts::toUnderlying(CovIdx::etaCov)];
153 covariance(1,1) = meas->covariance()[Acts::toUnderlying(CovIdx::phiCov)];
156 std::make_shared<Acts::LineBounds>(std::sqrt(covariance(0,0)), 20._m));
158 ship.beamSpot = ship.beamSpotMeasCreator->newMeasurement<2>(surf, ProjectorType::e2DimNoTime, covariance);
159 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Created beamspot measurement "<<(*meas)<<
", "
160 <<surf->toString(tgContext));
162 linkMap.emplace_back(ship.beamSpot, meas->fitState(), segIdx);
165 switch (
sp->type()) {
168 case MdtDriftCircleType:
169 case MMClusterType: {
170 linkMap.emplace_back(
sp->primaryMeasurement(), meas->fitState(), segIdx);
174 case sTgcStripType: {
175 if (
sp->primaryMeasurement() &&
sp->secondaryMeasurement()) {
176 if (
sp->primaryMeasurement() !=
sp->secondaryMeasurement()) {
177 linkMap.emplace_back(combine(
sp->primaryMeasurement(),
178 sp->secondaryMeasurement()),
179 meas->fitState(), segIdx);
181 linkMap.emplace_back(
sp->primaryMeasurement(), meas->fitState(), segIdx);
186 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Append for later combination "<<(*meas));
187 combineMap.emplace_back(
sp->primaryMeasurement(), meas->fitState(), segIdx);
196 for (std::size_t cmbIdx = 0; cmbIdx < combineMap.size(); ++cmbIdx){
198 const State s1{std::get<1>(combineMap[cmbIdx])};
199 const std::size_t segIdx1{std::get<2>(combineMap[cmbIdx])};
200 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Find another measurement to combine with "
202 if (cmbIdx +1 < combineMap.size()) {
204 const State s2{std::get<1>(combineMap[cmbIdx+1])};
206 <<
" is a good candidate");
209 if (m1->type() == m2->type() && m1->identifierHash() == m2->identifierHash() &&
210 m1->layerHash() == m2->layerHash() && s1 == s2) {
213 if (m1->measuresPhi()) {
214 linkMap.emplace_back(combine(m2, m1), s2, segIdx1);
216 linkMap.emplace_back(combine(m1, m2), s1, segIdx1);
223 linkMap.emplace_back(m1, s1, segIdx1);
226 std::ranges::sort(linkMap, [](
const auto&
a,
const auto& b){
227 return std::get<2>(
a) < std::get<2>(b);
230 for (
const auto& [prd, state, segIdx]: linkMap) {
233 linkStates.emplace_back(Acts::toUnderlying(state));
235 return StatusCode::SUCCESS;
242 Counter hits{}, outliers{}, holes{};
244 std::unordered_set<Identifier> crossedSurfaces{};
247 const Acts::Surface* startSurface{}, *lastSurface{};
250 ATH_MSG_DEBUG(__func__<<
"() "<<__LINE__<<
" - Loop over "<<nMeas<<
" measurements.");
251 for (std::size_t m = 0 ; m < nMeas; ++m) {
256 <<
" - Skip auxiliary measurement in segment summary");
261 Counter& increment = {isOutlier ? outliers: hits};
266 increment.
triggerPhi += (muonMeas->measuresPhi() ||
268 muonMeas->numDimensions() == 2);
271 (muonMeas->numDimensions() == 0 ) ||
273 (muonMeas->numDimensions() == 1 && !muonMeas->measuresPhi() ) ||
275 (muonMeas->numDimensions() == 2));
281 if (!muonMeas->measuresPhi() &&
re->nPhiStrips()) {
283 }
else if (muonMeas->measuresPhi()) {
289 if (!muonMeas->measuresPhi() &&
re->numStrips(muonMeas->layerHash())) {
291 }
else if (muonMeas->measuresPhi() &&
re->numWireGangs(muonMeas->layerHash())) {
312 muonMeas->identify());
314 assert(volume !=
nullptr);
317 }
else if (m +1 == nMeas) {
323 const Acts::GeometryContext tgContext =
m_ctxProvider.getGeometryContext(ctx);
324 std::shared_ptr<const Acts::Surface> startSurfPtr = startSurface->getSharedPtr();
325 auto atSurface = startSurface->intersect(tgContext, segment.
position(), segment.
direction(),
326 Acts::BoundaryTolerance::Infinite()).closest();
328 const auto locPos = startSurface->globalToLocal(tgContext, atSurface.position(), segment.
direction());
331 <<
" is not on surface "<<startSurface->geometryId());
334 if (!startSurface->insideBounds(*locPos)) {
336 lowestTrackingVolume(tgContext, atSurface.position()));
338 <<
" is outside surface: "<<startSurface->geometryId()<<
", "<<startSurface->bounds()<<
". "
339 <<
" Switch to volume "<<volume->geometryId()<<
", bounds: "<<volume->volumeBounds());
341 if (volume->isAlignable()) {
343 atSurface = startSurfPtr->intersect(tgContext, segment.
position(), segment.
direction(),
344 Acts::BoundaryTolerance::Infinite()).closest();
346 startSurfPtr = Acts::Surface::makeShared<Acts::PlaneSurface>(startSurfPtr->localToGlobalTransform(tgContext));
349 auto startPars = Acts::BoundTrackParameters::create(tgContext, startSurfPtr,
351 segment.
direction(), 1./ 5._TeV, std::nullopt,
352 Acts::ParticleHypothesis::muon());
353 if (startPars.ok()) {
354 findHoles(ctx, *startPars, lastSurface, crossedSurfaces, holes);
356 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" - Start parameters not defined.");
359 segment.
setNHits(hits.precision, hits.triggerPhi, hits.triggerEta);
360 segment.
setNOutliers(outliers.precision, outliers.triggerPhi, outliers.triggerEta);
361 segment.
setNHoles(holes.precision, holes.triggerPhi, holes.triggerEta);
362 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" Updated summary: "<<hits);
365 const Acts::BoundTrackParameters& startPars,
366 const Acts::Surface* target,
367 const std::unordered_set<Identifier>& layersWithHits,
374 propOpts.recordPassive =
false;
375 propOpts.recordSensitive =
true;
379 if (!propResult.ok()) {
384 for (Acts::BoundTrackParameters& record : (*propResult)) {
386 assert(placement !=
nullptr);
390 if (layersWithHits.count(placement->identify())) {
397 if(std::ranges::none_of(layersWithHits,[&](
const Identifier& recorded){
398 return m_idHelperSvc->chamberIndex(recorded) == detEl->chamberIndex() &&
402 <<
m_idHelperSvc->toStringGasGap(placement->identify())<<
" is not in the same sector");
405 switch (placement->detectorType()) {
408 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Precision hole detected "
415 <<
m_idHelperSvc->toStringGasGap(placement->identify())<<
".");
421 holeCounter.
triggerEta += (
re->numWireGangs(placement->hash())>0);
422 holeCounter.
triggerPhi += (
re->numStrips(placement->hash())>0);
424 <<
m_idHelperSvc->toStringGasGap(placement->identify())<<
".");
427 ATH_MSG_VERBOSE(__func__<<
"() "<<__LINE__<<
" - Precision hole detected "
434 <<placement->detectorType());
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define AmgSymMatrix(dim)
: Helper class to assign a @ActsSurfacePlacementBase to the Acts::Surfaces in order to make them alig...
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
int8_t side() const
Returns the side of the MS-sector 1 -> A side ; -1 -> C side.
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
int sector() const
Returns the sector of the MS-sector.
Muon::MuonStationIndex::ChIndex chamberIndex() const
Returns the chamber index scheme.
State
State flag to distinguish different space point states.
Placeholder for what will later be the muon segment EDM representation.
double segementT0() const
Returns the fitted segment time, if there's any.
unsigned int nDoF() const
Returns the number of degrees of freedom.
const SegmentFit::Covariance & covariance() const
Returns the uncertainties of the defining parameters.
const MuonGMR4::SpectrometerSector * msSector() const
Returns the associated MS sector.
Muon::MuonStationIndex::TechnologyIndex technology() const
Returns the technology index of the first precision hit.
const MeasVec & measurements() const
Returns the associated measurements.
double chi2() const
Returns the chi2 of the segment fit.
const Amg::Vector3D & position() const
Returns the global segment position.
const Amg::Vector3D & direction() const
Returns the global segment direction.
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
ActsTrk::detail::MeasurementCalibratorBase::ProjectorType ProjectorType
Use the calibration projector.
void setDirection(float px, float py, float pz)
Sets the direction.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
Amg::Vector3D direction() const
Returns the direction as Amg::Vector.
void setT0Error(float t0, float t0Error)
Sets the time error.
void setNHits(const std::uint8_t nPrecisionHits, const std::uint8_t nPhiLayers, const std::uint8_t nTrigEtaLayers)
Assign the segment hit summary.
void setNOutliers(const std::uint8_t nPrecOutliers, const std::uint8_t nTrigPhiOutliers, const std::uint8_t nTrigEtaOutliers)
Assign the number of hits with a large pull per hit category.
void setNHoles(const std::uint8_t nPrecHoles, const std::uint8_t nTrigPhiHoles, const std::uint8_t nTrigEtaHoles)
Assign the number of expected but missing hits.
void setPosition(float x, float y, float z)
Sets the global position.
void setIdentifier(const std::uint8_t sector, const ::Muon::MuonStationIndex::ChIndex chamberIndex, const std::int8_t etaIndex, const ::Muon::MuonStationIndex::TechnologyIndex technology)
Set the Identifier fields of the Segment.
Amg::Vector3D position() const
Returns the position as Amg::Vector.
virtual unsigned int numDimensions() const =0
Returns the number of dimensions of the measurement.
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.
Acts::Vector4 convertPosToActs(const Amg::Vector3D &athenaPos, const double athenaTime=0.)
Converts a position vector & time from Athena units into Acts units.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Amg::Isometry3D getTranslate3D(const double X, const double Y, const double Z)
: Returns a shift transformation along an arbitrary axis
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
const Acts::Surface * bottomBoundary(const Acts::TrackingVolume &volume)
Returns the boundary surface parallel to the x-y plane at negative local z.
const Acts::TrackingVolume * highestAlignable(const Acts::TrackingVolume *volume)
Returns the highest parent volume that is alignable.
const Acts::Surface * topBoundary(const Acts::TrackingVolume &volume)
Returns the boundary surface parallel to the x-y plane at positive local z.
SeedingAux::FitParIndex ParamDefs
Use the same parameter indices as used by the CompSpacePointAuxiliaries.
This header ties the generic definitions in this package.
const xAOD::UncalibratedMeasurement * getMeasurement(const xAOD::MuonSegment &segment, const std::size_t n)
Returns the n-th uncalibrated measurement.
CalibratedSpacePoint::State State
std::size_t nMeasurements(const xAOD::MuonSegment &segment)
Returns the number of associated Uncalibrated measurements.
Acts::GeometryIdentifier volumeId(const Acts::Surface &surface)
Returns the identifier of the volume in which the surface is embedded.
bool isOutlierMeasurement(const xAOD::MuonSegment &segment, const std::size_t n)
Returns whether the n-the uncalibrated measurement is an outlier.
std::vector< PrdLink_t > PrdLinkVec_t
xAOD::PosAccessor< Acts::toUnderlying(ParamDefs::nPars)>::element_type SegPars_t
SG::AuxElement::Accessor< std::array< float, N > > PosAccessor
xAOD Accessor to the position
UncalibratedMeasurement_v1 UncalibratedMeasurement
Define the version of the uncalibrated measurement class.
MuonMeasurement_v1 MuonMeasurement
MeasVector< N > toStorage(const AmgVector(N)&amgVec)
Converts the double precision of the AmgVector into the floating point storage precision of the MeasV...
UncalibMeasType
Define the type of the uncalibrated measurement.
bool isPrecisionHit(const UncalibratedMeasurement *meas)
Returns whether the measurement is a precision hit.
std::pair< Amg::Vector2D, AmgSymMatrix(2)> positionAndCovariance(const MuonMeasurement *oneDimMeas)
Returns the 1D position of the uncalibrated measurement expressed in the coordinate system of the mea...
UncalibratedMeasurementContainer_v1 UncalibratedMeasurementContainer
Define the version of the uncalibrated measurement container.
MuonSegment_v1 MuonSegment
Reference the current persistent version:
const Acts::Surface & muonSurface(const UncalibratedMeasurement *meas)
Returns the associated Acts surface to the measurement.
#define THROW_EXCEPTION(MESSAGE)