3030#include < DataFormatsParameters/GRPMagField.h>
3131#include < DetectorsBase/GeometryManager.h>
3232#include < DetectorsBase/Propagator.h>
33+ #include < Field/MagneticField.h>
3334#include < Framework/ASoA.h>
3435#include < Framework/AnalysisDataModel.h>
3536#include < Framework/AnalysisHelpers.h>
4748#include < Math/MatrixRepresentationsStatic.h>
4849#include < Math/SMatrix.h>
4950#include < Math/SVector.h>
51+ #include < TGeoGlobalMagField.h>
5052#include < TTree.h>
5153
5254#include < RtypesCore.h>
@@ -279,6 +281,8 @@ struct mftMchMatcher { // o2-linter: disable=name/struct (keep temporarily)
279281
280282 o2::parameters::GRPMagField* fGrpMag = nullptr ;
281283
284+ double mBzAtMftCenter {0 };
285+
282286 std::uniform_real_distribution<double > mDistribution {0.0 , 1.0 };
283287 std::mt19937 mGenerator ;
284288
@@ -302,6 +306,7 @@ struct mftMchMatcher { // o2-linter: disable=name/struct (keep temporarily)
302306 o2::track::TrackParCovFwd trackparCov{track.z (), tpars, tcovs, chi2};
303307 o2::dataformats::GlobalFwdTrack fwdtrack;
304308 fwdtrack.setParameters (trackparCov.getParameters ());
309+ fwdtrack.setZ (trackparCov.getZ ());
305310 fwdtrack.setCovariances (trackparCov.getCovariances ());
306311 return fwdtrack;
307312 }
@@ -422,6 +427,12 @@ struct mftMchMatcher { // o2-linter: disable=name/struct (keep temporarily)
422427 o2::base::Propagator::initFieldFromGRP (fGrpMag );
423428 VarManager::SetMagneticField (fGrpMag ->getNominalL3Field ());
424429 VarManager::SetupMuonMagField ();
430+
431+ auto * fieldB = dynamic_cast <o2::field::MagneticField*>(TGeoGlobalMagField::Instance ()->GetField ());
432+ if (fieldB) {
433+ const std::array<double , 3 > centerMft{0 , 0 , -61.4 }; // Field at center of MFT
434+ mBzAtMftCenter = fieldB->getBz (centerMft.data ());
435+ }
425436 }
426437 mRunNumber = bc.runNumber ();
427438 }
@@ -647,6 +658,42 @@ struct mftMchMatcher { // o2-linter: disable=name/struct (keep temporarily)
647658 return attempts;
648659 }
649660
661+ void propagateToZ (o2::track::TrackParCovFwd& mft, o2::dataformats::GlobalFwdTrack& muon, const double z)
662+ {
663+ auto mchTrack = mExtrap .FwdtoMCH (muon);
664+
665+ // MCH track extrapolation
666+ // The multiple scattering effect is fully associated to the MCH track
667+ // independently of the position of the matching plane
668+ constexpr float absFront = -90 .f ;
669+ constexpr float absBack = -505 .f ;
670+ if (muon.getZ () < absBack) {
671+ // the track origin is downstream of the absorber
672+ if (z > absFront) {
673+ // the destination is upstream of the absorber
674+ // full extrapolation through the absorber in the upstream direction
675+ o2::mch::TrackExtrap::extrapToVertexWithoutBranson (mchTrack, z);
676+ } else {
677+ // the destination is inside or downstream of the absorber
678+ // 1. do a full extrapolation through the absorber to estimate the MS effect
679+ o2::mch::TrackExtrap::extrapToVertexWithoutBranson (mchTrack, absFront + 0 .1f );
680+ // 2. extrapolate from there back to the destination z
681+ o2::mch::TrackExtrap::extrapToZCov (mchTrack, z);
682+ }
683+ } else {
684+ // all other cases
685+ o2::mch::TrackExtrap::extrapToZCov (mchTrack, z);
686+ }
687+
688+ auto proptrack = mExtrap .MCHtoFwd (mchTrack);
689+ muon.setParameters (proptrack.getParameters ());
690+ muon.setZ (proptrack.getZ ());
691+ muon.setCovariances (proptrack.getCovariances ());
692+
693+ // MFT extrapolation without MS effects, as they are fully included in the MCH track extrapolation
694+ mft.propagateToZhelix (z, mBzAtMftCenter );
695+ }
696+
650697 template <bool isMc, class TCOLLS , class TBCS , class TMUONS , class TMFTS , class TCOVS >
651698 void fillTable (TCOLLS const & collisions,
652699 TBCS const & bcs,
@@ -707,8 +754,7 @@ struct mftMchMatcher { // o2-linter: disable=name/struct (keep temporarily)
707754 o2::track::TrackParCovFwd mftprop = VarManager::FwdToTrackPar (mfttrack, mfttrackcov);
708755 o2::dataformats::GlobalFwdTrack muonprop = trackToGlobalFwd (muontrack, muontrack);
709756 if (cfgzMatching.value < 0 .) {
710- mftprop = VarManager::PropagateFwd (mfttrack, mfttrackcov, cfgzMatching.value );
711- muonprop = VarManager::PropagateMuon (muontrack, collision, VarManager::kToMatching );
757+ propagateToZ (mftprop, muonprop, cfgzMatching.value );
712758 }
713759 auto muonpropCov = muonprop.getCovariances ();
714760 auto mftpropCov = mftprop.getCovariances ();
0 commit comments