15 #include "GaudiKernel/PhysicalConstants.h"
26 #include "Acts/Utilities/MathHelpers.hpp"
37 using namespace Acts::UnitLiterals;
41 using namespace SegmentFit;
46 ATH_CHECK(m_mdtCalibrationTool.retrieve(EnableTool{m_idHelperSvc->hasMDT()}));
47 ATH_CHECK(m_nswCalibTool.retrieve(EnableTool{m_idHelperSvc->hasMM() || m_idHelperSvc->hasSTGC()}));
49 return StatusCode::SUCCESS;
56 const double timeDelay)
const {
59 calibSP = calibrate(ctx, spacePoint.
spacePoint(), segPos, segDir, timeDelay);
61 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint);
73 const double timeDelay)
const {
75 sp = calibrate(ctx, *sp, segPos, segDir, timeDelay);
84 const double timeOffset)
const {
87 if (!
SG::get(gctx, m_geoCtxKey, ctx).isSuccess()) {
97 : spPos + Amg::intersect<3>(posInChamb, dirInChamb, spPos, chDir).value_or(0) * chDir;
101 switch (spacePoint->
type()) {
104 + Amg::intersect<3>(spPos, chDir,
105 posInChamb, dirInChamb).value_or(0) * dirInChamb;
107 Amg::Vector3D closestApproach{locToGlob* locClosestApproach};
108 const double timeOfArrival = closestApproach.mag() * c_inv + timeOffset;
114 Acts::abs(dirInChamb.phi() - 90._degree) > 1.e-7 );
115 calibInput.setTimeOfFlight(timeOfArrival);
116 calibInput.setClosestApproach(std::move(closestApproach));
117 ATH_MSG_VERBOSE(
"Parse hit calibration "<<m_idHelperSvc->toString(dc->identify())<<
", "<<calibInput);
118 MdtCalibOutput calibOutput = m_mdtCalibrationTool->calibrate(ctx, calibInput);
123 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
124 <<std::endl<<calibInput<<std::endl<<calibOutput);
130 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos), fitState);
131 calibSP->setCovariance(
cov);
132 calibSP->setDriftRadius(calibOutput.
driftRadius());
137 calibInput.setTimeOfFlight(timeOfArrival);
139 MdtCalibInput twinInput{dc->twinIdentify(), dc->twinAdc(), dc->twinTdc(), dc->readoutElement(), *gctx};
141 twinInput.setTimeOfFlight(timeOfArrival);
144 std::move(calibInput),
145 std::move(twinInput));
149 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
150 <<std::endl<<calibOutput);
151 cov[Acts::toUnderlying(
AxisDefs::etaCov)] = Acts::square(dc->readoutElement()->innerTubeRadius());
152 cov[Acts::toUnderlying(
AxisDefs::phiCov)] = Acts::square(0.5* dc->readoutElement()->activeTubeLength(dc->measurementHash()));
158 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos), fitState);
159 calibSP->setCovariance(
cov);
168 const Amg::Transform3D toGasGap{strip->readoutElement()->globalToLocalTrans(*gctx, strip->layerHash()) * locToGlob};
171 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
175 const double time1 = strip->time()
176 - strip->readoutElement()->distanceToEdge(strip->layerHash(),
177 lPos.block<2,1>(0,0),
178 EdgeSide::readOut) /m_rpcSignalVelocity;
183 const double time2 = strip2->
time() -
184 strip2->readoutElement()->distanceToEdge(strip2->layerHash(),
185 Eigen::Rotation2D{90._degree}*lPos.block<2,1>(0,0),
186 EdgeSide::readOut)/m_rpcSignalVelocity;
188 calibSP->setTimeMeasurement(0.5*(time1 + time2));
192 calibSP->setCovariance(
cov);
193 ATH_MSG_VERBOSE(
"Create rpc space point "<<m_idHelperSvc->toString(strip->identify())<<
", dimension "<<spacePoint->
dimension()
194 <<
", at "<<
Amg::toString(calibSP->localPosition())<<
", uncalib time: "
195 <<strip->time()<<
", calib time: "<<calibSP->time()<<
" cov " <<calibSP->covariance());
199 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
200 calibSP->setCovariance(
cov);
208 std::pair<double, double> calibPosCov {calibrateMM(ctx, *gctx, *cluster, globalPos, globalDir)};
210 ATH_MSG_DEBUG(
"Calibrated pos and cov" << calibPosCov.first <<
" " << calibPosCov.second);
215 Amg::Vector3D calibSpPosInLayer = toChamberTrans.inverse() * calibSpPos;
217 calibSpPosInLayer.x() = calibPosCov.first;
219 calibSpPos = toChamberTrans * calibSpPosInLayer;
221 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
222 calibSP->setCovariance(
cov);
223 ATH_MSG_DEBUG(
"calibrated MM cluster "<<m_idHelperSvc->toString(cluster->
identify()) <<
" loc x old " << cluster->
localPosition<1>()[0] <<
" new loc x " << calibSP->localPosition()[1] <<
"cov " << calibSP->covariance());
231 if (cluster->channelType() != sTgcIdHelper::sTgcChannelTypes::Strip) {
232 ATH_MSG_DEBUG(
"Calibrating an sTGC Pad or wire " << m_idHelperSvc->toString(cluster->identify()));
233 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
234 calibSP->setCovariance(
cov);
238 double posAlongTheStrip{0.};
243 ATH_MSG_VERBOSE(
"Using secondary measurement "<< m_idHelperSvc->toString(secMeas->identify())<<
" for sTGC strip cluster " << m_idHelperSvc->toString(cluster->identify()));
246 ATH_MSG_VERBOSE(
"No secondary measurement for sTGC strip cluster " << m_idHelperSvc->toString(cluster->identify()));
253 const auto [calibPos, calibCov] = calibratesTGC(ctx, *gctx, *stripClus, posAlongTheStrip, globalPos, globalDir);
255 ATH_MSG_DEBUG(
"Calibrated pos and cov" << calibPos <<
" " << calibCov);
257 Amg::Transform3D toChamberTrans{ locToGlob.inverse() * cluster->readoutElement()->localToGlobalTrans(*gctx, cluster->layerHash())};
260 Amg::Vector3D calibSpPosInLayer = toChamberTrans.inverse() * calibSpPos;
262 calibSpPosInLayer.x() = calibPos;
264 calibSpPos = toChamberTrans * calibSpPosInLayer;
266 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
267 calibSP->setCovariance(
cov);
268 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());
283 const double timeOffset)
const {
287 CalibSpacePointPtr hit = calibrate(ctx, spacePoint, posInChamb, dirInChamb, timeOffset);
289 calibSpacePoints.push_back(std::move(hit));
292 return calibSpacePoints;
315 std::vector<NSWCalib::CalibratedStrip> calibClus;
316 StatusCode sc = m_nswCalibTool->calibrateClus(ctx, gctx, cluster, globalPos, calibClus);
319 return std::make_pair(0., 0.);
326 calibCov.resize(1,1);
328 ATH_MSG_DEBUG(
"old loc pos " << locPos[0] <<
" old cov" << calibCov(0,0) );
331 if(rotAuthor == Muon::IMMClusterBuilderTool::RIO_Author::unKnownAuthor){
334 ATH_MSG_DEBUG(
"new loc pos " << locPos[0] <<
" new cov" << calibCov(0,0) );
335 return std::make_pair(locPos[0], calibCov(0,0));
346 if(posAlongTheStrip == -FLT_MAX){
348 posAlongTheStrip = extPosLocal[1];
357 const Acts::CalibrationContext& cctx,
358 const Acts::SourceLink& link,
359 ActsTrk::MutableTrackContainer::TrackStateProxy trackState)
const {
362 const Acts::BoundTrackParameters trackPars{trackState.referenceSurface().getSharedPtr(),
363 trackState.parameters(), trackState.covariance(),
369 const EventContext* ctx = cctx.get<
const EventContext*>();
372 <<
" @ surface "<<trackState.referenceSurface().geometryId());
373 switch (muonMeas->type()){
375 case MdtDriftCircleType: {
378 calibInput.setClosestApproach(trackPos);
380 calibInput.setTrackDirection(trackDir,
true);
381 const double driftSign =
sign(trackPars.parameters()[Acts::eBoundLoc0]);
384 if (
ATH_LIKELY(muonMeas->numDimensions() == 1)) {
385 MdtCalibOutput calibOutput = m_mdtCalibrationTool->calibrate(*ctx, calibInput);
391 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
392 <<std::endl<<calibInput<<std::endl<<calibOutput);
393 cov(Acts::eBoundLoc0,Acts::eBoundLoc0) =
std::pow(dc->readoutElement()->innerTubeRadius(), 2);
398 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
pos,
cov, link, trackState);
403 MdtCalibInput twinInput{twinDC->twinIdentify(), twinDC->twinAdc(), twinDC->twinTdc(), twinDC->readoutElement(), *gctx};
404 twinInput.setClosestApproach(trackPos);
405 twinInput.setTimeOfFlight(trackPars.parameters()[Acts::eBoundTime]);
408 std::move(calibInput),
409 std::move(twinInput));
413 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
414 <<std::endl<<calibOutput);
415 locCov(Acts::eBoundLoc0, Acts::eBoundLoc0) =
std::pow(dc->readoutElement()->innerTubeRadius(), 2);
416 locCov(Acts::eBoundLoc1, Acts::eBoundLoc1) =
std::pow(0.5* dc->readoutElement()->activeTubeLength(dc->measurementHash()), 2);
419 locCov(Acts::eBoundLoc1, Acts::eBoundLoc1) =
std::pow(calibOutput.
sigmaZ(), 2);
420 locPos[Acts::eBoundLoc0] = driftSign*calibOutput.
primaryDriftR();
421 locPos[Acts::eBoundLoc1] = calibOutput.
locZ();
423 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimNoTime, locPos, locCov, link, trackState);
426 }
case RpcStripType: {
429 if (
ATH_LIKELY(rpcClust->numDimensions() == 1)) {
431 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
432 rpcClust->localPosition<1>(),
433 rpcClust->localCovariance<1>(), link, trackState);
437 measPars[0] = rpcClust->localPosition<1>()[0];
438 measCov(0,0) = rpcClust->localCovariance<1>()(0, 0);
439 measCov(1,1) =
std::pow(m_rpcTimeResolution, 2);
440 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimWithTime,
441 measPars, measCov, link, trackState);
447 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
448 rpcClust->localPosition<2>(),
449 rpcClust->localCovariance<2>(), link, trackState);
453 measPars.block<2,1>(0,0) = xAOD::toEigen(rpcClust->localPosition<2>());
454 measCov.block<2,2>(0,0) = xAOD::toEigen(rpcClust->localCovariance<2>());
455 measCov(2,2) =
std::pow(m_rpcTimeResolution, 2);
456 setState<3, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimWithTime,
457 measPars, measCov, link, trackState);
461 }
case TgcStripType: {
463 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimRotNoTime,
464 muonMeas->localPosition<1>(),
465 muonMeas->localCovariance<1>(), link, trackState);
471 case MMClusterType: {
473 std::pair<double, double> calibPosCov{calibrateMM(*ctx,* gctx, *mmClust, trackPos, trackDir)};
477 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
479 cov, link, trackState);
481 }
case sTgcStripType: {
484 if(stgcClust->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire) {
485 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
486 muonMeas->localPosition<1>(),
487 muonMeas->localCovariance<1>(), link, trackState);
489 }
else if(stgcClust->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad) {
490 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimNoTime,
491 stgcClust->localPosition<2>(),
492 stgcClust->localCovariance<2>(), link, trackState);
497 std::pair<double, double> calibPosCov{calibratesTGC(*ctx, *gctx, *stgCluster, -FLT_MAX, trackPos, trackDir)};
501 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
503 cov, link, trackState);
508 pos[0] = calibPosCov.first;
509 pos[1] = stgCluster->time();
510 cov(0,0) = calibPosCov.second;
513 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimWithTime,
515 cov, link, trackState);
523 THROW_EXCEPTION(
"The parsed measurement is not a muon measurement. Please check.");