29 #include "Acts/Utilities/MathHelpers.hpp"
30 #include "Acts/Utilities/Enumerate.hpp"
39 using namespace Acts::UnitLiterals;
43 using namespace SegmentFit;
48 ATH_CHECK(m_mdtCalibrationTool.retrieve(EnableTool{m_idHelperSvc->hasMDT()}));
49 ATH_CHECK(m_nswCalibTool.retrieve(EnableTool{m_idHelperSvc->hasMM() || m_idHelperSvc->hasSTGC()}));
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 {
70 calibSP = calibrate(ctx, spacePoint.
spacePoint(), segPos, segDir, timeDelay);
72 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint);
85 const double timeDelay,
88 const EventContext* ctx = cctx.get<
const EventContext*>();
91 newCalib.emplace_back(calibrate(*ctx, *sp, segPos, segDir, timeDelay));
100 const double timeOffset)
const {
103 if (!
SG::get(gctx, m_geoCtxKey, ctx).isSuccess()) {
113 : spPos + Amg::intersect<3>(posInChamb, dirInChamb, spPos, chDir).value_or(0) * chDir;
118 switch (spacePoint->
type()) {
121 + Amg::intersect<3>(spPos, chDir,
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 );
132 calibInput.setTimeOfFlight(timeOfArrival);
133 calibInput.setClosestApproach(std::move(closestApproach));
134 ATH_MSG_VERBOSE(
"Parse hit calibration "<<m_idHelperSvc->toString(dc->identify())<<
", "<<calibInput);
135 MdtCalibOutput calibOutput = m_mdtCalibrationTool->calibrate(ctx, calibInput);
140 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
141 <<std::endl<<calibInput<<std::endl<<calibOutput);
147 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos), fitState);
148 calibSP->setCovariance(
cov);
149 calibSP->setDriftRadius(calibOutput.
driftRadius());
154 calibInput.setTimeOfFlight(timeOfArrival);
156 MdtCalibInput twinInput{dc->twinIdentify(), dc->twinAdc(), dc->twinTdc(), dc->readoutElement(), *gctx};
158 twinInput.setTimeOfFlight(timeOfArrival);
161 std::move(calibInput),
162 std::move(twinInput));
166 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
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()));
175 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos), fitState);
176 calibSP->setCovariance(
cov);
185 const Amg::Transform3D toGasGap{strip->readoutElement()->globalToLocalTrans(*gctx, strip->layerHash()) * locToGlob};
188 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
192 const double time1 = strip->time()
193 - strip->readoutElement()->distanceToEdge(strip->layerHash(), lPos,
194 EdgeSide::readOut) /m_rpcSignalVelocity;
199 const double time2 = strip2->
time() -
200 strip2->readoutElement()->distanceToEdge(strip2->layerHash(),lPos, EdgeSide::readOut)/m_rpcSignalVelocity;
202 calibSP->setTimeMeasurement(0.5*(time1 + time2));
206 calibSP->setCovariance(
cov);
207 ATH_MSG_VERBOSE(
"Create rpc space point "<<m_idHelperSvc->toString(strip->identify())<<
", dimension "<<spacePoint->
dimension()
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);
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);
237 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());
245 if (cluster->channelType() != sTgcIdHelper::sTgcChannelTypes::Strip) {
246 ATH_MSG_DEBUG(
"Calibrating an sTGC Pad or wire " << m_idHelperSvc->toString(cluster->identify()));
247 calibSP = std::make_unique<CalibratedSpacePoint>(spacePoint, std::move(calibSpPos));
248 calibSP->setCovariance(
cov);
252 std::optional<double> posAlongTheStrip{std::nullopt};
257 ATH_MSG_VERBOSE(
"Using secondary measurement "<< m_idHelperSvc->toString(secMeas->identify())<<
" for sTGC strip cluster " << m_idHelperSvc->toString(cluster->identify()));
260 ATH_MSG_VERBOSE(
"No secondary measurement for sTGC strip cluster " << m_idHelperSvc->toString(cluster->identify()));
267 const auto [calibPos, calibCov] = calibratesTGC(ctx, *gctx, *stripClus, posAlongTheStrip, globalPos, globalDir);
269 ATH_MSG_DEBUG(
"Calibrated pos and cov" << calibPos <<
" " << 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());
296 const double timeOffset)
const {
300 CalibSpacePointPtr hit = calibrate(ctx, spacePoint, posInChamb, dirInChamb, timeOffset);
302 calibSpacePoints.push_back(std::move(hit));
305 return calibSpacePoints;
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 {
386 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimNoTime, cmbPos, cmbCov, sl, state);
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);
412 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimNoTime, cmbPos,
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(),
432 const EventContext* ctx = cctx.get<
const EventContext*>();
434 <<
" @ surface "<<trackState.referenceSurface().geometryId());
436 if (muonMeas->numDimensions() == 0
u) {
445 switch (muonMeas->type()){
447 case MdtDriftCircleType: {
450 calibInput.setClosestApproach(trackPos);
452 calibInput.setTrackDirection(trackDir,
true);
453 const double driftSign = m_MdtSignFromSegment ?
454 static_cast<double>(dec_trackSign(*dc)) :
455 sign(trackPars.parameters()[Acts::eBoundLoc0]);
458 if (
ATH_LIKELY(muonMeas->numDimensions() == 1)) {
459 MdtCalibOutput calibOutput = m_mdtCalibrationTool->calibrate(*ctx, calibInput);
465 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
466 <<std::endl<<calibInput<<std::endl<<calibOutput);
467 cov(Acts::eBoundLoc0,Acts::eBoundLoc0) =
std::pow(dc->readoutElement()->innerTubeRadius(), 2);
472 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
pos,
cov, link, trackState);
477 MdtCalibInput twinInput{twinDC->twinIdentify(), twinDC->twinAdc(), twinDC->twinTdc(), twinDC->readoutElement(), *gctx};
478 twinInput.setClosestApproach(trackPos);
479 twinInput.setTimeOfFlight(trackPars.parameters()[Acts::eBoundTime]);
482 std::move(calibInput),
483 std::move(twinInput));
487 ATH_MSG_DEBUG(
"Failed to create a valid hit from "<<m_idHelperSvc->toString(dc->identify())
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);
493 locCov(Acts::eBoundLoc1, Acts::eBoundLoc1) =
std::pow(calibOutput.
sigmaZ(), 2);
494 locPos[Acts::eBoundLoc0] = driftSign*calibOutput.
primaryDriftR();
495 locPos[Acts::eBoundLoc1] = calibOutput.
locZ();
497 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimNoTime, locPos, locCov, link, trackState);
500 }
case RpcStripType: {
503 if (
ATH_LIKELY(rpcClust->numDimensions() == 1)) {
506 const auto proj = rpcClust->measuresPhi() ? ProjectorType::e1DimRotNoTime
507 : ProjectorType::e1DimNoTime;
508 setState<1, ActsTrk::MutableTrackStateBackend>(
proj,
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");
517 measCov(1,1) =
std::pow(m_rpcTimeResolution, 2);
518 const auto proj = rpcClust->measuresPhi() ? ProjectorType::e1DimRotWithTime
519 : ProjectorType::e1DimWithTime;
520 setState<2, ActsTrk::MutableTrackStateBackend>(
proj,
521 measPars, measCov, link, trackState);
527 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimNoTime,
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");
536 measCov(2,2) =
std::pow(m_rpcTimeResolution, 2);
537 setState<3, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimWithTime,
538 measPars, measCov, link, trackState);
542 }
case TgcStripType: {
543 const auto* tgcClust =
static_cast<const xAOD::TgcStrip*
>(muonMeas);
545 const auto proj = tgcClust->measuresPhi() ? ProjectorType::e1DimRotNoTime
546 : ProjectorType::e1DimNoTime;
547 setState<1, ActsTrk::MutableTrackStateBackend>(
proj,
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)};
561 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
562 pos,
cov, link, trackState);
564 }
case sTgcStripType: {
567 if(stgcClust->channelType() == sTgcIdHelper::sTgcChannelTypes::Wire) {
568 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
569 muonMeas->localPosition<1>(),
570 muonMeas->localCovariance<1>(), link, trackState);
572 }
else if(stgcClust->channelType() == sTgcIdHelper::sTgcChannelTypes::Pad) {
573 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e2DimNoTime,
574 stgcClust->localPosition<2>(),
575 stgcClust->localCovariance<2>(), link, trackState);
580 std::pair<double, double> calibPosCov{calibratesTGC(*ctx, *gctx, *stgCluster, std::nullopt, trackPos, trackDir)};
584 setState<1, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimNoTime,
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");
597 setState<2, ActsTrk::MutableTrackStateBackend>(ProjectorType::e1DimWithTime,
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);