From f8a8a79b1ccf568f489bc4558604e89a15c533e4 Mon Sep 17 00:00:00 2001
From: John Derek Chapman <chapman@hep.phy.cam.ac.uk>
Date: Mon, 11 Jun 2018 15:24:23 +0000
Subject: [PATCH] Merge branch 'MM_mTPC' into '21.3'

Implementation of the mTPC reconstruction for MM

See merge request atlas/athena!11776

(cherry picked from commit 937f65804e4ff852f9f9475a0b2006ca81251131)

5e0d3047 Implementation of the mTPC reconstruction for MM
3b665187 Merge remote-tracking branch 'upstream/21.3' into MM_mTPC
---
 .../src/MM_FastDigitizer.cxx                  |  99 +++++++++++----
 .../src/MM_FastDigitizer.h                    |   1 +
 .../src/MuonClusterOnTrackCreator.cxx         |  54 ++++++--
 .../src/MuonClusterOnTrackCreator.h           |   2 +
 .../MuonTrackFindingEvent/MuPatHit.h          |   2 +-
 .../src/MuonClusterSegmentFinderTool.cxx      | 118 +++++++++++++-----
 .../src/MuonClusterSegmentFinderTool.h        |   5 +-
 .../src/MuPatHitTool.cxx                      |  14 ++-
 .../src/CombinedMuonTrackBuilder.cxx          |   6 +-
 .../TrkGlobalChi2Fitter/GlobalChi2Fitter.h    |   1 +
 .../TrkGlobalChi2Fitter/src/GXFTrajectory.cxx |   3 +-
 .../src/GlobalChi2Fitter.cxx                  |  46 ++++++-
 .../src/RIO_OnTrackCreator.cxx                |   4 +-
 13 files changed, 283 insertions(+), 72 deletions(-)

diff --git a/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.cxx b/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.cxx
index 8a7718e50bd..aae0346ccde 100644
--- a/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.cxx
+++ b/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.cxx
@@ -66,6 +66,7 @@ using namespace Muon;
   declareProperty("CheckIds", m_checkIds = false,  "Turn on validity checking of Identifiers"  );
   declareProperty("MaskMultiplet", m_maskMultiplet = 0,  "0: all, 1: first, 2: second, 3: both"  );
   declareProperty("SDOname", m_sdoName = "MMfast_SDO"  );
+  declareProperty("MicroTPC", m_microTPC = true,  "Turn on microTPC mode"  );
 }
 /*******************************************************************************/ 
 MM_FastDigitizer::~MM_FastDigitizer()  {
@@ -339,7 +340,8 @@ StatusCode MM_FastDigitizer::execute() {
     double scale;//, scaletop;
 //    double gasgap = 5.;
     
-    scale = -slpos.z()/ldir.z();
+    if (m_microTPC) scale = 0;
+    else scale = -slpos.z()/ldir.z();
 //    scaletop = (gasgap+slpos.z())/ldir.z();
 
     Amg::Vector3D hitOnSurface = slpos + scale*ldir;
@@ -352,6 +354,8 @@ StatusCode MM_FastDigitizer::execute() {
     Amg::Vector3D hitAfterTimeShift(hitOnSurface.x(),hitOnSurface.y(),shiftTimeOffset);
     Amg::Vector3D hitAfterTimeShiftOnSurface = hitAfterTimeShift - (shiftTimeOffset/ldirTime.z())*ldirTime;
 
+    double tdrift = 0;
+
     // resolution = -.01/3 * angle + .64/3.
     double resolution;
     if (fabs(inAngle_XZ)<3)
@@ -372,8 +376,8 @@ StatusCode MM_FastDigitizer::execute() {
     if( fabs(inAngle_XZ) > 70 ){
       posOnSurf[0]=(slpos.x()+sp);
 //      digiMode = 1;
-      // if using timing information use hit position after m_shift
-    }else if( m_useTimeShift ){
+      // if using timing information use hit position after shift
+    }else if( m_useTimeShift && !m_microTPC ){
       posOnSurf[0]=(hitAfterTimeShiftOnSurface.x()+sp);
 //      digiMode = 2;
     }
@@ -497,23 +501,83 @@ StatusCode MM_FastDigitizer::execute() {
 
     std::vector<Identifier> rdoList;
     rdoList.push_back(id);
-    Amg::MatrixX* cov = new Amg::MatrixX(1,1);
-    cov->setIdentity();
-    (*cov)(0,0) = resolution*resolution;
-    MMPrepData* prd = new MMPrepData( id,hash,posOnSurf,rdoList,cov,detEl);
-    prd->setHashAndIndex(col->identifyHash(), col->size()); // <<< add this line to the MM code as well
-    col->push_back(prd);
+
     ATH_MSG_VERBOSE("Global hit: r " << hit.globalPosition().perp() << " phi " << hit.globalPosition().phi() << " z " << hit.globalPosition().z());
-    ATH_MSG_VERBOSE(" Prd: r " << prd->globalPosition().perp() << "  phi " << prd->globalPosition().phi() << " z " << prd->globalPosition().z());
     ATH_MSG_VERBOSE(" Calculated truth hitOnSurfaceGlobal: r " << hitOnSurfaceGlobal.perp() << " phi " << hitOnSurfaceGlobal.phi() << " z " << hitOnSurfaceGlobal.z());
     ATH_MSG_VERBOSE(" detEl: r " << repos.perp() << " phi " << repos.phi() << " z " << repos.z());
     ATH_MSG_VERBOSE(" Surface center: r " << surf.center().perp() << " phi " << surf.center().phi() << " z " << surf.center().z());
-
     ATH_MSG_VERBOSE("Local hit in Det Element Frame: x " << hit.localPosition().x() << " y " << hit.localPosition().y() << " z " << hit.localPosition().z());
-    ATH_MSG_VERBOSE(" Prd: local posOnSurf.x() " << posOnSurf.x() << " posOnSurf.y() " << posOnSurf.y() );
-    // 		    << " detEl: x " << lpos.x() << " y " << lpos.y() << " z " << lpos.z() << " strip " << stripNumber);
     ATH_MSG_DEBUG(" hit:  " << m_idHelperTool->toString(id) << " hitx " << posOnSurf.x() << " hitOnSurface.x() " << hitOnSurface.x() << " residual " << posOnSurf.x() - hitOnSurface.x()
 		  << " pull " << (posOnSurf.x() - hitOnSurface.x())/resolution );
+    Amg::Vector3D CurrentHitInDriftGap = slpos;
+    // emulating micro track in the drift volume for microTPC
+    if (!m_microTPC) {
+      Amg::MatrixX* cov = new Amg::MatrixX(1,1);
+      cov->setIdentity();
+      (*cov)(0,0) = resolution*resolution;
+      MMPrepData* prd = new MMPrepData( id,hash,Amg::Vector2D(posOnSurf.x(),0.),rdoList,cov,detEl,(int)tdrift,0);
+      prd->setHashAndIndex(col->identifyHash(), col->size()); // <<< add this line to the MM code as well
+      col->push_back(prd);
+
+      std::vector<MuonSimData::Deposit> deposits;
+      MuonSimData::Deposit deposit(hit.particleLink(), MuonMCData(hitOnSurface.x(),hitOnSurface.y()));
+      deposits.push_back(deposit);
+
+      MuonSimData simdata(deposits,0);
+      simdata.setPosition(hitOnSurfaceGlobal);
+      simdata.setTime(m_globalHitTime);
+      h_sdoContainer->insert ( std::make_pair ( id, simdata ) );
+
+      ATH_MSG_VERBOSE(" Prd: local x " << posOnSurf.x() << " y " << 0 );
+      ATH_MSG_VERBOSE(" Prd: r " << prd->globalPosition().perp() << "  phi " << prd->globalPosition().phi() << " z " << prd->globalPosition().z());
+    } else {
+      for (int loop_direction = -1; loop_direction <=1; loop_direction+=2) {
+        Amg::Vector3D stepInDriftGap = loop_direction * ldir * (roParam.stripPitch/std::cos(roParam.stereoAngel.at(m_idHelper->gasGap(layid)-1) ))/abs(ldir.x());
+        if (loop_direction == 1) CurrentHitInDriftGap = slpos + stepInDriftGap;
+        while (std::abs(CurrentHitInDriftGap.z()) <= roParam.gasThickness) {
+          Amg::MatrixX* cov = new Amg::MatrixX(1,1);
+          cov->setIdentity();
+          (*cov)(0,0) = resolution*resolution;
+
+          tdrift = CurrentHitInDriftGap.z() / vdrift + CLHEP::RandGauss::shoot(m_rndmEngine, 0., 5.);
+          Amg::Vector2D CurrenPosOnSurf(CurrentHitInDriftGap.x(),CurrentHitInDriftGap.y());
+
+          stripNumber = detEl->stripNumber(CurrenPosOnSurf,layid);
+          if( (stripNumber >= detEl->numberOfStrips(layid)) || (stripNumber == -1) ) {
+            CurrentHitInDriftGap += stepInDriftGap;
+            continue;
+          }
+          id = m_idHelper->channelID(parentID, m_idHelper->multilayer(layid), m_idHelper->gasGap(layid),stripNumber,m_checkIds);
+          if( stripNumber != m_idHelper->channel(id) ) {
+            CurrentHitInDriftGap += stepInDriftGap;
+            continue;
+          }
+        
+          MMPrepData* prd = new MMPrepData( id,hash,Amg::Vector2D(CurrenPosOnSurf.x(),0.),rdoList,cov,detEl,(int)tdrift,0);
+          prd->setHashAndIndex(col->identifyHash(), col->size()); // <<< add this line to the MM code as well
+          col->push_back(prd);
+
+          std::vector<MuonSimData::Deposit> deposits;
+          MuonSimData::Deposit deposit(hit.particleLink(), MuonMCData(CurrenPosOnSurf.x(),CurrenPosOnSurf.y()));
+          deposits.push_back(deposit);
+
+          MuonSimData simdata(deposits,0);
+          Amg::Vector3D SDO_GP = surf.transform()*CurrentHitInDriftGap;
+          simdata.setPosition(SDO_GP);
+          simdata.setTime(m_globalHitTime);
+          h_sdoContainer->insert ( std::make_pair ( id, simdata ) );
+
+          ATH_MSG_VERBOSE(" Local CurrentHitInDriftGap.x() " << CurrentHitInDriftGap.x() << " CurrentHitInDriftGap.y() " << CurrentHitInDriftGap.y() << " CurrentHitInDriftGap.z() " << CurrentHitInDriftGap.z() << " drift time " << (int)tdrift );
+          ATH_MSG_VERBOSE(" Prd: local x " << CurrentHitInDriftGap.x() << " y " << 0 << " drift time " << (int)tdrift << " identifier " << id );
+          ATH_MSG_VERBOSE(" Prd: r " << prd->globalPosition().perp() << "  phi " << prd->globalPosition().phi() << " z " << prd->globalPosition().z());
+          ATH_MSG_VERBOSE(" SDO: True Global position: x  " << SDO_GP.x() << "  y " << SDO_GP.y() << " z " << SDO_GP.z());
+
+          CurrentHitInDriftGap += stepInDriftGap;
+        }
+      }
+    }
+
+
     m_err = resolution;
     m_ich = m_idHelper->channel(id);
     m_istr  = stripNumber;
@@ -526,15 +590,6 @@ StatusCode MM_FastDigitizer::execute() {
 //     }
 
     m_ntuple->Fill();
-    // create SDO 
-    MuonSimData::Deposit deposit(hit.particleLink(), MuonMCData(hitOnSurface.x(),hitOnSurface.y()));
-    //Record the SDO collection in StoreGate
-    std::vector<MuonSimData::Deposit> deposits;
-    deposits.push_back(deposit);
-    MuonSimData simData(deposits, 0);
-    simData.setPosition(hitOnSurfaceGlobal);
-    simData.setTime(m_globalHitTime);
-    h_sdoContainer->insert ( std::make_pair ( id, simData ) );
     // OLD CODE ENDS HERE
 
     previousHit = &hit;
diff --git a/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.h b/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.h
index 01837dbc834..d75c16fad84 100644
--- a/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.h
+++ b/MuonSpectrometer/MuonDigitization/MuonFastDigitization/src/MM_FastDigitizer.h
@@ -133,6 +133,7 @@ class MM_FastDigitizer : public AthAlgorithm {
   double m_energyThreshold;
   bool   m_checkIds;
   int    m_maskMultiplet;
+  bool   m_microTPC;
 };
 
 #endif // MUONDIGITIZATION_MM_DIGITIZER_H
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.cxx b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.cxx
index 09992546baa..51cd718907d 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.cxx
@@ -69,6 +69,7 @@ namespace Muon {
     declareProperty("FixedErrorTgcPhi", m_fixedErrorTgcPhi = 5. );
     declareProperty("FixedErrorRpcPhi", m_fixedErrorRpcPhi = 5. );
     declareProperty("FixedErrorCscPhi", m_fixedErrorCscPhi = 5. );
+    declareProperty("eDriftVelocityMM", m_eDriftVelocityMM = 0.047 );
   }
 
 
@@ -113,7 +114,7 @@ namespace Muon {
 
 
   const MuonClusterOnTrack* MuonClusterOnTrackCreator::createRIO_OnTrack(const Trk::PrepRawData& RIO,
-									 const Amg::Vector3D& GP) const
+									 const Amg::Vector3D& GP, const Amg::Vector3D& GD) const
 
   {
     MuonClusterOnTrack* MClT = 0;
@@ -320,13 +321,52 @@ namespace Muon {
       MClT = new CscClusterOnTrack(MClus,locpar,loce,positionAlongStrip,MClus->status(),MClus->timeStatus());
 
     }else if( m_idHelper->isMM(RIO.identify()) ){
-      // cast to CscPrepData
+      // cast to MMPrepData
       const MMPrepData* MClus   = dynamic_cast<const MMPrepData*> (&RIO);
       if (!MClus) {
 	ATH_MSG_WARNING ( "RIO not of type MMPrepData, cannot create ROT" );
 	return 0;
       }
-      
+
+      Amg::Vector2D lposMM = MClus->localPosition();
+
+      double tOffset = 0.0;
+      double zshift = m_eDriftVelocityMM * (MClus->time() - tOffset);
+
+      ATH_MSG_DEBUG( " Drift time " << MClus->time() << " zshift " << zshift);
+      if (zshift<-5.05) {
+        ATH_MSG_WARNING( "Invalid drift time: zshift " << zshift << " while volume size 10: [-5;5]. Set zshift = -5.05");
+	zshift = -5.05;
+      } else if (zshift>5.) {
+        ATH_MSG_WARNING( "Invalid drift time: zshift " << zshift << " while volume size 10: [-5;5]. Set zshift = 5.05");
+	zshift = 5.05;
+      }
+      ATH_MSG_DEBUG( " MM Prepdata pos locX " << lposMM[0] << " locY " << lposMM[1] << " and zshift " << zshift);
+
+      Amg::Vector3D lposTrack = RIO.detectorElement()->surface(RIO.identify()).transform().inverse()*GP;
+      Amg::Vector3D GPinGasGap = GP + Amg::Vector3D(0.,0.,zshift);
+      Amg::Vector3D GPshifted = GPinGasGap;
+      if (std::abs(GD.z()) > 0.000001)
+        GPshifted-= zshift*GD/GD.z();
+      else
+        ATH_MSG_WARNING ( "GD.z() is 0, mTPC correction cannot be done" );;
+
+      ATH_MSG_DEBUG( " GD x " << GD.x() << " y " << GD.y() << " z " << GD.z());
+      ATH_MSG_DEBUG( " GP x " << GP.x() << " y " << GP.y() << " z " << GP.z());
+      ATH_MSG_DEBUG( " GPshifted x " << GPshifted.x() << " y " << GPshifted.y() << " z " << GPshifted.z());
+
+      ATH_MSG_DEBUG( " lposTrack x " << lposTrack.x() << " y " << lposTrack.y() << " z " << lposTrack.z());
+      Amg::Vector3D lposTrackShifted = RIO.detectorElement()->surface(RIO.identify()).transform().inverse()*GPshifted;
+      ATH_MSG_DEBUG( " lposTrackShifted x " << lposTrackShifted.x() << " y " << lposTrackShifted.y() << " z " << lposTrackShifted.z());
+      double locXshift = lposTrackShifted.x() - lposTrack.x();
+      double locYshift = lposTrackShifted.y() - lposTrack.y();
+      ATH_MSG_DEBUG( " MM ClusterOnTrack locXshift " << locXshift);
+
+      ATH_MSG_DEBUG( " MM ClusterOnTrack old pos locX " << locpar[Trk::locX] << " Old position along strip " << positionAlongStrip);
+      positionAlongStrip += locYshift;
+      locpar[Trk::locX] = lposMM[0] + locXshift;
+      ATH_MSG_DEBUG( " MM ClusterOnTrack new pos locX " << locpar[Trk::locX] << " New position along strip " << positionAlongStrip);
+
       MClT = new MMClusterOnTrack(MClus,locpar,loce,positionAlongStrip);
 
     }else if( m_idHelper->issTgc(RIO.identify()) ){
@@ -345,13 +385,13 @@ namespace Muon {
   }  
 
   const MuonClusterOnTrack* MuonClusterOnTrackCreator::
-  createRIO_OnTrack(const Trk::PrepRawData& RIO, const Amg::Vector3D& GP,
-		    const Amg::Vector3D&) const {
-    return createRIO_OnTrack(RIO,GP);
+  createRIO_OnTrack(const Trk::PrepRawData& RIO, const Amg::Vector3D& GP) const {
+    const Amg::Vector3D GD = GP;
+    return createRIO_OnTrack(RIO,GP,GD);
   }
 
   const MuonClusterOnTrack* MuonClusterOnTrackCreator::correct(const Trk::PrepRawData& RIO,const Trk::TrackParameters& TP) const 
   {
-    return createRIO_OnTrack(RIO,TP.position());
+    return createRIO_OnTrack(RIO,TP.position(),TP.momentum());
   }
 }
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.h b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.h
index 9188c2db3c1..f047899d614 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonRIO_OnTrackCreators/MuonClusterOnTrackCreator/src/MuonClusterOnTrackCreator.h
@@ -108,6 +108,8 @@ namespace Muon {
     double                               m_fixedErrorTgcPhi;
     double                               m_fixedErrorRpcPhi;
     double                               m_fixedErrorCscPhi;
+
+    double                               m_eDriftVelocityMM;
   };
 }
 #endif // MuonClusterOnTrackCreator_H
diff --git a/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonTrackFindingEvent/MuonTrackFindingEvent/MuPatHit.h b/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonTrackFindingEvent/MuonTrackFindingEvent/MuPatHit.h
index 1cad2f89aac..7ad98733021 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonTrackFindingEvent/MuonTrackFindingEvent/MuPatHit.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonRecEvent/MuonTrackFindingEvent/MuonTrackFindingEvent/MuPatHit.h
@@ -19,7 +19,7 @@ namespace Muon {
 
   class MuPatHit {
   public:
-    enum Type   { UnknownType = -1, MDT = 0, RPC = 1, TGC = 2, CSC = 3, PREC = 4, Pseudo = 5, Scatterer = 6 };
+    enum Type   { UnknownType = -1, MDT = 0, RPC = 1, TGC = 2, CSC = 3, MM = 4, sTGC = 5, PREC = 6, Pseudo = 7, Scatterer = 8 };
     enum Status { UnknownStatus = -1, OnTrack = 0, Outlier, NotOnTrack };
     enum HitSelection { UnknownSelection = -1, Precise = 0, Broad = 1 };
     
diff --git a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.cxx
index f7eb4d7dc60..19d277c9b50 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.cxx
@@ -8,6 +8,7 @@
 #include "MuonReadoutGeometry/sTgcReadoutElement.h"
 #include "MuonReadoutGeometry/MuonPadDesign.h"
 #include "MuonPrepRawData/sTgcPrepData.h"
+#include "MuonPrepRawData/MMPrepData.h"
 #include "TrkTrack/Track.h"
 #include "TrkParameters/TrackParameters.h"
 #include "TrkEventPrimitives/FitQuality.h"
@@ -60,7 +61,7 @@ namespace Muon {
 
   std::vector<const Muon::MuonSegment*>* MuonClusterSegmentFinderTool::find(std::vector< const Muon::MuonClusterOnTrack* >& muonClusters) {
     ATH_MSG_DEBUG("Entering MuonClusterSegmentFinderTool with " << muonClusters.size() << " clusters to be fit" );
-    if(muonClusters.size() < 4) return 0;
+    if(belowThreshold(muonClusters,4)) return 0;
     std::vector<const Muon::MuonSegment*>* segs = findPrecisionSegments(muonClusters);
     if(segs == 0) return 0;
     if(segs->size() == 0)
@@ -85,7 +86,7 @@ namespace Muon {
     bool selectPhiHits(false);
     std::vector< const Muon::MuonClusterOnTrack* > clusters = cleanClusters(muonClusters,selectPhiHits);
     ATH_MSG_VERBOSE("After hit cleaning, there are " << clusters.size() << " 2D clusters to be fit" );
-    if(clusters.size() < 4){
+    if(belowThreshold(clusters,4)){
       return 0;
     }
     
@@ -101,9 +102,9 @@ namespace Muon {
     std::vector< const Muon::MuonClusterOnTrack* > rioVecPrevious;
     //find all clusters near the seed and try to fit
     for(unsigned int i=0; i<seeds.size(); ++i) {
-      std::vector< const Muon::MuonClusterOnTrack* > rioVec = getClustersOnSegment(orderedClusters,seeds[i]);
+      std::vector< const Muon::MuonClusterOnTrack* > rioVec = getClustersOnSegment(orderedClusters,seeds[i],false);
 //  make consistent cut
-      if(rioVec.size() <4) continue;
+      if(belowThreshold(rioVec,4)) continue;
       // logic to reduce combinatorics
       if(rioVec.size() == rioVecPrevious.size()) {
          bool sameContent = true;
@@ -264,8 +265,9 @@ namespace Muon {
 										      std::vector<const Muon::MuonSegment*>* etaSegs) const {
     bool selectPhiHits(true);
     std::vector< const Muon::MuonClusterOnTrack* > clusters = cleanClusters(muonClusters,selectPhiHits);
+    std::vector< const Muon::MuonClusterOnTrack* > etaClusters = cleanClusters(muonClusters,false);
     ATH_MSG_DEBUG("After hit cleaning, there are " << clusters.size() << " 3D clusters to be fit" );
-    if(clusters.size() < 4) {
+    if(belowThreshold(clusters,4)) {
       ATH_MSG_DEBUG("Not enough phi hits present, cannot perform the fit!");
       return etaSegs;
     }
@@ -273,7 +275,8 @@ namespace Muon {
     TrackCollection* segTrkColl = new TrackCollection;
     //order the clusters by layer
     bool useWires(true);
-    std::vector< std::vector<const Muon::MuonClusterOnTrack*> > orderedClusters = orderByLayer(clusters,useWires);    
+    std::vector< std::vector<const Muon::MuonClusterOnTrack*> > orderedClusters = orderByLayer(clusters,useWires);
+    std::vector< std::vector<const Muon::MuonClusterOnTrack*> > orderedEtaClusters = orderByLayer(etaClusters,false);
     if(orderedClusters.size() == 0) {
       ATH_MSG_DEBUG( "No phi wire hits found ... moving to pads" );
       useWires = false;
@@ -326,7 +329,8 @@ namespace Muon {
 	  seed3D = seeds[i];
 	}
 	
-	std::vector< const Muon::MuonClusterOnTrack* > phiHits = getClustersOnSegment(orderedClusters,seed3D);
+	std::vector< const Muon::MuonClusterOnTrack* > phiHits = getClustersOnSegment(orderedClusters,seed3D,true);
+	std::vector< const Muon::MuonClusterOnTrack* > etaHitsRedone = getClustersOnSegment(orderedEtaClusters,seed3D,true);
 	if(phiHits.size() < 2) {
           delete startpar;
           continue;
@@ -352,8 +356,15 @@ namespace Muon {
 	//interleave the phi hits
 	std::vector<const Trk::MeasurementBase*> vec2;
 	const std::vector<const Trk::RIO_OnTrack*> etaHits = (*sit)->containedROTs();
-	if(m_ipConstraint) vec2.reserve(phiHits.size()+etaHits.size()+1);
-	else vec2.reserve(phiHits.size()+etaHits.size());
+        bool useEtaHitsRedone = false;
+        if(etaHitsRedone.size()>etaHits.size()) {
+          ATH_MSG_VERBOSE(" Found additional eta hits " << etaHitsRedone.size() - etaHits.size());  
+          useEtaHitsRedone = true;
+        }
+        unsigned int netas = etaHits.size();
+        if(useEtaHitsRedone) netas = etaHitsRedone.size();
+	if(m_ipConstraint) vec2.reserve(phiHits.size()+netas+1);
+	else vec2.reserve(phiHits.size()+netas);
 
 	// pseudo measurement for vtx
 	Trk::PseudoMeasurementOnTrack* pseudoVtx = nullptr;
@@ -378,10 +389,14 @@ namespace Muon {
 	    iPhi++;
 	  }
 	  else {
-	    vec2.push_back(etaHits[iEta]);
+	    if(!useEtaHitsRedone) {
+              vec2.push_back(etaHits[iEta]);
+            } else {
+              vec2.push_back(etaHitsRedone[iEta]);
+            }
             iEta++;
 	  }
-	  if( iEta >= etaHits.size() && iPhi >= phiHits.size() ) break;
+	  if( iEta >= netas && iPhi >= phiHits.size() ) break;
 	}
 
 	
@@ -584,30 +599,62 @@ namespace Muon {
   }
 
   std::vector< const Muon::MuonClusterOnTrack* > MuonClusterSegmentFinderTool::getClustersOnSegment(std::vector< std::vector<const Muon::MuonClusterOnTrack*> >& clusters, 
-												    std::pair<Amg::Vector3D,Amg::Vector3D>& seed) const {
+												    std::pair<Amg::Vector3D,Amg::Vector3D>& seed, bool tight) const {
     ATH_MSG_VERBOSE(" getClustersOnSegment: layers " << clusters.size()  );
     std::vector< const Muon::MuonClusterOnTrack* > rios;
     int layer = 0;
     for(std::vector<std::vector<const Muon::MuonClusterOnTrack*> >::const_iterator cvecIt=clusters.begin(); cvecIt!=clusters.end(); ++cvecIt) {
       const Muon::MuonClusterOnTrack* rio = 0;      
       double bestDist(9999.);      
-      for(std::vector< const Muon::MuonClusterOnTrack* >::const_iterator cit=(*cvecIt).begin(); cit!=(*cvecIt).end(); ++cit) {
-	double dist = clusterDistanceToSeed( *cit, seed);
-	double error = Amg::error((*cit)->localCovariance(),Trk::locX);
-	if(m_idHelperTool->isMM((*cit)->identify())) error += 25.;
-	ATH_MSG_VERBOSE(" lay " << layer << " dist " << dist << " pull " << dist/error
+      double bestTimeDist(9999.);
+      if (m_idHelperTool->isMM((*((*cvecIt).begin()))->identify())) {  // MM specific algorithm
+        for(std::vector< const Muon::MuonClusterOnTrack* >::const_iterator cit=(*cvecIt).begin(); cit!=(*cvecIt).end(); ++cit) {
+	  double tdrift = (dynamic_cast<const MMPrepData *>((*cit)->prepRawData()))->time();
+	  double dist = clusterDistanceToSeed( *cit, seed);
+	  double timedist = std::abs(clusterDistanceToSeed( *cit, seed)) + std::abs(tdrift*0.015); // std::abs(tdrift*0.015) is an ad hoc penalty factor, to be optimised when time resolution is known
+	  double error = Amg::error((*cit)->localCovariance(),Trk::locX);
+	  if (!tight) error += 1.;
+	  ATH_MSG_VERBOSE(" lay " << layer << " tdrift " << tdrift << " dist " << dist  << " timedist " << timedist << " pull " << dist/error
 			<< " cut " << m_maxClustDist << "  " << m_idHelperTool->toString((*cit)->identify()) );
-	if( fabs(dist/error) < m_maxClustDist) {
-	  if(fabs(dist) < bestDist) {
-	    bestDist = fabs(dist);
-	    rio = (*cit);
-	  }
-	}	 
-      }
-      if(rio) {
-	ATH_MSG_VERBOSE(" adding  " << bestDist << "  " << m_idHelperTool->toString(rio->identify()) );
-	rios.push_back( rio );
-      }else{
+	  if( std::abs(dist/error) < m_maxClustDist) {
+	    if(std::abs(timedist) < bestTimeDist) {
+	      bestTimeDist = std::abs(timedist);
+	      bestDist = dist;
+	    }
+	  }	 
+        }
+        if(bestDist<9999.) {  // check if at least one cluster present close to seed 
+	  ATH_MSG_VERBOSE(" Best distance " << bestDist);
+	  ATH_MSG_VERBOSE(" Looking for RIOs from mTPC around the best distance");
+          for(std::vector< const Muon::MuonClusterOnTrack* >::const_iterator cit=(*cvecIt).begin(); cit!=(*cvecIt).end(); ++cit) {
+	    double dist = clusterDistanceToSeed( *cit, seed);
+	    double window = std::abs(2.*5.*0.047 * ((*cit)->globalPosition().perp() / (*cit)->globalPosition().z()));  // all hits in the range [bestDist-window;bestDist-window] will be accepted; 2-safety factor; 5-time resolution; 0.047-drift velocity; (hardcoded values to be removed once time resolution model is known) 
+	    double error = Amg::error((*cit)->localCovariance(),Trk::locX);
+	    if (!tight) error += 1.;
+	    ATH_MSG_VERBOSE(" Current RIO : distance " << dist << " window " << window << " to be attached " << ( (std::abs(std::abs(dist)-bestDist) < window) && (std::abs(dist/error) < m_maxClustDist) ) );
+	    if( (std::abs(dist-bestDist) < window) && (std::abs(dist/error) < m_maxClustDist) ) {
+	      rios.push_back( (*cit) );
+	      ATH_MSG_VERBOSE(" adding  " << dist << "  " << m_idHelperTool->toString((*cit)->identify()) );
+	    }	 
+          }
+        }
+      } else {  // algorithm for all the technoligies but MM
+        for(std::vector< const Muon::MuonClusterOnTrack* >::const_iterator cit=(*cvecIt).begin(); cit!=(*cvecIt).end(); ++cit) {
+	  double dist = clusterDistanceToSeed( *cit, seed);
+	  double error = Amg::error((*cit)->localCovariance(),Trk::locX);
+	  ATH_MSG_VERBOSE(" lay " << layer << " dist " << dist << " pull " << dist/error
+			<< " cut " << m_maxClustDist << "  " << m_idHelperTool->toString((*cit)->identify()) );
+	  if( std::abs(dist/error) < m_maxClustDist) {
+	    if(std::abs(dist) < bestDist) {
+	      bestDist = std::abs(dist);
+	      rio = (*cit);
+	    }
+	  }	 
+        }
+        if(rio) {
+	  ATH_MSG_VERBOSE(" adding  " << bestDist << "  " << m_idHelperTool->toString(rio->identify()) );
+	  rios.push_back( rio );
+        }
       }
       ++layer;
     }    
@@ -866,5 +913,20 @@ namespace Muon {
     return phiOverlap;
   }
 
+  bool MuonClusterSegmentFinderTool::belowThreshold(std::vector< const Muon::MuonClusterOnTrack* >& muonClusters, int threshold) const {
+    int n_surf_with_hits = 0;
+    if (muonClusters.size()>1) {
+      for(std::vector< const Muon::MuonClusterOnTrack* >::const_iterator cit=muonClusters.begin()+1; cit!=muonClusters.end(); cit++){  
+        if ((*cit) && (*(cit-1))) {
+          if ((*cit)->detectorElement()->center((*cit)->identify()) != (*(cit-1))->detectorElement()->center((*(cit-1))->identify())) {
+            n_surf_with_hits++;
+          }
+        }
+      }
+    } else 
+      n_surf_with_hits = muonClusters.size();
+    if(n_surf_with_hits < threshold) return true;
+    else return false;
+  }
 
 }//end namespace
diff --git a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.h b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.h
index e53b30c7f55..289d5f2fa7b 100755
--- a/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.h
+++ b/MuonSpectrometer/MuonReconstruction/MuonSegmentMakers/MuonSegmentMakerTools/DCMathSegmentMaker/src/MuonClusterSegmentFinderTool.h
@@ -77,11 +77,14 @@ namespace Muon {
     std::vector<std::pair<double,double> > getPadPhiOverlap(std::vector< std::vector<const Muon::MuonClusterOnTrack*> >& pads) const;
     //associate clusters to the segment seeds
     std::vector< const Muon::MuonClusterOnTrack* > getClustersOnSegment(std::vector< std::vector<const Muon::MuonClusterOnTrack*> >& clusters, 
-									std::pair<Amg::Vector3D,Amg::Vector3D>& seed) const;
+									std::pair<Amg::Vector3D,Amg::Vector3D>& seed, bool tight) const;
     //distance of cluster to segment seed
     double clusterDistanceToSeed(const Muon::MuonClusterOnTrack* clust, std::pair<Amg::Vector3D,Amg::Vector3D>& seed) const;
     Amg::Vector3D intersectPlane( const Trk::PlaneSurface& surf, const Amg::Vector3D& pos, const Amg::Vector3D& dir ) const;
     Trk::Track* fit( const std::vector<const Trk::MeasurementBase*>& vec2, const Trk::TrackParameters& startpar ) const;
+
+    //check if enough surfaces are hitted
+    bool belowThreshold(std::vector< const Muon::MuonClusterOnTrack* >& muonClusters, int threshold) const;
   };
   
   
diff --git a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx
index e08230638c1..960ce343624 100644
--- a/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx
+++ b/MuonSpectrometer/MuonReconstruction/MuonTrackMakers/MuonTrackMakerTools/MuonTrackSteeringTools/src/MuPatHitTool.cxx
@@ -400,6 +400,8 @@ namespace Muon {
     else if( m_idHelperTool->isTgc(id) ) return MuPatHit::TGC;
     else if( m_idHelperTool->isCsc(id) ) return MuPatHit::CSC;
     else if( m_idHelperTool->isRpc(id) ) return MuPatHit::RPC;
+    else if( m_idHelperTool->isMM(id) ) return MuPatHit::MM;
+    else if( m_idHelperTool->issTgc(id) ) return MuPatHit::sTGC;
     else if( m_idHelperTool->isMuon(id) ) return MuPatHit::PREC;
     return MuPatHit::UnknownType;
   }
@@ -414,7 +416,7 @@ namespace Muon {
     if( hitInfo.id.is_valid() && m_idHelperTool->isMuon(hitInfo.id) ) {
       hitInfo.type = getHitType(hitInfo.id);
       hitInfo.measuresPhi = m_idHelperTool->measuresPhi(hitInfo.id);
-      if( hitInfo.type != MuPatHit::MDT  ) hitInfo.id = m_idHelperTool->layerId(hitInfo.id);
+      if( hitInfo.type != MuPatHit::MDT && hitInfo.type != MuPatHit::MM ) hitInfo.id = m_idHelperTool->layerId(hitInfo.id);
     }
   }
 
@@ -479,7 +481,7 @@ namespace Muon {
 	// if we reached the end of the list, insert the hit at the end
 	if( pos == list.end() ) {
 	  // check whether hit duplicate of last hit in list
-	  if( isLargerCal(list.back(),hit) != isLargerCal(hit,list.back()) ){
+	  if( isLargerCal(list.back(),hit) != isLargerCal(hit,list.back()) || (hit->info().type == MuPatHit::MM && hit->info().id != list.back()->info().id) ){
 	    ATH_MSG_VERBOSE(" inserting hit at back   " << m_idHelperTool->toString(hit->info().id) 
 				   << " " << m_printer->print(hit->parameters()) );
   	    list.push_back(hit);
@@ -502,7 +504,7 @@ namespace Muon {
       // if we reached the first list item, check whether current hit is smaller. If so insert before first.
       if( pos == list.begin() && !isLarger  ){
 	// check whether hit duplicate of last hit in list
-	if( isLargerCal(list.front(),hit) != isLargerCal(hit,list.front()) ){
+	if( isLargerCal(list.front(),hit) != isLargerCal(hit,list.front()) || (hit->info().type == MuPatHit::MM && hit->info().id != list.front()->info().id) ){
 	  ATH_MSG_VERBOSE(" inserting hit at front  " << m_idHelperTool->toString(hit->info().id) 
 				 << " " << m_printer->print(hit->parameters()) );
  
@@ -521,7 +523,7 @@ namespace Muon {
       ++pos;
       if( pos == list.end() ) {
 	// check whether hit duplicate of last hit in list
-	if( isLargerCal(list.back(),hit) != isLargerCal(hit,list.back()) ){
+	if( isLargerCal(list.back(),hit) != isLargerCal(hit,list.back()) || (hit->info().type == MuPatHit::MM && hit->info().id != list.back()->info().id) ){
 	  ATH_MSG_VERBOSE(" inserting hit at back   " << m_idHelperTool->toString(hit->info().id) 
 				 << " " << m_printer->print(hit->parameters()) ); 
  	  list.push_back(hit);
@@ -539,7 +541,7 @@ namespace Muon {
     // remove duplicates
 
     // check whether hit and entry at pos are a duplicate
-    if( isLarger == isLargerCal(*pos,hit) ){
+    if( isLarger == isLargerCal(*pos,hit) && (hit->info().type != MuPatHit::MM || hit->info().id == (*pos)->info().id) ){
       // hit is a duplicate
       ATH_MSG_VERBOSE(" NOT inserting duplicate hit  " << m_idHelperTool->toString(hit->info().id) 
 			     << " " << m_printer->print(hit->parameters()) );
@@ -551,7 +553,7 @@ namespace Muon {
       --pos; // move to previous hit
 
       // check whether hit and entry at pos are a duplicate
-      if( isLargerCal(hit,*pos) == isLargerCal(*pos,hit) ){
+      if( isLargerCal(hit,*pos) == isLargerCal(*pos,hit) && (hit->info().type != MuPatHit::MM || hit->info().id == (*pos)->info().id) ){
 	++pos; // move forward to insert position for pos
 	// hit is a duplicate
 	ATH_MSG_VERBOSE(" NOT inserting duplicate hit  " << m_idHelperTool->toString(hit->info().id) 
diff --git a/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx b/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx
index 5a8dfd45d4f..f3d786d251f 100755
--- a/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx
+++ b/Reconstruction/MuonIdentification/MuidTrackBuilder/src/CombinedMuonTrackBuilder.cxx
@@ -3255,7 +3255,8 @@ CombinedMuonTrackBuilder::appendSelectedTSOS(
 	    if (previousSurface
 		&& std::find(measurementSurfaces.begin(),
 			     measurementSurfaces.end(),
-			     surface) != measurementSurfaces.end())	
+			     surface) != measurementSurfaces.end()
+		&& !m_idHelperTool->isMM(surface->associatedDetectorElementIdentifier()))	
 	    {
 		std::string type	 = "";
 		if (dynamic_cast<const Trk::CompetingRIOsOnTrack*>((**s).measurementOnTrack()))
@@ -4088,7 +4089,8 @@ CombinedMuonTrackBuilder::createSpectrometerTSOS(const Trk::Track& spectrometerT
 		if (previousSurface
 		    && std::find(measurementSurfaces.begin(),
 				 measurementSurfaces.end(),
-				 surface) != measurementSurfaces.end())
+				 surface) != measurementSurfaces.end()
+		    && !m_idHelperTool->isMM(surface->associatedDetectorElementIdentifier()))
 		{
 		    std::string type	 = "";
 		    if (dynamic_cast<const Trk::CompetingRIOsOnTrack*>((**s).measurementOnTrack()))
diff --git a/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h b/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h
index ee2674d2bd9..5248b04db46 100755
--- a/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h
+++ b/Tracking/TrkFitter/TrkGlobalChi2Fitter/TrkGlobalChi2Fitter/GlobalChi2Fitter.h
@@ -293,6 +293,7 @@ private:
   mutable std::vector<const Trk::Layer*> m_barrelcylinders;
   mutable std::vector<const Trk::Layer*> m_othercylinders;
   mutable bool m_fastmat;
+  mutable int m_MMCorrectionStatus;
 };
 
 //std::vector<CLHEP::HepMatrix> Trk::GlobalChi2Fitter::m_derivpool;
diff --git a/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GXFTrajectory.cxx b/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GXFTrajectory.cxx
index dd2e8609d3f..242693cd8f7 100644
--- a/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GXFTrajectory.cxx
+++ b/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GXFTrajectory.cxx
@@ -173,7 +173,8 @@ namespace Trk {
       const MeasurementBase *meas = m_states.back()->measurement();
       const MeasurementBase *meas2 = state->measurement();
       if (&meas->associatedSurface() == &meas2->associatedSurface() &&
-          meas->localParameters().parameterKey() == meas2->localParameters().parameterKey()) {
+          meas->localParameters().parameterKey() == meas2->localParameters().parameterKey() &&
+          state->measurementType() != TrackState::MM) {
         delete state;
         return false;
       }
diff --git a/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx b/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx
index 9b1cefe2495..4d19e16425c 100644
--- a/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx
+++ b/Tracking/TrkFitter/TrkGlobalChi2Fitter/src/GlobalChi2Fitter.cxx
@@ -143,7 +143,8 @@ namespace Trk {
     m_updatescat{},
     m_useCaloTG(false),
     m_caloMaterialProvider("Trk::TrkMaterialProviderTool/TrkMaterialProviderTool"),
-    m_rejectLargeNScat(false){
+    m_rejectLargeNScat(false),
+    m_MMCorrectionStatus(0){
     // tools and services
     declareProperty("ExtrapolationTool", m_extrapolator);
     declareProperty("MeasurementUpdateTool", m_updator);
@@ -2238,7 +2239,48 @@ namespace Trk {
     MeasurementSet::const_iterator itSet = rots.begin();
     MeasurementSet::const_iterator itSetEnd = rots.end();
     GXFTrajectory trajectory;
-    for (; itSet != itSetEnd; ++itSet) {
+
+    if (m_MMCorrectionStatus==0) {
+      for (itSet = rots.begin(); itSet != itSetEnd; ++itSet) {
+        if ((*itSet)) {
+          if (m_DetID->is_mm((*itSet)->associatedSurface().associatedDetectorElementIdentifier())) {
+            m_MMCorrectionStatus = 1;
+            break;
+          }
+        }
+      }
+    }
+
+    if (m_MMCorrectionStatus==1) {
+      itSet = rots.begin();
+      MeasurementSet rots_new;
+      MeasurementSet rots_tbd;
+      for (itSet = rots.begin(); itSet != itSetEnd; ++itSet) {
+          if (!(*itSet)) {
+            msg(MSG::WARNING) << "There is an empty MeasurementBase object in the track! Skip this object.." << endmsg;
+          } else {
+            const RIO_OnTrack *rot = dynamic_cast<const RIO_OnTrack *>(*itSet);
+            if (rot && m_DetID->is_mm(rot->identify())) {
+              const PlaneSurface* surf = dynamic_cast<const PlaneSurface *>(&rot->associatedSurface());
+              AtaPlane atapl(surf->center(), param.parameters()[Trk::phi], param.parameters()[Trk::theta], param.parameters()[Trk::qOverP], *surf);
+              rot = m_ROTcreator->correct(*(rot->prepRawData()), atapl);
+              rots_tbd.push_back(rot);
+              rots_new.push_back(rot);
+            } else {
+              rots_new.push_back(*itSet);
+            }
+          }
+      }
+      m_MMCorrectionStatus = -1;
+      Track *track = fit(rots_new, param, runOutlier, matEffects);
+      m_MMCorrectionStatus = 0;
+      for (MeasurementSet::const_iterator it = rots_tbd.begin(); it != rots_tbd.end(); it++) {
+        delete *it;
+      }
+      return track;
+    }
+
+    for (itSet = rots.begin(); itSet != itSetEnd; ++itSet) {
       if (!(*itSet)) {
         msg(MSG::WARNING) << "There is an empty MeasurementBase object in the track! Skip this object.." << endmsg;
       }else {
diff --git a/Tracking/TrkTools/TrkRIO_OnTrackCreator/src/RIO_OnTrackCreator.cxx b/Tracking/TrkTools/TrkRIO_OnTrackCreator/src/RIO_OnTrackCreator.cxx
index f0f9814a584..b67d506645a 100755
--- a/Tracking/TrkTools/TrkRIO_OnTrackCreator/src/RIO_OnTrackCreator.cxx
+++ b/Tracking/TrkTools/TrkRIO_OnTrackCreator/src/RIO_OnTrackCreator.cxx
@@ -213,8 +213,8 @@ Trk::RIO_OnTrackCreator::correct(const Trk::PrepRawData& rio,
       return m_MuonDriftCircleCor->correct(rio, trk);
     }
   }
-  if ( (m_idHelper->is_csc(id)) || (m_idHelper->is_rpc(id)) 
-       || (m_idHelper->is_tgc(id)) ) {
+  if ( (m_idHelper->is_csc(id)) || (m_idHelper->is_rpc(id))
+       || (m_idHelper->is_tgc(id)) || (m_idHelper->is_mm(id)) || (m_idHelper->is_stgc(id)) ) {
     if (m_mode == "indet") {
       msg(MSG::WARNING)<<"I have no tool to correct a CSC/RPC/TGC hit! - Giving back nil."<<endmsg;
       return 0;
-- 
GitLab