11 #include "GaudiKernel/ITHistSvc.h"
43 m_doCompoundLayerCheck(false)
46 , m_forceMomentum(false)
47 , m_xKalmanStraggling(false)
48 , m_useMostProbableEloss(false)
49 , m_msgOutputValidationDirection(true)
50 , m_msgOutputCorrections(false)
51 , m_validationMode(false)
52 , m_validationIgnoreUnmeasured(true)
54 , m_validationDirection(1)
58 , m_eLossUpdator(
"Trk::EnergyLossUpdator/AtlasEnergyLossUpdator")
59 , m_msUpdator(
"Trk::MultipleScatteringUpdator/AtlasMultipleScatteringUpdator")
60 , m_materialMapper(
"Trk::MaterialMapper/AtlasMaterialMapper")
62 declareInterface<IMaterialEffectsUpdator>(
this);
94 ATH_MSG_DEBUG(
"Minimal momentum cut for material update : " << m_momentumCut <<
" MeV");
98 if (m_eLossUpdator.retrieve().isFailure()) {
100 <<
". No multiple scattering effects will be taken into account.");
102 return StatusCode::FAILURE;
107 m_eLossUpdator.disable();
111 if (m_msUpdator.retrieve().isFailure()) {
113 <<
". No energy loss effects will be taken into account.");
115 return StatusCode::FAILURE;
120 m_msUpdator.disable();
124 if (m_validationMode) {
125 if (m_materialMapper.retrieve().isFailure()) {
126 ATH_MSG_FATAL(
"Failed to retrieve tool " << m_materialMapper <<
". No material recording.");
127 return StatusCode::FAILURE;
132 m_materialMapper.disable();
135 return StatusCode::SUCCESS;
139 std::unique_ptr<Trk::TrackParameters>
164 if (m_validationMode) {
167 return updateImpl(cache, parm, *mprop, pathCorrection,
dir,
particle, matupmode);
170 std::unique_ptr<Trk::TrackParameters>
188 double updateMomentum = (m_forceMomentum) ? m_forcedMomentum :
p;
190 double E = std::sqrt(
p *
p +
m *
m);
193 double pathcorrection = 1.;
195 double energyLoss = 0;
196 double energyLossSigma = 0;
205 double sigmaQoverP = 0;
206 double sigmaQoverPSq = 0;
209 if (energyLoss > 0) {
217 }
else if (m_landauMode) {
220 double qOverPnew = parm->parameters()[
Trk::qOverP];
222 if (
p > m_momentumCut &&
p < m_momentumMax && m_doEloss) {
223 double newP2 = (
E + energyLoss) * (
E + energyLoss) -
m *
m;
224 if (newP2 < m_momentumCut * m_momentumCut) {
227 if (
E + energyLoss < -
m) {
230 newP = std::sqrt(newP2);
231 sigmaQoverP = energyLossSigma / (
beta *
p *
p);
232 sigmaQoverPSq = sigmaQoverP * sigmaQoverP;
233 qOverPnew = parm->
charge() / newP;
240 AmgVector(5) updatedParameters(mpars->parameters());
241 std::optional<
AmgSymMatrix(5)> updatedCovariance = std::nullopt;
243 if (m_validationMode && !m_validationIgnoreUnmeasured) {
245 updatedCovariance = mpars->covariance()
246 ? std::optional<AmgSymMatrix(5)>(*mpars->covariance())
248 double angularVariation = 0;
249 double sigmaDeltaPhiSq = 0;
250 double sigmaDeltaThetaSq = 0;
259 angularVariation = m_msUpdator->sigmaSquare(mprop, updateMomentum, pathcorrection,
Trk::muon);
263 sigmaDeltaThetaSq = angularVariation;
267 sigmaDeltaPhiSq *= sigmaDeltaPhiSq;
269 sigmaDeltaThetaSq *= sigmaDeltaThetaSq;
275 if (updatedCovariance) {
281 if (!m_xKalmanStraggling && !m_landauMode) {
283 }
else if (m_xKalmanStraggling) {
284 }
else if (m_landauMode) {
295 if (matupmode ==
Trk::removeNoise && !checkCovariance(*updatedCovariance)) {
303 if (m_msgOutputCorrections) {
304 double sigmaAngle = std::sqrt(angularVariation);
307 ATH_MSG_VERBOSE(
" deltaP / sigmaQoverP = " << energyLoss <<
" / " << sigmaQoverP);
313 if (m_validationMode) {
330 m_materialMapper->recordMaterialHit(assMatHit, parm->
position());
353 std::unique_ptr<Trk::TrackParameters>
370 if (preFactor < 0.01) {
378 bool outputFlag = m_msgOutputValidationDirection ?
dir ==
int(m_validationDirection) :
true;
382 pathCorrection *= preFactor;
392 double eta = parm->
momentum().eta();
395 ATH_MSG_VERBOSE(
" [M] pre material update at layer with [r,z] = [ " << layerR <<
", " << layerZ <<
" ] - Index "
397 ATH_MSG_VERBOSE(
" thickness/X0 , path/X0 (eta: g.factor) = " << sX0 <<
" , " << tX0 <<
" (" << eta <<
": "
398 << pathCorrection <<
")");
401 if (m_validationMode) {
404 return updateImpl(cache, parm, *mprop, pathCorrection,
dir,
particle, matupmode);
407 std::unique_ptr<Trk::TrackParameters>
427 if (postFactor < 0.01) {
432 bool outputFlag = m_msgOutputValidationDirection ?
dir ==
int(m_validationDirection) :
true;
436 pathCorrection *= postFactor;
450 ATH_MSG_VERBOSE(
" [M] post material update, layer with [r,z] = [ " << layerR <<
", " << layerZ <<
" ] - Index "
452 ATH_MSG_VERBOSE(
" thickness/X0 , path/X0 (eta: g.factor) = " << sX0 <<
" , " << tX0 <<
" (" << eta <<
": "
453 << pathCorrection <<
")");
456 if (m_validationMode) {
459 return updateImpl(cache, parm, *mprop, pathCorrection,
dir,
particle, matupmode);
463 std::unique_ptr<Trk::TrackParameters>
468 double pathcorrection,
480 double updateMomentum = (m_forceMomentum) ? m_forcedMomentum :
p;
482 double E = std::sqrt(
p *
p +
m *
m);
486 bool outputFlag = m_msgOutputValidationDirection ?
dir ==
int(m_validationDirection) :
true;
489 if (
p > m_momentumCut &&
p < m_momentumMax) {
492 (m_doEloss) ? m_eLossUpdator->energyLoss(matprop, updateMomentum,
494 m_useMostProbableEloss)
497 double deltaE = energyLoss.
deltaE();
509 }
else if (m_landauMode) {
513 double newP2 = (
E + deltaE) * (
E + deltaE) -
m *
m;
514 if (
E + deltaE < -
m) {
517 if (newP2 < m_momentumCut * m_momentumCut) {
520 double deltaP = std::sqrt(newP2) -
p;
527 AmgVector(5) updatedParameters(mpars->parameters());
529 std::optional<
AmgSymMatrix(5)> updatedCovariance = std::nullopt;
534 ? std::optional<AmgSymMatrix(5)>(*mpars->covariance())
537 double angularVariation =
538 (m_doMs) ? m_msUpdator->sigmaSquare(matprop, updateMomentum, pathcorrection,
particle) : 0.;
540 if (updatedCovariance) {
544 double sigmaDeltaPhiSq =
546 double sigmaDeltaThetaSq = angularVariation;
550 if (!m_xKalmanStraggling && !m_landauMode) {
552 }
else if (m_xKalmanStraggling) {
556 }
else if (m_landauMode) {
565 if (matupmode ==
Trk::removeNoise && !checkCovariance(*updatedCovariance)) {
573 if (outputFlag && m_msgOutputCorrections) {
574 double sigmaAngle = std::sqrt(angularVariation);
576 <<
" / " << sigmaAngle);
577 ATH_MSG_VERBOSE(
" deltaP / sigmaQoverP = " << deltaP <<
" / " << sigmaQoverP);
599 l0 = extProperties->
l0();
614 m_materialMapper->recordMaterialHit(assMatHit, parm->
position());
632 std::move(updatedCovariance)
640 std::unique_ptr<Trk::TrackParameters>
645 double pathcorrection,
657 double updateMomentum = (m_forceMomentum) ? m_forcedMomentum :
p;
659 double E = std::sqrt(
p *
p +
m *
m);
663 bool outputFlag = m_msgOutputValidationDirection ?
dir ==
int(m_validationDirection) :
true;
666 if (
p > m_momentumCut &&
p < m_momentumMax) {
668 AmgVector(5) updatedParameters(parm.parameters());
673 ? m_eLossUpdator->energyLoss(matprop, updateMomentum, pathcorrection,
dir,
particle, m_useMostProbableEloss)
676 double deltaE = energyLoss.
deltaE() ;
688 }
else if (m_landauMode) {
692 double newP2 = (
E + deltaE) * (
E + deltaE) -
m *
m;
693 if (
E + deltaE < -
m) {
696 if (newP2 < m_momentumCut * m_momentumCut) {
699 double deltaP = std::sqrt(newP2) -
p;
705 std::optional<
AmgSymMatrix(5)> updatedCovariance = std::nullopt;
706 if (parm.covariance() || (m_validationMode && !m_validationIgnoreUnmeasured)) {
708 updatedCovariance =
AmgSymMatrix(5)(*parm.covariance());
710 double angularVariation =
711 (m_doMs) ? m_msUpdator->sigmaSquare(matprop, updateMomentum, pathcorrection,
particle) : 0.;
716 double sigmaDeltaPhiSq =
718 double sigmaDeltaThetaSq = angularVariation;
722 if (!m_xKalmanStraggling && !m_landauMode) {
724 }
else if (m_xKalmanStraggling) {
725 }
else if (m_landauMode) {
735 if (matupmode ==
Trk::removeNoise && !checkCovariance(*updatedCovariance)) {
742 if (outputFlag && m_msgOutputCorrections) {
743 double sigmaAngle = std::sqrt(angularVariation);
746 ATH_MSG_VERBOSE(
" deltaP / sigmaQoverP = " << deltaP <<
" / " << sigmaQoverP);
766 l0 = extProperties->
l0();
781 m_materialMapper->recordMaterialHit(assMatHit, parm.
position());
799 std::move(updatedCovariance)
827 ATH_MSG_DEBUG(
" [-] update material with 'removeNoise' results in negative covariance entries. Skipping update.");