29#include "Acts/Utilities/MathHelpers.hpp"
30#include "Acts/Utilities/Enumerate.hpp"
34 constexpr double c_inv = 1./ Gaudi::Units::c_light;
39 using namespace Acts::UnitLiterals;
51 return StatusCode::SUCCESS;
57 std::vector<int> signs = SeedingAux::strawSigns(trackPos, trackDir,
59 for (
const auto [spIdx,
sp]: Acts::enumerate(hitsToCalib)) {
60 sp->setDriftRadius(
sp->driftRadius() * signs[spIdx]);
67 const double timeDelay)
const {
72 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint);
74 if (spacePoint.
fitState() == State::Outlier) {
75 calibSP->setFitState(State::Outlier);
76 }
else if (spacePoint.
fitState() == State::Duplicate) {
77 calibSP->setFitState(State::Duplicate);
85 const double timeDelay,
88 const EventContext* ctx = cctx.get<
const EventContext*>();
89 newCalib.reserve(spacePoints.size());
91 newCalib.emplace_back(
calibrate(*ctx, *
sp, segPos, segDir, timeDelay));
100 const double timeOffset)
const {
113 : spPos +
Amg::intersect<3>(posInChamb, dirInChamb, spPos, chDir).value_or(0) * chDir;
118 switch (spacePoint->
type()) {
122 posInChamb, dirInChamb).value_or(0) * dirInChamb;
124 Amg::Vector3D closestApproach{locToGlob* locClosestApproach};
125 const double timeOfArrival = closestApproach.mag() * c_inv + timeOffset;
131 Acts::abs(dirInChamb.phi() - 90._degree) > 1.e-7 );
137 State fitState{State::Valid};
139 if (calibOutput.
status() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime) {
141 <<std::endl<<calibInput<<std::endl<<calibOutput);
142 fitState = State::FailedCalib;
143 cov[Acts::toUnderlying(AxisDefs::etaCov)] = dc->readoutElement()->innerTubeRadius();
145 cov[Acts::toUnderlying(AxisDefs::etaCov)] = Acts::square(calibOutput.
driftRadiusUncert());
147 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos), fitState);
148 calibSP->setCovariance(cov);
149 calibSP->setDriftRadius(calibOutput.
driftRadius());
156 MdtCalibInput twinInput{dc->twinIdentify(), dc->twinAdc(), dc->twinTdc(), dc->readoutElement(), *gctx};
161 std::move(calibInput),
162 std::move(twinInput));
164 State fitState{State::Valid};
165 if (calibOutput.
primaryStatus() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime) {
167 <<std::endl<<calibOutput);
168 cov[Acts::toUnderlying(AxisDefs::etaCov)] = Acts::square(dc->readoutElement()->innerTubeRadius());
169 cov[Acts::toUnderlying(AxisDefs::phiCov)] = Acts::square(0.5* dc->readoutElement()->activeTubeLength(dc->measurementHash()));
170 fitState = State::FailedCalib;
172 cov[Acts::toUnderlying(AxisDefs::etaCov)] = Acts::square(calibOutput.
uncertPrimaryR());
173 cov[Acts::toUnderlying(AxisDefs::phiCov)] = Acts::square(calibOutput.
sigmaZ());
175 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos), fitState);
176 calibSP->setCovariance(cov);
188 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
192 const double time1 =
strip->time()
193 -
strip->readoutElement()->distanceToEdge(
strip->layerHash(), lPos,
199 const double time2 = strip2->time() -
200 strip2->readoutElement()->distanceToEdge(strip2->layerHash(),lPos, EdgeSide::readOut)/
m_rpcSignalVelocity;
202 calibSP->setTimeMeasurement(0.5*(time1 + time2));
204 cov[Acts::toUnderlying(AxisDefs::timeCov)] += Acts::square(0.5*(time1 - time2));
206 calibSP->setCovariance(cov);
208 <<
", at "<<
Amg::toString(calibSP->localPosition())<<
", uncalib time: "
209 <<
strip->time()<<
", calib time: "<<calibSP->time()<<
" cov " <<calibSP->covariance());
213 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
214 calibSP->setCovariance(cov);
222 std::pair<double, double> calibPosCov {
calibrateMM(ctx, *gctx, *cluster, globalPos, globalDir)};
224 ATH_MSG_DEBUG(
"Calibrated pos and cov" << calibPosCov.first <<
" " << calibPosCov.second);
225 cov[Acts::toUnderlying(AxisDefs::etaCov)] = calibPosCov.second;
229 Amg::Vector3D calibSpPosInLayer = toChamberTrans.inverse() * calibSpPos;
231 calibSpPosInLayer.x() = calibPosCov.first;
233 calibSpPos = toChamberTrans * calibSpPosInLayer;
235 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
236 calibSP->setCovariance(cov);
247 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
248 calibSP->setCovariance(cov);
252 std::optional<double> posAlongTheStrip{std::nullopt};
258 posAlongTheStrip =
static_cast<double>(spacePoint->
secondaryMeasurement()->localPosition<1>()[0]);
267 const auto [calibPos, calibCov] =
calibratesTGC(ctx, *gctx, *stripClus, posAlongTheStrip, globalPos, globalDir);
269 ATH_MSG_DEBUG(
"Calibrated pos and cov" << calibPos <<
" " << calibCov);
270 cov[Acts::toUnderlying(AxisDefs::etaCov)] = calibCov;
271 Amg::Transform3D toChamberTrans{ locToGlob.inverse() * cluster->readoutElement()->localToGlobalTrans(*gctx, cluster->layerHash())};
274 Amg::Vector3D calibSpPosInLayer = toChamberTrans.inverse() * calibSpPos;
276 calibSpPosInLayer.x() = calibPos;
278 calibSpPos = toChamberTrans * calibSpPosInLayer;
280 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
281 calibSP->setCovariance(cov);
282 ATH_MSG_DEBUG(
"calibrated sTGC cluster "<<
m_idHelperSvc->toString(cluster->identify()) <<
" loc x old " << cluster->localPosition<1>()[0] <<
" new loc x " << calibSP->localPosition()[1] <<
"cov " << calibSP->covariance());
293 const std::vector<const SpacePoint*>& spacePoints,
296 const double timeOffset)
const {
298 calibSpacePoints.reserve(spacePoints.size());
299 for(
const SpacePoint* spacePoint : spacePoints) {
302 calibSpacePoints.push_back(std::move(hit));
305 return calibSpacePoints;
312 const std::optional<double> driftTime = calibConsts->
rtRelation->tr()->driftTime(spacePoint.
driftRadius());
313 return calibConsts->
rtRelation->rt()->driftVelocity(driftTime.value_or(0.));
321 const std::optional<double> driftTime = calibConsts->
rtRelation->tr()->driftTime(spacePoint.
driftRadius());
322 return calibConsts->
rtRelation->rt()->driftAcceleration(driftTime.value_or(0.));
332 std::vector<NSWCalib::CalibratedStrip> calibClus;
333 StatusCode
sc =
m_nswCalibTool->calibrateClus(ctx, gctx, cluster, globalPos, calibClus);
336 return std::make_pair(0., 0.);
343 calibCov.resize(1,1);
345 ATH_MSG_DEBUG(
"old loc pos " << locPos[0] <<
" old cov" << calibCov(0,0) );
348 if(rotAuthor == Muon::IMMClusterBuilderTool::RIO_Author::unKnownAuthor){
351 ATH_MSG_DEBUG(
"new loc pos " << locPos[0] <<
" new cov" << calibCov(0,0) );
352 return std::make_pair(locPos[0], calibCov(0,0));
358 std::optional<double> posAlongTheStrip,
363 if(!posAlongTheStrip) {
365 posAlongTheStrip = extPosLocal[1];
375 ActsTrk::MutableTrackContainer::TrackStateProxy state)
const {
396 const auto& radialDesign = stripMeas->readoutElement()->stripLayout(stripMeas->layerHash());
397 const auto& wireDesign = wireMeas->readoutElement()->wireGangLayout(wireMeas->layerHash());
399 const double dirDots = radialDesign.stripDir(stripMeas->channelNumber()).dot(wireDesign.stripNormal());
402 const double invDist = 1. / (1. - Acts::square(dirDots));
403 stereoTrf(0, 0) = stereoTrf(1, 1) = invDist;
404 stereoTrf(0, 1) = stereoTrf(1, 0) = -dirDots * invDist;
407 stripMeas->localPosition<1>()[0]};
409 cmbCov (0, 0) = wireMeas->localCovariance<1>()(0,0);
410 cmbCov (1, 1) = stripMeas->localCovariance<1>()(0,0);
413 stereoTrf*cmbCov*stereoTrf.transpose(), sl, state);
420 const Acts::CalibrationContext& cctx,
421 const Acts::SourceLink& link,
422 ActsTrk::MutableTrackContainer::TrackStateProxy trackState)
const {
425 const Acts::BoundTrackParameters trackPars{trackState.referenceSurface().getSharedPtr(),
426 trackState.parameters(), trackState.covariance(),
427 Acts::ParticleHypothesis::muon()};
432 const EventContext* ctx = cctx.get<
const EventContext*>();
434 <<
" @ surface "<<trackState.referenceSurface().geometryId());
436 if (muonMeas->numDimensions() == 0u) {
445 switch (muonMeas->type()){
447 case MdtDriftCircleType: {
454 static_cast<double>(dec_trackSign(*dc)) :
455 sign(trackPars.parameters()[Acts::eBoundLoc0]);
458 if (
ATH_LIKELY(muonMeas->numDimensions() == 1)) {
464 if (calibOutput.
status() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime) {
466 <<std::endl<<calibInput<<std::endl<<calibOutput);
467 cov(Acts::eBoundLoc0,Acts::eBoundLoc0) = std::pow(dc->readoutElement()->innerTubeRadius(), 2);
469 pos[Acts::eBoundLoc0] = driftSign*calibOutput.
driftRadius();
470 cov(Acts::eBoundLoc0, Acts::eBoundLoc0) = std::pow(calibOutput.
driftRadiusUncert(), 2);
477 MdtCalibInput twinInput{twinDC->twinIdentify(), twinDC->twinAdc(), twinDC->twinTdc(), twinDC->readoutElement(), *gctx};
482 std::move(calibInput),
483 std::move(twinInput));
486 if (calibOutput.
primaryStatus() != Muon::MdtDriftCircleStatus::MdtStatusDriftTime) {
488 <<std::endl<<calibOutput);
489 locCov(Acts::eBoundLoc0, Acts::eBoundLoc0) = std::pow(dc->readoutElement()->innerTubeRadius(), 2);
490 locCov(Acts::eBoundLoc1, Acts::eBoundLoc1) = std::pow(0.5* dc->readoutElement()->activeTubeLength(dc->measurementHash()), 2);
492 locCov(Acts::eBoundLoc0, Acts::eBoundLoc0) = std::pow(calibOutput.
uncertPrimaryR(), 2);
493 locCov(Acts::eBoundLoc1, Acts::eBoundLoc1) = std::pow(calibOutput.
sigmaZ(), 2);
494 locPos[Acts::eBoundLoc0] = driftSign*calibOutput.
primaryDriftR();
495 locPos[Acts::eBoundLoc1] = calibOutput.
locZ();
500 }
case RpcStripType: {
503 if (
ATH_LIKELY(rpcClust->numDimensions() == 1)) {
509 rpcClust->localPosition<1>(),
510 rpcClust->localCovariance<1>(), link, trackState);
514 measPars[0] = rpcClust->localPosition<1>()[0];
515 measCov(0,0) = rpcClust->localCovariance<1>()(0, 0);
516 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
"Please fix me using the ActsInterops package");
521 measPars, measCov, link, trackState);
528 rpcClust->localPosition<2>(),
529 rpcClust->localCovariance<2>(), link, trackState);
533 measPars.block<2,1>(0,0) = xAOD::toEigen(rpcClust->localPosition<2>());
534 measCov.block<2,2>(0,0) = xAOD::toEigen(rpcClust->localCovariance<2>());
535 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
"Please fix me using the ActsInterops package");
538 measPars, measCov, link, trackState);
542 }
case TgcStripType: {
543 const auto* tgcClust =
static_cast<const xAOD::TgcStrip*
>(muonMeas);
548 tgcClust->localPosition<1>(),
549 tgcClust->localCovariance<1>(), link, trackState);
555 case MMClusterType: {
557 std::pair<double, double> calibPosCov{
calibrateMM(*ctx,* gctx, *mmClust, trackPos, trackDir)};
562 pos, cov, link, trackState);
564 }
case sTgcStripType: {
569 muonMeas->localPosition<1>(),
570 muonMeas->localCovariance<1>(), link, trackState);
574 stgcClust->localPosition<2>(),
575 stgcClust->localCovariance<2>(), link, trackState);
580 std::pair<double, double> calibPosCov{
calibratesTGC(*ctx, *gctx, *stgCluster, std::nullopt, trackPos, trackDir)};
586 cov, link, trackState);
591 pos[0] = calibPosCov.first;
592 pos[1] = stgCluster->time();
593 cov(0,0) = calibPosCov.second;
594 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
"Please fix me using the ActsInterops package");
595 cov(1,1) = std::pow(25 , 2);
599 cov, link, trackState);
607 THROW_EXCEPTION(
"The parsed measurement is not a muon measurement. Please check.");
616 dec_trackSign(*meas->spacePoint()->primaryMeasurement()) =
617 SeedingAux::strawSign(segPos, segLine, *meas);
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define AmgSymMatrix(dim)
@ e2DimWithTime
Project out the locY & time coordinate - (Applies to Rpc, Tgc, sTgc)
@ e2DimNoTime
Project out solely the locY - Complementary projector if the strip plane is rotated (Applies to Itk e...
@ e1DimWithTime
Project out the two spatial coordinates - (Applies to ITk pixel, BI-Rpc, sTgc pad)
@ e1DimRotNoTime
Project out solely the locX (Applies to Itk strips, Rpc, Tgc, sTgc, Mm)
@ e1DimRotWithTime
Project out the locX & time coordinate - (Applies to Rpc, Tgc, Mm, sTgc)
void setState(const ProjectorType projector, const pos_t &locpos, const cov_t &cov, Acts::SourceLink link, TrackState_t< trajectory_t > &trackState) const
Copy the local position & covariance into the Acts track state proxy.
static const xAOD::UncalibratedMeasurement * unpack(const Acts::SourceLink &sl)
Helper method to unpack an Acts source link to an uncalibrated measurement.
static Acts::SourceLink pack(const xAOD::UncalibratedMeasurement *meas)
Helper method to pack an uncalibrated measurement to an Acts source link.
double driftRadiusUncert() const
Returns the uncertainty on the drift radius.
double driftRadius() const
Returns the drift radius of the calibrated object.
MdtDriftCircleStatus status() const
Status of the calibration.
MdtDriftCircleStatus primaryStatus() const
double primaryDriftR() const
double uncertPrimaryR() const
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
Amg::Transform3D globalToLocalTrans(const ActsTrk::GeometryContext &ctx) const
Transformations to translate between local <-> global coordinates.
const Amg::Transform3D & localToGlobalTrans(const ActsTrk::GeometryContext &gctx) const
Returns the local -> global tarnsformation from the sector.
The calibrated Space point is created during the calibration process.
double driftRadius() const
: Returns the size of the drift radius
const SpacePoint * spacePoint() const
The pointer to the space point out of which this space point has been built.
xAOD::UncalibMeasType type() const
Returns the space point type.
State
State flag to distinguish different space point states.
State fitState() const
Returns the state of the calibrated space point.
std::unique_ptr< CalibratedSpacePoint > CalibSpacePointPtr
std::vector< CalibSpacePointPtr > CalibSpacePointVec
Placeholder for what will later be the muon segment EDM representation.
const MeasVec & measurements() const
Returns the associated measurements.
Gaudi::Property< bool > m_useRpcTime
Load the Rpc time on the track states for the track fit.
void calibrateCombinedPrd(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const xAOD::CombinedMuonStrip *combinedPrd, ActsTrk::MutableTrackContainer::TrackStateProxy state) const
Calibrates the track states from a combined muon strip.
ToolHandle< Muon::IMMClusterBuilderTool > m_clusterBuilderToolMM
void calibrateSourceLink(const Acts::GeometryContext &geoctx, const Acts::CalibrationContext &cctx, const Acts::SourceLink &link, ActsTrk::MutableTrackContainer::TrackStateProxy state) const override final
ToolHandle< Muon::INSWCalibTool > m_nswCalibTool
std::pair< double, double > calibratesTGC(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const xAOD::sTgcStripCluster &cluster, std::optional< double > posAlongTheStrip, const Amg::Vector3D &globalPos, const Amg::Vector3D &globalDir) const
Calibrates the position and covariance of an sTGC (small-strip Thin Gap Chamber) cluster.
double driftVelocity(const Acts::CalibrationContext &ctx, const CalibratedSpacePoint &spacePoint) const override final
ToolHandle< IMdtCalibrationTool > m_mdtCalibrationTool
CalibSpacePointPtr calibrate(const EventContext &ctx, const SpacePoint *spacePoint, const Amg::Vector3D &seedPosInChamb, const Amg::Vector3D &seedDirInChamb, const double timeDelay) const override final
Gaudi::Property< double > m_rpcSignalVelocity
How fast does an electron signal travel along an rpc strip.
void updateSigns(const Amg::Vector3D &trackPos, const Amg::Vector3D &trackDir, CalibSpacePointVec &hitsToCalib) const override final
StatusCode initialize() override final
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
const MuonGMR4::MuonDetectorManager * m_detMgr
Gaudi::Property< bool > m_MdtSignFromSegment
Gaudi::Property< bool > m_useTgcTime
Load the Tgc bunch crossing ID on the track states.
SG::ReadHandleKey< ActsTrk::GeometryContext > m_geoCtxKey
access to the ACTS geometry context
Gaudi::Property< bool > m_usesTgcTime
double driftAcceleration(const Acts::CalibrationContext &ctx, const CalibratedSpacePoint &spacePoint) const override final
Gaudi::Property< double > m_rpcTimeResolution
std::pair< double, double > calibrateMM(const EventContext &ctx, const ActsTrk::GeometryContext &gctx, const xAOD::MMCluster &cluster, const Amg::Vector3D &globalPos, const Amg::Vector3D &globalDir) const
Calibrates the position and covariance of a MicroMegas (MM) cluster.
void stampSignsOnMeasurements(const xAOD::MuonSegment &segment) const override final
The muon space point is the combination of two uncalibrated measurements one of them measures the eta...
unsigned dimension() const
Is the space point a 1D or combined 2D measurement.
const Amg::Vector3D & sensorDirection() const
const xAOD::UncalibratedMeasurement * secondaryMeasurement() const
const Amg::Vector3D & localPosition() const
std::array< double, 3 > Cov_t
Abrivation of the covariance type.
const Identifier & identify() const
: Identifier of the primary measurement
xAOD::UncalibMeasType type() const
const Cov_t & covariance() const
Returns the covariance array.
const xAOD::UncalibratedMeasurement * primaryMeasurement() const
const MuonGMR4::SpectrometerSector * msSector() const
Helper class to provide type-safe access to aux data.
const xAOD::UncalibratedMeasurement * secondaryStrip() const
Returns the secondary associated measurement.
const xAOD::UncalibratedMeasurement * primaryStrip() const
Returns the primary associated measurement.
virtual xAOD::UncalibMeasType type() const override final
Returns the type of the measurement type as a simple enumeration.
const Identifier & identify() const
: Returns the Athena identifier of the micro mega cluster It's constructed from the measurementHash &...
IdentifierHash layerHash() const
Returns the hash of the associated layer (Needed for surface retrieval)
const MuonGMR4::MmReadoutElement * readoutElement() const
Retrieve the associated MmReadoutElement.
ConstMatrixMap< N > localCovariance() const
Returns the local covariance of the measurement.
ConstVectorMap< N > localPosition() const
Returns the local position of the measurement.
IdentifierHash layerHash() const
Returns the hash of the associated gasGap layer.
const MuonGMR4::sTgcReadoutElement * readoutElement() const
Retrieve the associated sTgcReadoutElement.
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Parameters localSegmentPars(const xAOD::MuonSegment &seg)
Returns the localSegPars decoration from a xAODMuon::Segment.
std::pair< Amg::Vector3D, Amg::Vector3D > makeLine(const Parameters &pars)
Returns the parsed parameters into an Eigen line parametrization.
This header ties the generic definitions in this package.
constexpr double sign(const double x)
Returns the sign of a number.
ISpacePointCalibrator::CalibSpacePointVec CalibSpacePointVec
CalibratedSpacePoint::State State
ISpacePointCalibrator::CalibSpacePointPtr CalibSpacePointPtr
const Segment * detailedSegment(const xAOD::MuonSegment &seg)
Helper function to navigate from the xAOD::MuonSegment to the MuonR4::Segment.
Amg::Vector3D toLocal(const Amg::Transform3D &toLocalTrans, const Amg::Vector3D &dir)
Rotates a direction vector into a local frame: x-axis : Parallell to the radial direction of the dete...
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
MdtDriftCircle_v1 MdtDriftCircle
MdtTwinDriftCircle_v1 MdtTwinDriftCircle
sTgcStripCluster_v1 sTgcStripCluster
UncalibMeasType
Define the type of the uncalibrated measurement.
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
RpcMeasurement_v1 RpcMeasurement
sTgcMeasurement_v1 sTgcMeasurement
MuonSegment_v1 MuonSegment
Reference the current persistent version:
CombinedMuonStrip_v1 CombinedMuonStrip
class which holds the full set of calibration constants for a given tube
#define THROW_EXCEPTION(MESSAGE)