diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 7fa667426b023d1307b541fb9ed0f8921059f9b8..cf78e94fe012b5ce64d9e07e559eb83353b8d987 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -15,6 +15,7 @@ add_subdirectory(detectors/tof)
 add_subdirectory(detectors/sts)
 add_subdirectory(detectors/psd)
 add_subdirectory(detectors/fsd)
+add_subdirectory(detectors/must)
 
 If(ROOT_opengl_FOUND)
   Message(STATUS "OpenGL support found. Build the eventdisplay.")
diff --git a/core/data/CMakeLists.txt b/core/data/CMakeLists.txt
index b5b59dd07855d9e7f8fb17bbd151c570757e7563..a728ff52126ed65c10785633c52cc5fb6d29723c 100644
--- a/core/data/CMakeLists.txt
+++ b/core/data/CMakeLists.txt
@@ -15,6 +15,7 @@ set(INCLUDE_DIRECTORIES
   ${CMAKE_CURRENT_SOURCE_DIR}/rich
   ${CMAKE_CURRENT_SOURCE_DIR}/psd
   ${CMAKE_CURRENT_SOURCE_DIR}/fsd
+  ${CMAKE_CURRENT_SOURCE_DIR}/must
   ${CMAKE_CURRENT_SOURCE_DIR}/global
   )
 
@@ -108,6 +109,10 @@ set(SRCS
   fsd/CbmFsdPoint.cxx
   fsd/CbmFsdAddress.cxx
 
+  must/CbmMustPoint.cxx
+  must/CbmMustDigi.cxx
+  must/CbmMustHit.cxx
+
   global/CbmGlobalTrack.cxx
   global/CbmVertex.cxx
   global/CbmTrackParam.cxx
diff --git a/core/data/CbmDataLinkDef.h b/core/data/CbmDataLinkDef.h
index b418995a9fd6172f5b98464b855627f419d9dd94..a4d542f498a494279b8358d24b2aa63c2411b82d 100644
--- a/core/data/CbmDataLinkDef.h
+++ b/core/data/CbmDataLinkDef.h
@@ -109,6 +109,10 @@
 #pragma link C++ namespace CbmFsdAddress;
 #pragma link C++ enum CbmFsdAddress::Level;
 
+#pragma link C++ class CbmMustPoint + ;
+#pragma link C++ class CbmMustDigi + ;
+#pragma link C++ class CbmMustHit + ;
+
 // --- data/global
 #pragma link C++ class CbmGlobalTrack + ;
 #pragma link C++ class CbmVertex + ;
diff --git a/core/data/must/CbmMustDigi.cxx b/core/data/must/CbmMustDigi.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5af6165ae5791ae83071c95efe1d3967ca27bf2e
--- /dev/null
+++ b/core/data/must/CbmMustDigi.cxx
@@ -0,0 +1,46 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustDigi header file                  -----
+// -----                  Created 2025-01-26 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+#include "CbmMustDigi.h"
+
+#include "CbmDefs.h"
+#include "TMath.h"
+
+#include <iostream>
+
+/** Default constructor **/
+CbmMustDigi::CbmMustDigi() : TObject()
+{
+  // ClearDigi();
+}
+
+CbmMustDigi::CbmMustDigi(Int_t detectorId, Int_t skew, Double_t signalTime, Double_t signalError, Double_t chargeDep)
+  : TObject()
+  , fDetectorId(detectorId)
+  , fSkewed(skew)
+  , fSignalTime(signalTime)
+  , fSignalError(signalError)
+  , fDepCharge(chargeDep)
+{
+}
+
+/** Public method ClearDigi **/
+void CbmMustDigi::ClearDigi()
+{
+  fDetectorId  = 0;
+  fSkewed      = 0;
+  fSignalTime  = 0.;
+  fSignalError = 0.;
+  fDepCharge   = 0.;
+}
+
+/** Destructor **/
+CbmMustDigi::~CbmMustDigi() {}
+
+ClassImp(CbmMustDigi)
diff --git a/core/data/must/CbmMustDigi.h b/core/data/must/CbmMustDigi.h
new file mode 100644
index 0000000000000000000000000000000000000000..d0d90568bfbddd480f3b52ca05dc52da886487d0
--- /dev/null
+++ b/core/data/must/CbmMustDigi.h
@@ -0,0 +1,92 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustDigi header file                  -----
+// -----                  Created 2025-01-26 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+/**
+ **
+ ** Meaning of RefIndex:  Index of corresponding MCPoint
+ **                       -1 if fake or background digi
+ **
+ ** Meaning of Flag:       0 = Digi ok
+ **                       -1 : Digi lost due to detection inefficiency
+ **/
+
+#ifndef CBMMUSTDIGI_H
+#define CBMMUSTDIGI_H 1
+
+#include "FairHit.h"
+#include "TObject.h"
+#include "TVector3.h"
+
+class CbmMustDigi : public TObject {
+
+ public:
+  /** Default constructor **/
+  CbmMustDigi();
+
+  /** Standard constructor
+   *@param detectorId  Tube unique volume ID
+   *@param skew        flag for skewed tube
+   *@param signalTime  The signal drift time
+   *@param signalError The error on signal
+   *@param chargeDep   Deposited charge (arbitrary unit)
+   **/
+
+  // THIS ONE!
+  CbmMustDigi(Int_t detectorId, Int_t skew, Double_t signalTime, Double_t signalError, Double_t chargeDep);
+
+  /** Destructor **/
+  virtual ~CbmMustDigi();
+
+  /** Output to screen (not yet implemented) **/
+  virtual void Print(const Option_t* opt = nullptr) const
+  {
+    std::cout << " opt = " << opt << std::endl;
+    return;
+  }
+
+  /** Public method ClearDigi
+     ** Resets the isochrone and it's error to 0
+     **/
+  void ClearDigi();
+
+  /** Accessors **/
+  Double_t GetSignalTime() const { return fSignalTime; };
+  Double_t GetSignalError() const { return fSignalError; };
+  Double_t GetDepCharge() const { return fDepCharge; };
+  Double_t GetEnergyLoss() const { return fDepCharge / 1e6; };
+
+  Double_t GetTime() const { return fSignalTime; };
+  Double_t GetSkewed() const { return fSkewed; };
+
+  /** Modifiers **/
+  void SetSignalTime(Double_t signalTime) { fSignalTime = signalTime; };
+  void SetSignalError(Double_t signalError) { fSignalError = signalError; };
+  void SetDepCharge(Double_t depcharge) { fDepCharge = depcharge; }
+
+  void SetTime(Double_t signalTime) { fSignalTime = signalTime; };
+
+  // tube ID // CHECK added
+  void SetDetectorId(Int_t detectorId) { fDetectorId = detectorId; }
+  Int_t GetDetectorId() const { return fDetectorId; }
+
+ protected:
+  Double_t fSignalTime{0.};
+  Double_t fSignalError{0.};
+
+  /**  deposit charge (arbitrary units) **/
+  Double_t fDepCharge{0.};
+
+  /** tube id **/
+  Int_t fDetectorId{0};
+  Int_t fSkewed{0};
+
+  ClassDef(CbmMustDigi, 1);
+};
+
+#endif
diff --git a/core/data/must/CbmMustHit.cxx b/core/data/must/CbmMustHit.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6e86ef86668f7251ede5d3d4a0e1b6f79142ed61
--- /dev/null
+++ b/core/data/must/CbmMustHit.cxx
@@ -0,0 +1,51 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustHit source file                   -----
+// -----                  Created 2024-11-26 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+#include "CbmMustHit.h"
+
+#include "CbmDefs.h"
+#include "TMath.h"
+
+#include <iostream>
+/** Default constructor **/
+CbmMustHit::CbmMustHit() : FairHit()
+{
+  // ClearHit();
+}
+
+CbmMustHit::CbmMustHit(Int_t sysId, Int_t detectorId, Int_t skew, Int_t mcindex, TVector3 pos, TVector3 dpos,
+                       TVector3 dir, Double_t pulse, Double_t isochrone, Double_t isochroneError, Double_t chDep)
+  : FairHit(sysId, pos, dpos, mcindex)
+  , fDirection(dir)
+  , fIsochrone(isochrone)
+  , fIsochroneError(isochroneError)
+  , fPulse(pulse)
+  , fDepCharge(chDep)
+  , fDetectorId(detectorId)
+  , fSkewed(skew)
+{
+  SetTimeStamp(pulse);
+}
+
+/** Public method ClearHit **/
+void CbmMustHit::ClearHit()
+{
+  fDetectorId     = 0;
+  fSkewed         = 0;
+  fPulse          = 0;
+  fIsochrone      = 0.;
+  fIsochroneError = 0.;
+  fDepCharge      = 0.;
+  fDirection.SetXYZ(0., 0., 0.);
+}
+
+/** Destructor **/
+CbmMustHit::~CbmMustHit() {}
+
+ClassImp(CbmMustHit)
diff --git a/core/data/must/CbmMustHit.h b/core/data/must/CbmMustHit.h
new file mode 100644
index 0000000000000000000000000000000000000000..4d6e21205d51270a7b9a7177b5c6eff32376919b
--- /dev/null
+++ b/core/data/must/CbmMustHit.h
@@ -0,0 +1,132 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustHit header file                   -----
+// -----                  Created 2024-11-26 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+/**
+ **
+ ** Meaning of RefIndex:  Index of corresponding MCPoint
+ **                       -1 if fake or background hit
+ **
+ ** Meaning of Flag:       0 = Hit ok
+ **                       -1 : Hit lost due to detection inefficiency
+ **/
+
+#ifndef CBMMUSTHIT_H
+#define CBMMUSTHIT_H 1
+
+#include "FairHit.h"
+#include "TVector3.h"
+
+class CbmMustHit : public FairHit {
+
+ public:
+  /** Default constructor **/
+  CbmMustHit();
+
+  /** Standard constructor
+   *@param sysId     Detector system unique volume ID
+   *@param detectorId Tube unique ID
+   *@param skew    flag for skewed tube
+   *@param mcindex   Index of corresponding MCPoint
+   *@param pos       Position coordinates of the tube [cm] 
+   *@param dpos      Errors in position coordinates [cm]
+   *@param dir       Direction of the tube [radians]
+   *@param p         Pulse
+   *@param isochrone The radial measurement
+   *@param isoerror  The erroon on the radial measurement
+   *@param chDep     Deposited charge (arbitrary unit)
+   **/
+
+  // THIS ONE!
+  CbmMustHit(Int_t sysId, Int_t detectorId, Int_t skew, Int_t mcindex, TVector3 pos, TVector3 dpos, TVector3 dir,
+             Double_t pulse, Double_t isochrone, Double_t isochroneError, Double_t chDep);
+
+  /** Destructor **/
+  virtual ~CbmMustHit();
+
+  /** Output to screen (not yet implemented) **/
+  virtual void Print(const Option_t* opt = nullptr) const
+  {
+    std::cout << " opt = " << opt << std::endl;
+    return;
+  }
+
+  /** Public method ClearHit
+     ** Resets the isochrone and it's error to 0
+     **/
+  void ClearHit();
+
+  /** Accessors **/
+  Double_t GetIsochrone() const { return fIsochrone; };
+  Double_t GetIsochroneError() const { return fIsochroneError; };
+  Double_t GetPulse() const { return fPulse; };
+  Double_t GetDepCharge() const { return fDepCharge; };
+  Double_t GetEnergyLoss() const { return fDepCharge / 1e6; };
+
+  TVector3 GetDirection() const { return fDirection; };
+
+  /** Modifiers **/
+  void SetIsochrone(Double_t isochrone) { fIsochrone = isochrone; };
+  void SetIsochroneError(Double_t isochroneError) { fIsochroneError = isochroneError; };
+  void SetDepCharge(Double_t depcharge) { fDepCharge = depcharge; }
+
+  // tube ID // CHECK added
+  void SetDetSysId(Int_t sysId) { fDetSysId = sysId; }
+  Int_t GetDetSysId() const { return fDetSysId; }
+  void SetTubeId(Int_t tubeId) { fDetectorId = tubeId; }
+  Int_t GetTubeId() const { return fDetectorId; }
+  Int_t GetSkewed() const { return fSkewed; }
+
+  virtual bool equal(FairTimeStamp* data)
+  {
+    CbmMustHit* myHit = dynamic_cast<CbmMustHit*>(data);
+    if (myHit != nullptr) {
+      if (fDetectorId == myHit->GetTubeId()) return true;
+    }
+    return false;
+  }
+
+  virtual bool operator<(const CbmMustHit& myHit) const
+  {
+    if (fDetectorId < myHit.GetTubeId())
+      return true;
+    else
+      return false;
+  }
+
+  friend std::ostream& operator<<(std::ostream& out, CbmMustHit& digi)
+  {
+    out << "CbmSttHit in Tube: " << digi.GetTubeId() << " Isochrone: " << digi.GetIsochrone() << " +/- "
+        << digi.GetIsochroneError() << " Charge: " << digi.GetDepCharge() << " Pulse: " << digi.GetPulse() << std::endl;
+    return out;
+  }
+
+ protected:
+  TVector3 fDirection{0., 0., 0.};
+
+  /** This variable contains the radial distance to the wire **/
+  Double_t fIsochrone{0.};
+  ;
+  /** This variable contains the error on the radial distance to the wire **/
+  Double_t fIsochroneError{0.};
+
+  /** time pulse **/
+  Double_t fPulse{0.};
+
+  /**  deposit charge (arbitrary units) **/
+  Double_t fDepCharge{0.};
+
+  /** tube id **/
+  Int_t fDetSysId{0};  // CHECK added
+  Int_t fDetectorId{0};
+  Int_t fSkewed{0};
+
+  ClassDef(CbmMustHit, 1);
+};
+
+#endif
diff --git a/core/data/must/CbmMustPoint.cxx b/core/data/must/CbmMustPoint.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ffce57cf2a5310516c992ec84f80bf5abdfb00de
--- /dev/null
+++ b/core/data/must/CbmMustPoint.cxx
@@ -0,0 +1,116 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustPoint source file                 -----
+// -----                  Created 2024-11-26 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+#include "CbmMustPoint.h"
+
+#include "CbmDefs.h"  // for kMCTrack
+#include "FairLogger.h"
+#include "math.h"
+
+#include <FairLink.h>     // for FairLink
+#include <FairMCPoint.h>  // for FairMCPoint
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+// -----   Default constructor   -------------------------------------------
+CbmMustPoint::CbmMustPoint()
+  : FairMCPoint()
+  , fX_out_local(0)
+  , fY_out_local(0)
+  , fZ_out_local(0)
+  , fX_in_local(0.)
+  , fY_in_local(0)
+  , fZ_in_local(0)
+  , fPx_out(0)
+  , fPy_out(0)
+  , fPz_out(0)
+  , fPx_in(0)
+  , fPy_in(0)
+  , fPz_in(0)
+  , fMass(0)
+  , fLayerID(0)
+  , fModuleID(0)
+  , fStrawID(0)
+{
+}
+// -------------------------------------------------------------------------
+
+// -----   Standard constructor   ------------------------------------------
+CbmMustPoint::CbmMustPoint(Int_t trackID, Int_t detID, Int_t layerID, Int_t moduleID, Int_t strawID, TVector3 pos,
+                           TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t tof,
+                           Double_t length, Double_t eLoss, Double_t mass)
+  : FairMCPoint(trackID, detID, pos, momIn, tof, length, eLoss)
+  , fX_out_local(posOutLocal.X())
+  , fY_out_local(posOutLocal.Y())
+  , fZ_out_local(posOutLocal.Z())
+  , fX_in_local(posInLocal.X())
+  , fY_in_local(posInLocal.Y())
+  , fZ_in_local(posInLocal.Z())
+  , fPx_out(momOut.Px())
+  , fPy_out(momOut.Py())
+  , fPz_out(momOut.Pz())
+  , fPx_in(momIn.Px())
+  , fPy_in(momIn.Py())
+  , fPz_in(momIn.Pz())
+  , fMass(mass)
+  , fLayerID(layerID)
+  , fModuleID(moduleID)
+  , fStrawID(strawID)
+{
+  // reset MC momentum
+  fPx = (momIn.Px() + momOut.Px()) / 2.;
+  fPy = (momIn.Py() + momOut.Py()) / 2.;
+  fPz = (momIn.Pz() + momOut.Pz()) / 2.;
+  SetLink(FairLink(ToIntegralType(ECbmDataType::kMCTrack), trackID));
+}
+// -------------------------------------------------------------------------
+
+// -----   Destructor   ----------------------------------------------------
+CbmMustPoint::~CbmMustPoint() {}
+// -------------------------------------------------------------------------
+
+// -----   Copy constructor   ------------------------------------------
+CbmMustPoint::CbmMustPoint(const CbmMustPoint& point)
+  : FairMCPoint(point.fTrackID, point.fDetectorID, TVector3(point.fX, point.fY, point.fZ),
+                TVector3(point.fPx, point.fPy, point.fPz), point.fTime, point.fLength, point.fELoss, point.fEventId)
+  , fX_out_local(point.fX_out_local)
+  , fY_out_local(point.fY_out_local)
+  , fZ_out_local(point.fZ_out_local)
+  , fX_in_local(point.fX_in_local)
+  , fY_in_local(point.fY_in_local)
+  , fZ_in_local(point.fZ_in_local)
+  , fPx_out(point.fPx_out)
+  , fPy_out(point.fPy_out)
+  , fPz_out(point.fPz_out)
+  , fPx_in(point.fPx_in)
+  , fPy_in(point.fPy_in)
+  , fPz_in(point.fPz_in)
+  , fMass(point.fMass)
+  , fLayerID(point.fLayerID)
+  , fModuleID(point.fModuleID)
+  , fStrawID(point.fStrawID)
+{
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method Print   -------------------------------------------
+void CbmMustPoint::Print(const Option_t* opt) const
+{
+  LOG(info) << " CbmMustPoint: MUST Point for track " << fTrackID << " in det/lay/mod/str " << fDetectorID << "/"
+            << fLayerID << "/" << fModuleID << "/" << fStrawID;
+  LOG(info) << "    Position (" << fX << ", " << fY << ", " << fZ << ") cm";
+  LOG(info) << "    Momentum (" << fPx << ", " << fPy << ", " << fPz << ") GeV";
+  LOG(info) << "    Time " << fTime << " ns,  Length " << fLength << " cm,  Energy loss " << fELoss * 1.0e06 << " keV"
+            << " opt=" << opt;
+}
+// -------------------------------------------------------------------------
+
+ClassImp(CbmMustPoint)
diff --git a/core/data/must/CbmMustPoint.h b/core/data/must/CbmMustPoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e782506e2ec16acf4304a253054ace1e510cff0
--- /dev/null
+++ b/core/data/must/CbmMustPoint.h
@@ -0,0 +1,138 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustPoint header file                 -----
+// -----                  Created 2024-11-26 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+#ifndef CBMMUSTPOINT_H
+#define CBMMUSTPOINT_H
+
+#include "FairMCPoint.h"
+#include "TObject.h"
+#include "TVector3.h"
+
+class CbmMustPoint : public FairMCPoint {
+
+ public:
+  /** Default constructor **/
+  CbmMustPoint();
+
+  /** Constructor with arguments
+   *@param trackID       Index of MCTrack
+   *@param detID         Detector ID
+   *@param LayerID       MUST layerID (1...12)
+   *@param moduleID      moduleID in layer (1...36)
+   *@param strawID       strawID in module (1...128)
+   *@param pos           Coordinates at wire center of active volume [cm]
+   *@param posInLocal    Local coordinates at entrance to active volume [cm]
+   *@param posOutLocal   Local coordinates at exit of active volume [cm]
+   *@param momIn         Momentum of track at entrance [GeV]
+   *@param momOut        Momentum of track at exit [GeV]
+   *@param tof           Time since event start [ns]
+   *@param length        Track length since creation [cm]
+   *@param eLoss         Energy deposit [GeV]
+   **/
+  CbmMustPoint(Int_t trackID, Int_t detID, Int_t layerID, Int_t moduleID, Int_t strawID, TVector3 pos,
+               TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t tof,
+               Double_t length, Double_t eLoss, Double_t mass);
+
+  /** Copy constructor **/
+  CbmMustPoint(const CbmMustPoint& point);
+
+  /** Destructor **/
+  virtual ~CbmMustPoint();
+
+  // da cancellare
+  Double_t GetXtot() const { return GetX(); }
+  Double_t GetYtot() const { return GetY(); }
+  Double_t GetZtot() const { return GetZ(); }
+
+  Double_t GetPxOut() const { return fPx_out; }
+  Double_t GetPyOut() const { return fPy_out; }
+  Double_t GetPzOut() const { return fPz_out; }
+
+  //////
+
+  /** Accessors **/
+  Double_t GetXOutLocal() const { return fX_out_local; }
+  Double_t GetYOutLocal() const { return fY_out_local; }
+  Double_t GetZOutLocal() const { return fZ_out_local; }
+  Double_t GetXInLocal() const { return fX_in_local; }
+  Double_t GetYInLocal() const { return fY_in_local; }
+  Double_t GetZInLocal() const { return fZ_in_local; }
+
+  // Double_t GetXWireDirection() const { return fX_wire_dir; }
+  // Double_t GetYWireDirection() const { return fY_wire_dir; }
+  // Double_t GetZWireDirection() const { return fZ_wire_dir; }
+
+  Double_t GetMass() const { return fMass; }
+
+  void PositionOutLocal(TVector3& pos) { pos.SetXYZ(fX_out_local, fY_out_local, fZ_out_local); }
+  void PositionInLocal(TVector3& pos) { pos.SetXYZ(fX_in_local, fY_in_local, fZ_in_local); }
+  void MomentumOut(TVector3& mom) { mom.SetXYZ(fPx_out, fPy_out, fPz_out); }
+  // void WireDirection(TVector3& wire) { wire.SetXYZ(fX_wire_dir, fY_wire_dir, fZ_wire_dir); }
+
+  /** Modifiers **/
+  void SetPositionOutLocal(TVector3 pos);
+  void SetPositionInLocal(TVector3 pos);
+  void SetMomentumOut(TVector3 mom);
+  // void SetWireDirection(TVector3 wire);
+
+  // tube ID // CHECK added
+  Int_t GetLayerID() const { return fLayerID; }
+  Int_t GetModuleID() const { return fModuleID; }
+  Int_t GetStrawID() const { return fStrawID; }
+  void SetLayerID(Int_t layerid) { fLayerID = layerid; }
+  void SetModuleID(Int_t moduleid) { fModuleID = moduleid; }
+  void SetStrawID(Int_t strawid) { fStrawID = strawid; }
+
+  /** Output to screen **/
+  virtual void Print(const Option_t* opt) const;
+
+ protected:
+  // exit coordinates in straw frame
+  Double_t fX_out_local, fY_out_local, fZ_out_local;
+  // entry coordinates in straw frame
+  Double_t fX_in_local, fY_in_local, fZ_in_local;
+
+  Double_t fPx_out, fPy_out, fPz_out;
+  Double_t fPx_in, fPy_in, fPz_in;
+  // wire direction
+  // Double_t fX_wire_dir, fY_wire_dir, fZ_wire_dir;
+
+  // particle mass
+  Double_t fMass;
+  Int_t fLayerID;
+  Int_t fModuleID;
+  Int_t fStrawID;
+
+  //////
+
+  ClassDef(CbmMustPoint, 1)
+};
+
+inline void CbmMustPoint::SetPositionOutLocal(TVector3 pos)
+{
+  fX_out_local = pos.X();
+  fY_out_local = pos.Y();
+  fZ_out_local = pos.Z();
+}
+
+inline void CbmMustPoint::SetPositionInLocal(TVector3 pos)
+{
+  fX_in_local = pos.X();
+  fY_in_local = pos.Y();
+  fZ_in_local = pos.Z();
+}
+
+inline void CbmMustPoint::SetMomentumOut(TVector3 mom)
+{
+  fPx_out = mom.Px();
+  fPy_out = mom.Py();
+  fPz_out = mom.Pz();
+}
+
+#endif
diff --git a/core/detectors/must/CMakeLists.txt b/core/detectors/must/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9a533cd7636454099257879d5e5a9b85e03a9558
--- /dev/null
+++ b/core/detectors/must/CMakeLists.txt
@@ -0,0 +1,48 @@
+set(INCLUDE_DIRECTORIES
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  )
+
+
+set(SRCS
+  CbmGeoMust.cxx
+  CbmGeoMustPar.cxx
+  CbmMustContFact.cxx
+  CbmMustGeoScheme.cxx
+  CbmMustStation.cxx
+  CbmMustLayer.cxx
+  CbmMustModule.cxx
+  CbmMustTube.cxx
+)
+
+
+# ---- Enable OpenMP  -------------------------------------
+find_package(OpenMP)
+if (OPENMP_FOUND)
+  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
+  set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
+endif()
+# ---------------------------------------------------------
+
+set(LIBRARY_NAME CbmMustBase)
+set(LINKDEF ${LIBRARY_NAME}LinkDef.h)
+set(PUBLIC_DEPENDENCIES
+  FairRoot::Base
+  FairRoot::ParBase
+  CbmBase
+  ROOT::Core
+  ROOT::Geom
+  ROOT::Gpad
+  ROOT::Hist
+  ROOT::MathCore
+  ROOT::Physics
+  )
+
+set(PRIVATE_DEPENDENCIES
+  FairLogger::FairLogger
+  CbmData
+  ROOT::Graf
+  ROOT::MLP
+  ROOT::Tree
+  )
+
+generate_cbm_library()
diff --git a/core/detectors/must/CbmGeoMust.cxx b/core/detectors/must/CbmGeoMust.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a8215fc9d290451d136a3af903a9e0cef310d842
--- /dev/null
+++ b/core/detectors/must/CbmGeoMust.cxx
@@ -0,0 +1,45 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmGeoMust source file
+//
+// Class for geometry of MUST
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmGeoFts by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#include "CbmGeoMust.h"
+// from FairRoot
+#include <FairGeoNode.h>
+// from fmt
+#include <fmt/core.h>
+
+ClassImp(CbmGeoMust)
+
+  CbmGeoMust::CbmGeoMust()
+{
+  // Constructor
+  fName      = "must";
+  maxSectors = 0;
+  maxModules = 40;
+}
+
+const char* CbmGeoMust::getModuleName(Int_t m)
+{
+  // Returns the module name of MUST number m
+  modName = fmt::format("must{:02d}", m + 1);
+
+  return modName.c_str();
+}
+
+const char* CbmGeoMust::getEleName(Int_t m)
+{
+  // Returns the element name of MUST number m
+  eleName = fmt::format("must{:02d}", m + 1);
+
+  return eleName.c_str();
+}
diff --git a/core/detectors/must/CbmGeoMust.h b/core/detectors/must/CbmGeoMust.h
new file mode 100644
index 0000000000000000000000000000000000000000..f18d4ed53f1b1f468afdf6000f242727f67ade70
--- /dev/null
+++ b/core/detectors/must/CbmGeoMust.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmGeoMust header file
+//
+// Class for geometry of MUST
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmGeoFts by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef CBMGEOMUST_H
+#define CBMGEOMUST_H
+
+// from FairRoot
+#include <FairGeoSet.h>
+
+class CbmGeoMust : public FairGeoSet {
+ protected:
+  std::string modName;  // name of module
+  std::string eleName;  // substring for elements in module
+ public:
+  CbmGeoMust();
+  ~CbmGeoMust() {}
+  const char* getModuleName(Int_t);
+  const char* getEleName(Int_t);
+  inline Int_t getModNumInMod(const TString&);
+  ClassDef(CbmGeoMust, 0)  // Class for Must
+};
+
+inline Int_t CbmGeoMust::getModNumInMod(const TString& name)
+{
+  // returns the module index from module name
+
+  return (Int_t)(name[2] - '0') - 1;
+}
+
+#endif /* !CBMGEOMUST_H */
diff --git a/core/detectors/must/CbmGeoMustPar.cxx b/core/detectors/must/CbmGeoMustPar.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bc48bc12f18db957a79fe6992e690e4c3ddb1413
--- /dev/null
+++ b/core/detectors/must/CbmGeoMustPar.cxx
@@ -0,0 +1,68 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmGeoMustPar source file
+//
+// Class for geometry parameters of MUST
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmGeoFtsPar by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#include "CbmGeoMustPar.h"
+// from FairRoot
+#include <FairParamList.h>
+// standard
+#include <iomanip>
+#include <iostream>
+
+ClassImp(CbmGeoMustPar)
+
+  CbmGeoMustPar::CbmGeoMustPar(const char* name, const char* title, const char* context)
+  : FairParGenericSet(name, title, context)
+  , fGeoSensNodes(new TObjArray())
+  , fGeoPassNodes(new TObjArray())
+  , fGeoType(-1)
+  , fTubeInRad(0)
+  , fTubeOutRad(0)
+{
+}
+
+CbmGeoMustPar::~CbmGeoMustPar(void) {}
+
+void CbmGeoMustPar::clear(void)
+{
+  if (fGeoSensNodes) {
+    fGeoSensNodes->Delete();
+    delete fGeoSensNodes;
+  }
+  if (fGeoPassNodes) {
+    fGeoPassNodes->Delete();
+    delete fGeoPassNodes;
+  }
+}
+
+void CbmGeoMustPar::putParams(FairParamList* l)
+{
+  if (!l) return;
+  l->addObject("FairGeoNodes Sensitive List", fGeoSensNodes);
+  l->addObject("FairGeoNodes Passive List", fGeoPassNodes);
+  l->add("Tube Innen Radius", fTubeInRad);
+  l->add("Tube Outer Radius", fTubeOutRad);
+  l->add("Geometry Type", fGeoType);
+}
+
+Bool_t CbmGeoMustPar::getParams(FairParamList* l)
+{
+  if (!l) return kFALSE;
+  if (!l->fillObject("FairGeoNodes Sensitive List", fGeoSensNodes)) return kFALSE;
+  if (!l->fillObject("FairGeoNodes Passive List", fGeoPassNodes)) return kFALSE;
+  if (!l->fill("Tube Innen Radius", &fTubeInRad)) return kFALSE;
+  if (!l->fill("Tube Outer Radius", &fTubeOutRad)) return kFALSE;
+  if (!l->fill("Geometry Type", &fGeoType)) return kFALSE;
+
+  return kTRUE;
+}
diff --git a/core/detectors/must/CbmGeoMustPar.h b/core/detectors/must/CbmGeoMustPar.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce3058005ff7b4b37755c173e81771ab6090929f
--- /dev/null
+++ b/core/detectors/must/CbmGeoMustPar.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmGeoMustPar header file
+//
+// Class for geometry parameters of MUST
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmGeoFtsPar by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef CBMGEOMUSTPAR_H
+#define CBMGEOMUSTPAR_H
+// from FairRoot
+#include <FairParGenericSet.h>
+// from ROOT
+#include <TH1F.h>
+#include <TObjArray.h>
+
+class CbmGeoMustPar : public FairParGenericSet {
+ private:
+  TObjArray* fGeoSensNodes;          /** List of FairGeoNodes for sensitive volumes*/
+  TObjArray* fGeoPassNodes;          /** List of FairGeoNodes for sensitive volumes*/
+  Int_t fGeoType;                    // modif
+  Double_t fTubeInRad, fTubeOutRad;  // modif
+
+  CbmGeoMustPar(const CbmGeoMustPar& L);
+  CbmGeoMustPar& operator=(const CbmGeoMustPar&) { return *this; }
+
+ public:
+  CbmGeoMustPar(const char* name = "CbmGeoMustPar", const char* title = "Must Geometry Parameters",
+                const char* context = "TestDefaultContext");
+  ~CbmGeoMustPar(void);
+  void clear(void);
+  void putParams(FairParamList*);
+  Bool_t getParams(FairParamList*);
+  TObjArray* GetGeoSensitiveNodes() { return fGeoSensNodes; }
+  TObjArray* GetGeoPassiveNodes() { return fGeoPassNodes; }
+
+  // Additional function
+  void SetGeometryType(Int_t geoType) { fGeoType = geoType; }
+  void SetTubeInRad(Double_t inrad) { fTubeInRad = inrad; }
+  void SetTubeOutRad(Double_t outrad) { fTubeOutRad = outrad; }
+  Int_t GetGeometryType() { return (Int_t) fGeoType; };
+  Double_t GetTubeInRad() { return (Double_t) fTubeInRad; };
+  Double_t GetTubeOutRad() { return (Double_t) fTubeOutRad; };
+
+  ClassDef(CbmGeoMustPar, 1)
+};
+
+#endif /* !CBMGEOMUSTPAR_H */
diff --git a/core/detectors/must/CbmMustBaseLinkDef.h b/core/detectors/must/CbmMustBaseLinkDef.h
new file mode 100644
index 0000000000000000000000000000000000000000..d994d020bb603d003b6cc4249094991fa3c225cd
--- /dev/null
+++ b/core/detectors/must/CbmMustBaseLinkDef.h
@@ -0,0 +1,20 @@
+/* Copyright (C) 2020-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Volker Friese [committer] */
+
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class CbmGeoMust + ;
+#pragma link C++ class CbmGeoMustPar + ;
+#pragma link C++ class CbmMustContFact + ;
+#pragma link C++ class CbmMustGeoScheme + ;
+#pragma link C++ class CbmMustStation + ;
+#pragma link C++ class CbmMustLayer + ;
+#pragma link C++ class CbmMustModule + ;
+#pragma link C++ class CbmMustTube + ;
+
+#endif /* __CINT__ */
diff --git a/core/detectors/must/CbmMustContFact.cxx b/core/detectors/must/CbmMustContFact.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..d9631af9c98794ba874696b5c06a4aabd124f9bd
--- /dev/null
+++ b/core/detectors/must/CbmMustContFact.cxx
@@ -0,0 +1,61 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmMustContFact source file
+//
+// Factory for the parameter containers in libMust
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmMustContFact by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#include "CbmMustContFact.h"
+// from CbnRoot, this library
+#include "CbmGeoMustPar.h"
+// from FairRoot
+#include <FairParAsciiFileIo.h>
+#include <FairParRootFileIo.h>
+#include <FairRuntimeDb.h>
+// standard
+#include <iomanip>
+#include <iostream>
+
+ClassImp(CbmMustContFact)
+
+  static CbmMustContFact gCbmMustContFact;
+
+CbmMustContFact::CbmMustContFact()
+{
+  // Constructor (called when the library is loaded)
+  fName  = "CbmMustContFact";
+  fTitle = "Factory for parameter containers in libMust";
+  setAllContainers();
+  FairRuntimeDb::instance()->addContFactory(this);
+}
+
+void CbmMustContFact::setAllContainers()
+{
+  /** Creates the Container objects with all accepted contexts and adds them to
+   *  the list of containers for the MUST library.*/
+  FairContainer* p1 = new FairContainer("CbmGeoMustPar", "Must Geometry Parameters", "TestDefaultContext");
+  p1->addContext("TestNonDefaultContext");
+  containers->Add(p1);
+}
+
+FairParSet* CbmMustContFact::createContainer(FairContainer* c)
+{
+  /** Calls the constructor of the corresponding parameter container.
+   * For an actual context, which is not an empty string and not the default context
+   * of this container, the name is concatinated with the context. */
+  const char* name = c->GetName();
+  std::cout << "[MUST] CbmMustContFact createContainer name " << name << std::endl;
+  FairParSet* p = 0;
+
+  if (strcmp(name, "CbmGeoMustPar") == 0) {
+    p = new CbmGeoMustPar(c->getConcatName().Data(), c->GetTitle(), c->getContext());
+  }
+  return p;
+}
diff --git a/core/detectors/must/CbmMustContFact.h b/core/detectors/must/CbmMustContFact.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b1537422e6bad2d8fb3d0db7c03667fb70f1ec2
--- /dev/null
+++ b/core/detectors/must/CbmMustContFact.h
@@ -0,0 +1,35 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmMustContFact header file
+//
+// Factory for the parameter containers in libMust
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmMustContFact by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef CBMMUSTCONTFACT_H
+#define CBMMUSTCONTFACT_H
+
+// from FairRoot
+#include <FairContFact.h>
+
+class FairContainer;
+
+class CbmMustContFact : public FairContFact {
+ private:
+  void setAllContainers();
+
+ public:
+  CbmMustContFact();
+  ~CbmMustContFact() {}
+  FairParSet* createContainer(FairContainer*);
+  //  void  activateParIo(FairParIo* io);
+  ClassDef(CbmMustContFact, 0)  // Factory for all MUST parameter containers
+};
+
+#endif /* !CBMMUSTCONTFACT_H */
diff --git a/core/detectors/must/CbmMustGeoScheme.cxx b/core/detectors/must/CbmMustGeoScheme.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b9de8c744265e1bba08f569ffe0b094152b30649
--- /dev/null
+++ b/core/detectors/must/CbmMustGeoScheme.cxx
@@ -0,0 +1,195 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+/** CbmMustGeoScheme
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** Based on CbmMuchGeoScheme by Evgeny Kryshen <e.kryshen@gsi.de>
+ **
+ **/
+#include "CbmMustGeoScheme.h"
+
+#include "CbmMustLayer.h"  // for CbmMustLayer
+#include "CbmMustModule.h"
+#include "CbmMustStation.h"  // for CbmMustStation
+#include "CbmMustTube.h"
+
+#include <Logger.h>  // for LOG
+
+#include <TArrayD.h>       // for TArrayD
+#include <TArrayI.h>       // for TArrayI
+#include <TClonesArray.h>  // for TClonesArray
+#include <TFile.h>         // for TFile, gFile
+#include <TGeoBBox.h>      // for TGeoBBox
+#include <TGeoManager.h>   // for TGeoManager, gGeoManager
+#include <TGeoNode.h>      // for TGeoNode
+#include <TGeoTube.h>      // for TGeoTube
+#include <TGeoVolume.h>    // for TGeoVolume
+#include <TMath.h>         // for Cos, Sqrt
+#include <TObjArray.h>     // for TObjArray
+#include <TObject.h>       // for TObject
+#include <TVector3.h>      // for TVector3
+
+#include <cassert>    // for assert
+#include <stdexcept>  // for out_of_range
+#include <utility>    // for pair
+#include <vector>
+
+#include <math.h>  // for sqrt
+
+using std::vector;
+
+CbmMustGeoScheme* CbmMustGeoScheme::fInstance = nullptr;
+
+// -------------------------------------------------------------------------
+CbmMustGeoScheme::CbmMustGeoScheme() : TObject() { LOG(debug) << "CbmMustGeoScheme created"; }
+// -------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------
+CbmMustGeoScheme::~CbmMustGeoScheme()
+{
+
+  if (fInstance != nullptr) delete fInstance;
+}
+// -------------------------------------------------------------------------
+
+
+// -------------------------------------------------------------------------
+CbmMustGeoScheme* CbmMustGeoScheme::Instance()
+{
+
+  if (!fInstance) fInstance = new CbmMustGeoScheme();
+  return fInstance;
+}
+// -------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------
+void CbmMustGeoScheme::Init(TObjArray* stations)
+{
+  if (!fInitialized) {
+    fStations    = stations;
+    fInitialized = kTRUE;
+  }
+  LOG(debug) << "CbmMustGeoScheme init successful";
+}
+// -------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------
+void CbmMustGeoScheme::Init(TString parFileName)
+{
+
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
+  TFile* file = new TFile(parFileName);
+  LOG_IF(fatal, !file) << "File " << parFileName << " does not exist";
+  TObjArray* stations = file->Get<TObjArray>("stations");
+  LOG_IF(fatal, !stations) << "No TObjArray stations found in file " << parFileName;
+  file->Close();
+  file->Delete();
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
+  Init(stations);
+}
+// -------------------------------------------------------------------------
+
+
+// -------------------------------------------------------------------------
+CbmMustStation* CbmMustGeoScheme::GetStation(int iStation) const
+{
+
+  if (!fStations) return nullptr;
+  Bool_t result = (iStation >= 0) || (iStation < fStations->GetEntriesFast());
+
+  return result ? (CbmMustStation*) fStations->At(iStation) : nullptr;
+}
+// -------------------------------------------------------------------------
+
+CbmMustStation* CbmMustGeoScheme::FindStation(int detid)
+{
+  if (!fStations) fStations = new TObjArray();
+  for (Int_t iobj = 0; iobj < fStations->GetEntriesFast(); iobj++) {
+    CbmMustStation* tempStation = (CbmMustStation*) (fStations->At(iobj));
+    if (tempStation->GetDetectorId() == detid) return tempStation;
+  }
+  return nullptr;
+}
+
+CbmMustTube* CbmMustGeoScheme::GetTube(int detid)
+{
+  int stationid            = detid / 1e7 - 1;
+  CbmMustStation* tempStat = GetStation(stationid);
+  //    LOG(info) << "trying to get tube " << detid % 10000000 << " from station " << stationid;
+  return tempStat ? tempStat->GetTube(detid % 10000000) : nullptr;
+}
+
+bool CbmMustGeoScheme::AddStation(CbmMustStation* station)
+{
+  for (Int_t iobj = 0; iobj < fStations->GetEntriesFast(); iobj++) {
+    CbmMustStation* tempStation = (CbmMustStation*) (fStations->At(iobj));
+    if (tempStation->GetDetectorId() == station->GetDetectorId()) return false;
+  }
+
+  fStations->Add(station);
+  return true;
+}
+
+void CbmMustGeoScheme::Show()
+{
+  LOG(info) << "MustGeoScheme:";
+  for (Int_t iobj = 0; iobj < fStations->GetEntriesFast(); iobj++) {
+    CbmMustStation* tempStation = (CbmMustStation*) (fStations->At(iobj));
+    tempStation->Show();
+  }
+}
+
+// -------------------------------------------------------------------------
+void CbmMustGeoScheme::StoreGeoScheme()
+{
+
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
+  std::string geoSchemeFileName("must_geoScheme.root");
+  TFile* file = new TFile(geoSchemeFileName.c_str(), "recreate");
+  LOG_IF(fatal, !file) << "File " << geoSchemeFileName << " does not exist";
+  file->WriteObject(fStations, "stations");
+  //  fStations->Write();
+  file->Close();
+  file->Delete();
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+}
+// -------------------------------------------------------------------------
+CbmMustLayer* CbmMustGeoScheme::GetLayer(int iStation, int iLayer) const
+{
+
+  CbmMustStation* station = GetStation(iStation);
+  return station ? station->GetLayer(iLayer) : nullptr;
+}
+// -------------------------------------------------------------------------
+
+// -------------------------------------------------------------------------
+void CbmMustGeoScheme::NavigateTo(const TString& path)
+{
+  gGeoManager->cd(path.Data());
+  //    fGeoPathHash;
+  //  fGeoPathHash      = path.Hash();
+  TGeoVolume* fCurrentVolume = gGeoManager->GetCurrentVolume();
+  //  TGeoBBox*   fVolumeBoxShape   = (TGeoBBox*) fCurrentVolume->GetShape();
+  Double_t local[3] = {0., 0., 0.};
+  gGeoManager->LocalToMaster(local, fGlobal);
+  //  LOG(info) << "position: " << fGlobal[0] << "," << fGlobal[1] << "," << fGlobal[2];
+}
+// -------------------------------------------------------------------------
+
+ClassImp(CbmMustGeoScheme)
diff --git a/core/detectors/must/CbmMustGeoScheme.h b/core/detectors/must/CbmMustGeoScheme.h
new file mode 100644
index 0000000000000000000000000000000000000000..896174698bd391616abe2593ba87d1bf174f6dfb
--- /dev/null
+++ b/core/detectors/must/CbmMustGeoScheme.h
@@ -0,0 +1,95 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                   CbmMustGeoScheme header file                -----
+// -----                  Created 18/02/08  by E. Kryshen              -----
+// -----                  Modified 08/01/2025 by R. Karabowicz         -----
+// -------------------------------------------------------------------------
+
+/** CbmMustGeoScheme
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** Based on CbmMuchGeoScheme by Evgeny Kryshen <e.kryshen@gsi.de>
+ **
+ **/
+
+#ifndef CbmMustGeoScheme_H
+#define CbmMustGeoScheme_H 1
+
+#include <Rtypes.h>      // for THashConsistencyHolder, ClassDef
+#include <RtypesCore.h>  // for Int_t, Double_t, Bool_t, Float_t, Char_t
+#include <TArrayC.h>     // for TArrayC
+#include <TArrayD.h>     // for TArrayD
+#include <TArrayI.h>     // for TArrayI
+#include <TGeoBBox.h>    // for TGeoBBox
+#include <TGeoCone.h>    // for TGeoCone
+#include <TObjArray.h>   // for TObjArray
+#include <TObject.h>     // for TObject
+#include <TString.h>     // for TString
+#include <TVector3.h>    // for TVector3
+
+#include <map>     // for map
+#include <vector>  // for vector
+
+class CbmMustTube;
+class CbmMustLayer;
+class CbmMustModule;
+class CbmMustStation;
+class TGeoHMatrix;
+class TGeoNode;
+class TGeoTrap;
+class TGeoVolume;
+
+class CbmMustGeoScheme : public TObject {
+
+ public:
+  /** Destructor.     */
+  ~CbmMustGeoScheme();
+  //void Init(Bool_t isSimulation = kFALSE);
+  static CbmMustGeoScheme* Instance();
+  /** Gets whether the geometry scheme is initialized. */
+  Bool_t IsInitialized() { return fInitialized; }
+
+  // Get geometry objects by indices
+  TObjArray* GetStations() const { return fStations; };
+  CbmMustStation* GetStation(int iStation) const;
+  CbmMustLayer* GetLayer(int iStation, int iLayer) const;
+
+  int GetNStations() const { return fStations->GetEntriesFast(); }
+
+  CbmMustTube* GetTube(int detid);
+
+  CbmMustStation* FindStation(int detid);
+  bool AddStation(CbmMustStation* station);
+  void Show();
+  void StoreGeoScheme();
+
+  void Init(TObjArray* stations);
+  void Init(TString parFileName);
+
+  void NavigateTo(const TString& path);
+  // void NavigateToBBox(const TString& path);
+  // void NavigateToTube(const TString& path);
+
+  TVector3 GetGlobal() { return TVector3(fGlobal); }
+
+ private:
+  static CbmMustGeoScheme* fInstance;
+
+  CbmMustGeoScheme();
+
+  bool fInitialized{false};
+  TObjArray* fStations{nullptr};  //!
+  double fGlobal[3]{0., 0., 0.};
+
+  CbmMustGeoScheme(const CbmMustGeoScheme&);
+  CbmMustGeoScheme& operator=(const CbmMustGeoScheme&);
+
+  ClassDef(CbmMustGeoScheme, 1);
+};
+
+#endif
diff --git a/core/detectors/must/CbmMustLayer.cxx b/core/detectors/must/CbmMustLayer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1422079cbb99f8c041ab600677feba06d171e0d8
--- /dev/null
+++ b/core/detectors/must/CbmMustLayer.cxx
@@ -0,0 +1,89 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+/** CbmMustLayer.cxx
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** This class holds the transport geometry parameters
+ ** of one MuST tracking layer.
+ ** Based on CbmMuchLayer by  M.Ryzhinskiy <m.ryzhinskiy@gsi.de>
+ **
+ **/
+#include "CbmMustLayer.h"
+
+#include <Logger.h>  // for LOG
+
+#include <TMathBase.h>  // for Abs
+#include <TObject.h>    // for TObject
+#include <TVector3.h>   // for TVector3
+
+// -----   Default constructor   -------------------------------------------
+CbmMustLayer::CbmMustLayer() : TObject() {}
+// -------------------------------------------------------------------------
+
+// -----   Standard constructor   ------------------------------------------
+CbmMustLayer::CbmMustLayer(int detId, double z, double zRel)
+  : TObject()
+  , fDetectorId(detId)
+  , fZ(z)
+  , fZtoStationCenter(zRel)
+{
+}
+// -------------------------------------------------------------------------
+
+// -----   Standard constructor   ------------------------------------------
+CbmMustLayer::CbmMustLayer(int iStation, int iLayer, double z, double zRel)
+  : TObject()
+  , fDetectorId(iStation * 1e7 + iLayer * 1e5)
+  , fZ(z)
+  , fZtoStationCenter(zRel)
+
+{
+}
+// -------------------------------------------------------------------------
+
+// -----   Destructor   ----------------------------------------------------
+CbmMustLayer::~CbmMustLayer() {}
+// -------------------------------------------------------------------------
+
+CbmMustTube* CbmMustLayer::GetTube(int detid)
+{
+  int moduleid              = detid / 1e3 - 1;
+  CbmMustModule* tempModule = GetModule(moduleid);
+  //    LOG(info) << "trying to get tube " << detid % 1000 << " from module " << moduleid;
+  return tempModule ? tempModule->GetTube(detid % 1000 - 1) : nullptr;
+}
+
+CbmMustModule* CbmMustLayer::FindModule(int detid)
+{
+  for (Int_t iobj = 0; iobj < fModules.GetEntriesFast(); iobj++) {
+    CbmMustModule* tempModule = (CbmMustModule*) (fModules.At(iobj));
+    if (tempModule->GetDetectorId() == detid) return tempModule;
+  }
+  return nullptr;
+}
+
+bool CbmMustLayer::AddModule(CbmMustModule* module)
+{
+  for (Int_t iobj = 0; iobj < fModules.GetEntriesFast(); iobj++) {
+    CbmMustModule* tempModule = (CbmMustModule*) (fModules.At(iobj));
+    if (tempModule->GetDetectorId() == module->GetDetectorId()) return false;
+  }
+
+  fModules.Add(module);
+  return true;
+}
+
+void CbmMustLayer::Show()
+{
+  LOG(info) << "    Layer " << fDetectorId << " (@ z = " << fZ << "):";
+  for (Int_t iobj = 0; iobj < fModules.GetEntriesFast(); iobj++) {
+    CbmMustModule* tempModule = (CbmMustModule*) (fModules.At(iobj));
+    tempModule->Show();
+  }
+}
+
+ClassImp(CbmMustLayer)
diff --git a/core/detectors/must/CbmMustLayer.h b/core/detectors/must/CbmMustLayer.h
new file mode 100644
index 0000000000000000000000000000000000000000..1c60c30e646db93befe94567a53c3afd60cd3274
--- /dev/null
+++ b/core/detectors/must/CbmMustLayer.h
@@ -0,0 +1,76 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+/** CbmMustLayer.h
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** This class holds the transport geometry parameters
+ ** of one MuST tracking layer.
+ ** Based on CbmMuchLayer by  M.Ryzhinskiy <m.ryzhinskiy@gsi.de>
+ **
+ **/
+
+
+#ifndef CBMMUSTLAYER_H
+#define CBMMUSTLAYER_H 1
+
+#include "CbmMustModule.h"
+#include "CbmMustTube.h"
+
+#include <Rtypes.h>      // for THashConsistencyHolder, ClassDef
+#include <RtypesCore.h>  // for Double_t, Int_t, Bool_t, Double32_t
+#include <TObjArray.h>   // for TObjArray
+#include <TObject.h>     // for TObject
+
+class CbmMustLayer : public TObject {
+
+ public:
+  /** Default constructor **/
+  CbmMustLayer();
+
+  /** Standard constructor
+     *@param detId     Detector ID
+     *@param z         z position of layer center [cm]
+     *@param zRel      z position of layer center relative to station center [cm]
+     **/
+  CbmMustLayer(int detId, double z, double zRel);
+
+  /** Standard constructor
+     *@param iStation  Station index
+     *@param iLayer    Layer index
+     *@param z         z position of layer center [cm]
+     *@param zRel      z position of layer center relative to station center [cm]
+     **/
+  CbmMustLayer(int iStation, int iLayer, double z, double zRel);
+
+  /** Destructor **/
+  virtual ~CbmMustLayer();
+
+  /** Accessors **/
+  int GetDetectorId() const { return fDetectorId; }
+  double GetZ() const { return fZ; }
+  double GetZtoStationCenter() const { return fZtoStationCenter; }
+
+  int GetNModules() const { return fModules.GetEntriesFast(); }
+
+  CbmMustModule* GetModule(int iModule) const { return (CbmMustModule*) fModules.At(iModule); }
+
+  CbmMustTube* GetTube(int detid);
+
+  CbmMustModule* FindModule(int detid);
+  bool AddModule(CbmMustModule* module);
+  void Show();
+
+ protected:
+  int fDetectorId{0};  // Unique detector ID
+  double fZ{0.};
+  double fZtoStationCenter{0.};  // Relative position of the layer center with respect
+                                 // to the station center
+  TObjArray fModules;            // Array of CbmMustModules
+
+  ClassDef(CbmMustLayer, 1);
+};
+#endif
diff --git a/core/detectors/must/CbmMustModule.cxx b/core/detectors/must/CbmMustModule.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..26502ec98de8ed04ef51691e1bb41f8e2896bcd2
--- /dev/null
+++ b/core/detectors/must/CbmMustModule.cxx
@@ -0,0 +1,78 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+/** CbmMustModule.cxx
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** This class holds geometry parameters of must modules
+ ** Based on CbmMuchModule by M.Ryzhinskiy <m.ryzhinskiy@gsi.de>
+ **
+ **/
+#include "CbmMustModule.h"
+
+#include <Logger.h>  // for LOG
+
+#include <TObject.h>   // for TObject
+#include <TVector3.h>  // for TVector3
+
+// -----   Default constructor   -------------------------------------------
+CbmMustModule::CbmMustModule() : TObject(), fDetectorId(0), fPosition(TVector3()), fDirection(TVector3()) {}
+// -------------------------------------------------------------------------
+
+
+// -----   Standard constructor   ------------------------------------------
+CbmMustModule::CbmMustModule(int iStation, int iLayer, int iModule, TVector3 position, TVector3 direction)
+  : TObject()
+  , fDetectorId(iStation * 1e7 + iLayer * 1e5 + iModule * 1e3)
+  , fPosition(position)
+  , fDirection(direction)
+{
+}
+// -------------------------------------------------------------------------
+
+CbmMustTube* CbmMustModule::FindTube(int detid)
+{
+  for (Int_t iobj = 0; iobj < fTubes.GetEntriesFast(); iobj++) {
+    CbmMustTube* tempTube = (CbmMustTube*) (fTubes.At(iobj));
+    if (tempTube->GetTubeNumber() == detid) return tempTube;
+  }
+  return nullptr;
+}
+
+bool CbmMustModule::AddTube(CbmMustTube* tube)
+{
+  for (Int_t iobj = 0; iobj < fTubes.GetEntriesFast(); iobj++) {
+    CbmMustTube* tempTube = (CbmMustTube*) (fTubes.At(iobj));
+    if (tempTube->GetTubeNumber() == tube->GetTubeNumber()) return false;
+  }
+  fTubes.Add(tube);
+  return true;
+}
+
+void CbmMustModule::Show()
+{
+  LOG(info) << "      Module " << fDetectorId << " (@ (" << fPosition.X() << "," << fPosition.Y() << ","
+            << fPosition.Z() << ") -> (" << fDirection.X() << "," << fDirection.Y() << "," << fDirection.Z() << "):";
+  std::string tubeString(128, '.');
+  std::string tubeNumbDec(128, '0');
+  std::string tubeNumbOne(128, '0');
+  for (Int_t iobj = 0; iobj < fTubes.GetEntriesFast(); iobj++) {
+    CbmMustTube* tempTube = (CbmMustTube*) (fTubes.At(iobj));
+    //        if ( iobj == 0 )
+    LOG(info) << "        Tube " << tempTube->GetDetectorId() << "  @ " << tempTube->GetPosition().X() << ","
+              << tempTube->GetPosition().Y() << "," << tempTube->GetPosition().Z() << " -> "
+              << tempTube->GetWireDirection().X() << "," << tempTube->GetWireDirection().Y() << ","
+              << tempTube->GetWireDirection().Z();
+    tubeNumbDec[iobj]                         = char(tempTube->GetTubeNumber() / 10 + 48);
+    tubeNumbOne[iobj]                         = char(tempTube->GetTubeNumber() % 10 + 48);
+    tubeString[tempTube->GetTubeNumber() - 1] = '*';
+  }
+  LOG(info) << "        Tubes " << tubeString;
+  LOG(info) << "            - " << tubeNumbDec;
+  LOG(info) << "            - " << tubeNumbOne;
+}
+
+ClassImp(CbmMustModule)
diff --git a/core/detectors/must/CbmMustModule.h b/core/detectors/must/CbmMustModule.h
new file mode 100644
index 0000000000000000000000000000000000000000..65f96123cc6ad2acb7ba8c5fc6c42d2c80487ff5
--- /dev/null
+++ b/core/detectors/must/CbmMustModule.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+/** CbmMustModule.h
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** This class holds geometry parameters of must modules
+ ** Based on CbmMuchModule by M.Ryzhinskiy <m.ryzhinskiy@gsi.de>
+ **
+ **/
+
+#ifndef CBMMUSTMODULE_H
+#define CBMMUSTMODULE_H 1
+
+#include "CbmMustTube.h"
+
+#include <Rtypes.h>      // for THashConsistencyHolder, ClassDef
+#include <RtypesCore.h>  // for Color_t
+#include <TObjArray.h>   // for TObjArray
+#include <TObject.h>     // for TObject
+#include <TVector3.h>    // for TVector3
+
+#include <map>      // for multimap
+#include <utility>  // for pair
+
+class CbmMustModule : public TObject {
+ public:
+  /** Default constructor **/
+  CbmMustModule();
+  /** Standard constructor
+     *@param iStation  Station index
+     *@param iLayer    Layer index
+     *@param iModule   Module index
+     *@param position  Location of the module center in global c.s. (all dimensions in [cm])
+     *@param direction Direction of the module
+     **/
+  CbmMustModule(int iStation, int iLayer, int iModule, TVector3 position, TVector3 direction);
+  /** Destructor **/
+  virtual ~CbmMustModule() {}
+
+  /** Accessors */
+  int GetDetectorId() const { return fDetectorId; }
+  TVector3 GetPosition() const { return fPosition; }
+  TVector3 GetDirection() const { return fDirection; }
+
+  int GetNTubes() const { return fTubes.GetEntriesFast(); }
+
+  CbmMustTube* GetTube(int iTube) const { return (CbmMustTube*) fTubes.At(iTube); }
+
+  CbmMustTube* FindTube(int detid);
+  bool AddTube(CbmMustTube* tube);
+  void SortTubes() { fTubes.Sort(); }
+  void Show();
+
+  virtual bool InitModule() { return kTRUE; }
+  virtual void DrawModule(Color_t) {}
+
+ protected:
+  int fDetectorId;      // Unique detector ID
+  TVector3 fPosition;   // Location vector of the module center in global c.s. (all dimensions in [cm])
+  TVector3 fDirection;  // Direction vector of the module
+  TObjArray fTubes;     // Array of CbmMustTubes
+
+ private:
+  CbmMustModule(const CbmMustModule&);
+  CbmMustModule& operator=(const CbmMustModule&);
+
+  ClassDef(CbmMustModule, 2);
+};
+#endif
diff --git a/core/detectors/must/CbmMustStation.cxx b/core/detectors/must/CbmMustStation.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b72c53e0570f0b588ebbf87403d719cc2c422477
--- /dev/null
+++ b/core/detectors/must/CbmMustStation.cxx
@@ -0,0 +1,76 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+/** CbmMustStation.cxx
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** This class holds the transport geometry parameters
+ ** of one Must tracking station.
+ ** Based on CbmMuchStation by M.Ryzhinskiy <m.ryzhinskiy@gsi.de>
+ **/
+#include "CbmMustStation.h"
+
+#include "CbmMustLayer.h"  // for CbmMustLayer
+
+#include <Logger.h>  // for LOG
+
+#include <TMathBase.h>  // for Abs
+#include <TObjArray.h>  // for TObjArray
+
+// -----   Default constructor   -------------------------------------------
+CbmMustStation::CbmMustStation() : TObject(), fDetectorId(0), fZ(0.), fLayers() {}
+// -------------------------------------------------------------------------
+
+// -----   Standard constructor   ------------------------------------------
+CbmMustStation::CbmMustStation(int iStation, double z) : TObject(), fDetectorId(iStation * 1e7), fZ(z), fLayers() {}
+// -------------------------------------------------------------------------
+
+// -----   Destructor   ----------------------------------------------------
+CbmMustStation::~CbmMustStation() {}
+// -------------------------------------------------------------------------
+
+CbmMustTube* CbmMustStation::GetTube(int detid)
+{
+  int layerid           = detid / 1e5 - 1;
+  CbmMustLayer* tempLay = GetLayer(layerid);
+  //    LOG(info) << "trying to get tube " << detid % 100000 << " from layer " << layerid;
+  return tempLay ? tempLay->GetTube(detid % 100000) : nullptr;
+}
+
+// -----   Public method AddSector   ---------------------------------------
+CbmMustLayer* CbmMustStation::FindLayer(int detid)
+{
+  for (Int_t iobj = 0; iobj < fLayers.GetEntriesFast(); iobj++) {
+    CbmMustLayer* tempLayer = (CbmMustLayer*) (fLayers.At(iobj));
+    if (tempLayer->GetDetectorId() == detid) return tempLayer;
+  }
+  return nullptr;
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method AddSector   ---------------------------------------
+bool CbmMustStation::AddLayer(CbmMustLayer* layer)
+{
+  for (Int_t iobj = 0; iobj < fLayers.GetEntriesFast(); iobj++) {
+    CbmMustLayer* tempLayer = (CbmMustLayer*) (fLayers.At(iobj));
+    if (tempLayer->GetDetectorId() == layer->GetDetectorId()) return false;
+  }
+
+  fLayers.Add(layer);
+  return true;
+}
+// -------------------------------------------------------------------------
+
+void CbmMustStation::Show()
+{
+  LOG(info) << "  Station " << fDetectorId << " (@ z = " << fZ << "):";
+  for (Int_t iobj = 0; iobj < fLayers.GetEntriesFast(); iobj++) {
+    CbmMustLayer* tempLayer = (CbmMustLayer*) (fLayers.At(iobj));
+    tempLayer->Show();
+  }
+}
+
+ClassImp(CbmMustStation)
diff --git a/core/detectors/must/CbmMustStation.h b/core/detectors/must/CbmMustStation.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f9ad649b3cbd533c60982a06bc406462ea593f8
--- /dev/null
+++ b/core/detectors/must/CbmMustStation.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+/** CbmMustStation.h
+ *@author  R.Karabowicz <r.karabowicz@gsi.de>
+ *@version 1.0
+ *@since   2025.01.08
+ **
+ ** This class holds the transport geometry parameters
+ ** of one Must tracking station.
+ ** Based on CbmMuchStation by M.Ryzhinskiy <m.ryzhinskiy@gsi.de>
+ **
+ **/
+
+
+#ifndef CBMMUSTSTATION_H
+#define CBMMUSTSTATION_H 1
+
+#include "CbmMustLayer.h"  // for CbmMustLayer
+#include "CbmMustTube.h"
+
+#include <Rtypes.h>     // for THashConsistencyHolder, ClassDef
+#include <TObjArray.h>  // for TObjArray
+#include <TObject.h>    // for TObject
+
+class CbmMustStation : public TObject {
+ public:
+  /** Default constructor **/
+  CbmMustStation();
+
+
+  /** Standard constructor
+  *@param iStation  Station index
+  *@param z         z position of station center in global cs [cm]
+  **/
+  CbmMustStation(int iStation, double z);
+
+
+  /** Destructor **/
+  virtual ~CbmMustStation();
+
+  /** Accessors **/
+  int GetDetectorId() const { return fDetectorId; }
+  double GetZ() const { return fZ; }
+  int GetNLayers() const { return fLayers.GetEntriesFast(); }
+
+  CbmMustTube* GetTube(int detid);
+
+  CbmMustLayer* GetLayer(int iLayer) const { return (CbmMustLayer*) fLayers.At(iLayer); }
+
+  /** Add one sector to the array **/
+  CbmMustLayer* FindLayer(int detid);
+  bool AddLayer(CbmMustLayer* layer);
+  void Show();
+
+ protected:
+  int fDetectorId;    // Unique detector ID
+  double fZ;          // z position of station center (midplane) [cm] in global cs
+  TObjArray fLayers;  // Array of CbmMustLayers
+  ClassDef(CbmMustStation, 1);
+};
+#endif
diff --git a/core/detectors/must/CbmMustTube.cxx b/core/detectors/must/CbmMustTube.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0481e23ccdec9e90f056362e64424b7e5a22e4c2
--- /dev/null
+++ b/core/detectors/must/CbmMustTube.cxx
@@ -0,0 +1,103 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmMustTube header file
+//
+// Copied from PndFtsTube
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+////////////////////////////////////////////////////////////////////////////
+
+#include "CbmMustTube.h"
+// standard
+#include <iostream>
+
+CbmMustTube::CbmMustTube()
+  : fCenPosition(TVector3(0, 0, 0))
+  , fRotationMatrix(TMatrixT<double>(3, 3))
+  , fRadIn(0)
+  , fRadOut(0)
+  , fHalfLength(0)
+{
+  fRotationMatrix[0][0] = -1.;
+  fRotationMatrix[0][1] = -1.;
+  fRotationMatrix[0][2] = -1.;
+
+  fRotationMatrix[1][0] = -1.;
+  fRotationMatrix[1][1] = -1.;
+  fRotationMatrix[1][2] = -1.;
+
+  fRotationMatrix[2][0] = -1.;
+  fRotationMatrix[2][1] = -1.;
+  fRotationMatrix[2][2] = -1.;
+}
+
+CbmMustTube::CbmMustTube(CbmMustTube& tube)
+  : TObject(tube)
+  , fTubeNumber(tube.GetTubeNumber())
+  , fCenPosition(tube.GetPosition())
+  , fRotationMatrix(TMatrixT<double>(3, 3))
+  , fRadIn(tube.GetRadIn())
+  , fRadOut(tube.GetRadOut())
+  , fHalfLength(tube.GetHalfLength())
+{
+  fRotationMatrix.ResizeTo(3, 3);
+  fRotationMatrix = tube.GetRotationMatrix();
+}
+
+CbmMustTube::CbmMustTube(int detectorId, int tubeNumber, Double_t x, Double_t y, Double_t z, Double_t r11, Double_t r12,
+                         Double_t r13, Double_t r21, Double_t r22, Double_t r23, Double_t r31, Double_t r32,
+                         Double_t r33, Double_t radin, Double_t radout, Double_t hl)
+  : fDetectorId(detectorId)
+  , fTubeNumber(tubeNumber)
+  , fCenPosition(TVector3(x, y, z))
+  , fRotationMatrix(TMatrixT<double>(3, 3))
+  , fRadIn(radin)
+  , fRadOut(radout)
+  , fHalfLength(hl)
+{
+
+  fRotationMatrix[0][0] = r11;
+  fRotationMatrix[0][1] = r12;
+  fRotationMatrix[0][2] = r13;
+
+  fRotationMatrix[1][0] = r21;
+  fRotationMatrix[1][1] = r22;
+  fRotationMatrix[1][2] = r23;
+
+  fRotationMatrix[2][0] = r31;
+  fRotationMatrix[2][1] = r32;
+  fRotationMatrix[2][2] = r33;
+}
+
+CbmMustTube::~CbmMustTube()
+{
+  //  fCenPosition.Delete();
+  //  fRotationMatrix.Delete();
+}
+
+TVector3 CbmMustTube::GetPosition() const { return fCenPosition; }
+
+TMatrixT<Double_t> CbmMustTube::GetRotationMatrix() const { return fRotationMatrix; }
+
+Double_t CbmMustTube::GetRadIn() const { return fRadIn; }
+
+Double_t CbmMustTube::GetRadOut() const { return fRadOut; }
+
+Double_t CbmMustTube::GetHalfLength() const { return fHalfLength; }
+
+TVector3 CbmMustTube::GetWireDirection() const
+{
+  return TVector3(-fRotationMatrix[0][1], fRotationMatrix[1][1], fRotationMatrix[2][1]);
+}
+
+Int_t CbmMustTube::Compare(const TObject* obj) const
+{
+  if (((CbmMustTube*) obj)->GetTubeNumber() == this->GetTubeNumber()) return 0;
+  if (((CbmMustTube*) obj)->GetTubeNumber() < this->GetTubeNumber()) return 1;
+  return -1;
+}
+
+ClassImp(CbmMustTube)
diff --git a/core/detectors/must/CbmMustTube.h b/core/detectors/must/CbmMustTube.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae5d3bf291c6db38b7cb8de89abe806d8d078dec
--- /dev/null
+++ b/core/detectors/must/CbmMustTube.h
@@ -0,0 +1,57 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmMustTube header file
+//
+// Copied from PndFtsTube
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef CBMMUSTTUBE_H
+#define CBMMUSTTUBE_H 1
+
+// from ROOT
+#include "TMatrixT.h"
+#include "TObject.h"
+#include "TVector3.h"
+
+class CbmMustTube : public TObject {
+
+ public:
+  /** Default constructor **/
+  CbmMustTube();
+  CbmMustTube(CbmMustTube& tube);
+
+  ~CbmMustTube();
+  CbmMustTube(int detectorId, int tubeNumber, Double_t x, Double_t y, Double_t z, Double_t r11, Double_t r12,
+              Double_t r13, Double_t r21, Double_t r22, Double_t r23, Double_t r31, Double_t r32, Double_t r33,
+              Double_t radin, Double_t radout, Double_t hl);
+
+  int GetDetectorId() const { return fDetectorId; }
+  int GetTubeNumber() const { return fTubeNumber; }
+  TVector3 GetPosition() const;
+  TMatrixT<Double_t> GetRotationMatrix() const;
+  Double_t GetRadIn() const;
+  Double_t GetRadOut() const;
+  Double_t GetHalfLength() const;
+  TVector3 GetWireDirection() const;
+
+  bool IsSkew() const { return (0. != GetWireDirection().X()); }
+
+  Int_t Compare(const TObject* obj) const override;
+  Bool_t IsSortable() const override { return kTRUE; }
+
+ private:
+  int fDetectorId{0};
+  int fTubeNumber{0};
+  TVector3 fCenPosition;
+  TMatrixT<double> fRotationMatrix;
+  Double_t fRadIn, fRadOut, fHalfLength;
+
+  ClassDef(CbmMustTube, 1);
+};
+
+#endif
diff --git a/macro/must/run_digi.C b/macro/must/run_digi.C
new file mode 100644
index 0000000000000000000000000000000000000000..81a01e16f4f5250221e4064c817bb802e6f88632
--- /dev/null
+++ b/macro/must/run_digi.C
@@ -0,0 +1,91 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+#include <TStopwatch.h>
+#include <TString.h>
+
+#include <iostream>
+#include <memory>
+
+using std::cout;
+using std::endl;
+
+void run_digi()
+{
+  FairLogger* logger = FairLogger::GetLogger();
+  // logger->SetLogFileName("MyLog.log");
+  // logger->SetLogToScreen(kTRUE);
+  //  logger->SetLogToFile(kTRUE);
+  logger->SetLogVerbosityLevel("LOW");
+  //  logger->SetLogFileLevel("DEBUG4");
+  //  logger->SetLogScreenLevel("DEBUG");
+
+  // Verbosity level (0=quiet, 1=event level, 2=track level, 3=debug)
+  Int_t iVerbose = 0;  // just forget about it, for the moment
+
+  // Input file (MC events)
+  TString inFile = "points.root";
+
+  // Parameter file
+  TString parFile = "params.root";
+
+  // Output file
+  TString outFile = "digis.root";
+
+  // -----   Timer   --------------------------------------------------------
+  TStopwatch timer;
+
+  // -----   Reconstruction run   -------------------------------------------
+  FairRunAna run{};
+  FairFileSource* fFileSource = new FairFileSource(inFile);
+  run.SetSource(fFileSource);
+  run.SetSink(std::make_unique<FairRootFileSink>(outFile));
+  run.SetUseFairLinks(kTRUE);
+  FairLinkManager::Instance()->AddIncludeType(0);
+  //  FairLinkManager::Instance()->AddIncludeType(1);
+  run.SetGenerateRunInfo(kTRUE);  // Create FairRunInfo file
+
+  FairRuntimeDb* rtdb          = run.GetRuntimeDb();
+  FairParRootFileIo* parInput1 = new FairParRootFileIo();
+  parInput1->open(parFile.Data());
+  rtdb->setFirstInput(parInput1);
+
+  // -----   TorinoDetector hit  producers   ---------------------------------
+  CbmMustDigitize* digiTask = new CbmMustDigitize();
+  run.AddTask(digiTask);
+
+  run.Init();
+
+  timer.Start();
+  run.Run();
+
+  // -----   Finish   -------------------------------------------------------
+
+  cout << endl << endl;
+
+  // Extract the maximal used memory an add is as Dart measurement
+  // This line is filtered by CTest and the value send to CDash
+  FairSystemInfo sysInfo;
+  Float_t maxMemory = sysInfo.GetMaxMemory();
+  cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
+  cout << maxMemory;
+  cout << "</DartMeasurement>" << endl;
+
+  timer.Stop();
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+
+  Float_t cpuUsage = ctime / rtime;
+  cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
+  cout << cpuUsage;
+  cout << "</DartMeasurement>" << endl;
+
+  cout << endl << endl;
+  cout << "Output file is " << outFile << endl;
+  cout << "Parameter file is " << parFile << endl;
+  cout << "Real time " << rtime << " s, CPU time " << ctime << "s" << endl << endl;
+  cout << "Macro finished successfully." << endl;
+
+  // ------------------------------------------------------------------------
+}
diff --git a/macro/must/run_hit.C b/macro/must/run_hit.C
new file mode 100644
index 0000000000000000000000000000000000000000..de6a780034cda80d7e90148a6ed70aef359157a8
--- /dev/null
+++ b/macro/must/run_hit.C
@@ -0,0 +1,91 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+#include <TStopwatch.h>
+#include <TString.h>
+
+#include <iostream>
+#include <memory>
+
+using std::cout;
+using std::endl;
+
+void run_hit()
+{
+  FairLogger* logger = FairLogger::GetLogger();
+  // logger->SetLogFileName("MyLog.log");
+  // logger->SetLogToScreen(kTRUE);
+  //  logger->SetLogToFile(kTRUE);
+  logger->SetLogVerbosityLevel("LOW");
+  //  logger->SetLogFileLevel("DEBUG4");
+  //  logger->SetLogScreenLevel("DEBUG");
+
+  // Verbosity level (0=quiet, 1=event level, 2=track level, 3=debug)
+  Int_t iVerbose = 0;  // just forget about it, for the moment
+
+  // Input file (MC events)
+  TString inFile = "digis.root";
+
+  // Parameter file
+  TString parFile = "params.root";
+
+  // Output file
+  TString outFile = "hits.root";
+
+  // -----   Timer   --------------------------------------------------------
+  TStopwatch timer;
+
+  // -----   Reconstruction run   -------------------------------------------
+  FairRunAna run{};
+  FairFileSource* fFileSource = new FairFileSource(inFile);
+  run.SetSource(fFileSource);
+  run.SetSink(std::make_unique<FairRootFileSink>(outFile));
+  run.SetUseFairLinks(kTRUE);
+  FairLinkManager::Instance()->AddIncludeType(0);
+  //  FairLinkManager::Instance()->AddIncludeType(1);
+  run.SetGenerateRunInfo(kTRUE);  // Create FairRunInfo file
+
+  FairRuntimeDb* rtdb          = run.GetRuntimeDb();
+  FairParRootFileIo* parInput1 = new FairParRootFileIo();
+  parInput1->open(parFile.Data());
+  rtdb->setFirstInput(parInput1);
+
+  // -----   TorinoDetector hit  producers   ---------------------------------
+  CbmMustFindHits* hitTask = new CbmMustFindHits();
+  run.AddTask(hitTask);
+
+  run.Init();
+
+  timer.Start();
+  run.Run();
+
+  // -----   Finish   -------------------------------------------------------
+
+  cout << endl << endl;
+
+  // Extract the maximal used memory an add is as Dart measurement
+  // This line is filtered by CTest and the value send to CDash
+  FairSystemInfo sysInfo;
+  Float_t maxMemory = sysInfo.GetMaxMemory();
+  cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
+  cout << maxMemory;
+  cout << "</DartMeasurement>" << endl;
+
+  timer.Stop();
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+
+  Float_t cpuUsage = ctime / rtime;
+  cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
+  cout << cpuUsage;
+  cout << "</DartMeasurement>" << endl;
+
+  cout << endl << endl;
+  cout << "Output file is " << outFile << endl;
+  cout << "Parameter file is " << parFile << endl;
+  cout << "Real time " << rtime << " s, CPU time " << ctime << "s" << endl << endl;
+  cout << "Macro finished successfully." << endl;
+
+  // ------------------------------------------------------------------------
+}
diff --git a/macro/must/run_sim.C b/macro/must/run_sim.C
new file mode 100644
index 0000000000000000000000000000000000000000..07233784a204d9b142f6e83b8d467f9e204cf141
--- /dev/null
+++ b/macro/must/run_sim.C
@@ -0,0 +1,134 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+int run_sim(Int_t nEvents = 10, Int_t pid = 13, Float_t p1 = 10.0, Float_t p2 = 10.0)
+{
+  // 2212 proton
+  TStopwatch timer;
+  timer.Start();
+  gDebug = 0;
+
+  TString dir = getenv("VMCWORKDIR");
+
+  TString tut_configdir = dir + "/sim/transport/gconfig/";
+  gSystem->Setenv("CONFIG_DIR", tut_configdir.Data());
+
+  FairRunSim* fRun = new FairRunSim();
+
+  // set the MC version used
+  fRun->SetName("TGeant4");
+
+  // Cave geometry
+  TString caveGeom = "cave.geo";
+  // Target geometry
+  TString targetGeom = "tpassive/targetbox_v22c.gdml";
+  // Beam pipe geometry
+  TString pipeGeom = "pipe/pipe_v22d.geo.root";
+  // Magnet geometry and field map
+  TString magnetGeom  = "magnet/magnet_v22b.geo.root";
+  TString fieldMap    = "field_v22d";
+  Double_t fieldZ     = 50.;  // z position of field centre
+  Double_t fieldScale = 1.;   // field scaling factor
+
+  std::string outFile = "points.root";
+  std::string parFile = "params.root";
+
+  fRun->SetSink(new FairRootFileSink(outFile));
+
+  // Fill the Parameter containers for this run
+  //-------------------------------------------
+
+  FairRuntimeDb* rtdb       = fRun->GetRuntimeDb();
+  Bool_t kParameterMerged   = kTRUE;
+  FairParRootFileIo* output = new FairParRootFileIo(kParameterMerged);
+  output->open(parFile.c_str());
+  rtdb->setOutput(output);
+
+  // Set Material file Name
+  fRun->SetMaterials("media.geo");
+
+
+  // -----   Create geometry   ----------------------------------------------
+  FairModule* cave = new CbmCave("CAVE");
+  cave->SetGeometryFileName(caveGeom);
+  fRun->AddModule(cave);
+
+  FairModule* pipe = new CbmPipe("PIPE");
+  pipe->SetGeometryFileName(pipeGeom);
+  fRun->AddModule(pipe);
+
+  //  FairModule* target = new CbmTarget("Target");
+  //  target->SetGeometryFileName(targetGeom);
+  //  fRun->AddModule(target);
+
+  FairModule* magnet = new CbmMagnet("MAGNET");
+  magnet->SetGeometryFileName(magnetGeom);
+  fRun->AddModule(magnet);
+
+  FairDetector* must = new CbmMust("MUST", kTRUE);
+  must->SetGeometryFileName("must/must_v24a_mcbm.geo.root");
+  fRun->AddModule(must);
+
+  // Create and Set Event Generator
+  //-------------------------------
+
+  FairPrimaryGenerator* primGen = new FairPrimaryGenerator();
+  fRun->SetGenerator(primGen);
+
+  // Box Generator
+  FairBoxGenerator* boxGen = new FairBoxGenerator(pid, 100);  // 13=muon; 2212=proton 1 = multipl.
+  if (p2 < 0.) p2 = p1;
+  boxGen->SetPRange(p1, p2);      // GeV/c //setPRange vs setPtRange
+  boxGen->SetPhiRange(270, 450);  // Azimuth angle range [degree]
+  boxGen->SetThetaRange(6, 22);   // Polar angle in lab system range [degree]
+  boxGen->SetCosTheta();
+  boxGen->SetXYZ(0., 0., 0.);
+  primGen->AddGenerator(boxGen);
+
+  fRun->SetStoreTraj(kTRUE);
+  fRun->SetBeamMom(15.);
+
+  // -----   Create magnetic field   ----------------------------------------
+  CbmFieldMap* magField = new CbmFieldMapSym3(fieldMap);
+  magField->SetPosition(0., 0., fieldZ);
+  magField->SetScale(fieldScale);
+  fRun->SetField(magField);
+
+  fRun->Init();
+
+  // Transport nEvents
+  // -----------------
+  fRun->Run(nEvents);
+
+  rtdb->saveOutput();
+  rtdb->print();
+
+  timer.Stop();
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+  printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime);
+
+  TChain chain("cbmsim");
+  chain.Add(outFile.c_str());
+  auto nofE = chain.GetEntries();
+  auto nofT = chain.Draw("MCTrack.fPx", "", "goff");
+  auto nofP = chain.Draw("MUSTPoint.fPx", "", "goff");
+  cout << "Output chain has " << nofE << " events, " << nofT << " tracks, " << nofP << " points." << endl;
+
+  if (nofE < nEvents) {
+    std::cerr << "Not enough events (" << nofE << " < " << nEvents << ") in the output chain." << endl;
+    return 1;
+  }
+  if (nofT < nEvents) {
+    std::cerr << "Not enough tracks (" << nofT << " < " << nEvents << ") in the output chain." << endl;
+    return 1;
+  }
+  if (nofP < nEvents * 10) {
+    std::cerr << "Not enough points (" << nofP << " < " << nEvents * 10 << ") in the output chain." << endl;
+    return 1;
+  }
+  cout << "Simulation successful." << endl;
+
+  return 0;
+}
diff --git a/reco/detectors/CMakeLists.txt b/reco/detectors/CMakeLists.txt
index 3b70d1eded69c93bc705a925f5e989f8ccf731e7..0cf3fa93893ce71d50f2c4ef811f10fa7439c25c 100644
--- a/reco/detectors/CMakeLists.txt
+++ b/reco/detectors/CMakeLists.txt
@@ -3,6 +3,7 @@
 
 add_subdirectory(bmon)
 add_subdirectory(much)
+add_subdirectory(must)
 add_subdirectory(mvd)
 add_subdirectory(psd)
 add_subdirectory(fsd)
diff --git a/reco/detectors/must/CMakeLists.txt b/reco/detectors/must/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..539d73343a913bd6cfe22256813e0e99e6413ca1
--- /dev/null
+++ b/reco/detectors/must/CMakeLists.txt
@@ -0,0 +1,39 @@
+set(INCLUDE_DIRECTORIES
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  )
+
+set(SRCS
+  CbmMustFindHits.cxx
+  )
+
+
+set(LIBRARY_NAME CbmMustReco)
+set(LINKDEF ${LIBRARY_NAME}LinkDef.h)
+set(PUBLIC_DEPENDENCIES
+  CbmData
+  CbmMustBase
+  CbmRecoBase
+  FairRoot::Base
+  ROOT::Core
+  ROOT::Hist
+  )
+
+set(PRIVATE_DEPENDENCIES
+  CbmBase
+  CbmQaBase
+  FairRoot::ParBase
+  ROOT::Gpad
+  ROOT::Graf
+  ROOT::MathCore
+  ROOT::Physics
+  ROOT::RHTTP
+  ROOT::RIO
+  )
+
+set(INTERFACE_DEPENDENCIES
+  FairLogger::FairLogger
+  external::fles_ipc
+  )
+
+
+generate_cbm_library()
diff --git a/reco/detectors/must/CbmMustFindHits.cxx b/reco/detectors/must/CbmMustFindHits.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8c86fb4e3ab79d20e6ea566f5129c58f247e2c90
--- /dev/null
+++ b/reco/detectors/must/CbmMustFindHits.cxx
@@ -0,0 +1,105 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustFindHits source file              -----
+// -----                  Created 2025-01-30 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+/** @file CbmMustFindHits.cxx
+ ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de>
+ ** @since 30.01.2025
+ **/
+#include "CbmMustFindHits.h"
+
+#include "CbmMustDigi.h"
+#include "CbmMustHit.h"
+#include "CbmMustTube.h"
+#include "FairRootManager.h"
+#include "TFile.h"
+#include "TMath.h"
+#include "TStopwatch.h"
+
+#include <algorithm>
+#include <iomanip>
+#include <iostream>
+
+using std::cout;
+using std::endl;
+using std::fixed;
+using std::left;
+using std::multimap;
+using std::right;
+using std::setw;
+using std::vector;
+
+// -------------------------------------------------------------------------
+CbmMustFindHits::CbmMustFindHits() : FairTask("MustFindHits", 1) {}
+
+// -----   Destructor   ----------------------------------------------------
+CbmMustFindHits::~CbmMustFindHits() {}
+// -------------------------------------------------------------------------
+
+// -----   Task execution   ------------------------------------------------
+void CbmMustFindHits::Exec(Option_t* /*opt*/)
+{
+  assert(fDigiArray);
+  fHitArray->Delete();
+
+  //    LOG(info) << "got " << fDigiArray->GetEntriesFast() << " points";
+  for (Int_t iDigi = 0; iDigi < fDigiArray->GetEntriesFast(); iDigi++) {
+    const CbmMustDigi* digi = (const CbmMustDigi*) fDigiArray->At(iDigi);
+    if (!digi) LOG(info) << "no digi";
+    auto isochrone = GetIsochrone(digi);
+
+    //        LOG(info) << "trying to get tube number " << digi->GetDetectorId();
+    CbmMustTube* tube = fGeoScheme->GetTube(digi->GetDetectorId());
+    if (!tube) LOG(info) << "no tube";
+
+    CbmMustHit* hit = new ((*fHitArray)[iDigi]) CbmMustHit(
+      7, digi->GetDetectorId(), digi->GetSkewed(), 0, tube->GetPosition(), {0., 0., 0.}, tube->GetWireDirection(),
+      digi->GetSignalTime(), isochrone.first, isochrone.second, digi->GetDepCharge());
+  }
+}
+// -------------------------------------------------------------------------
+
+// -----   Private function to get isochronoe   ----------------------------
+std::pair<double, double> CbmMustFindHits::GetIsochrone(const CbmMustDigi* digi)
+{
+  return std::pair<double, double>(digi->GetSignalTime() / 400., digi->GetSignalError() / 400.);
+}
+// -------------------------------------------------------------------------
+
+
+// -----   Initialisation    -----------------------------------------------
+InitStatus CbmMustFindHits::Init()
+{
+  FairRootManager* ioman = FairRootManager::Instance();
+  if (!ioman) {
+    std::cout << "-E- CbmMustFindHits::Init: "  /// todo replace with logger!
+              << "RootManager not instantiated!" << std::endl;
+    return kFATAL;
+  }
+
+  fDigiArray = static_cast<TClonesArray*>(ioman->GetObject("MUSTDigi"));
+  if (!fDigiArray) {
+    std::cout << "-W- CbmMustFindHits::Init: "
+              << "No Digi array!" << std::endl;
+    return kERROR;
+  }
+
+  // Create and register output array
+  fHitArray = new TClonesArray("CbmMustHit");
+  ioman->Register("MUSTHit", "MUST", fHitArray, kTRUE);
+
+  fGeoScheme = CbmMustGeoScheme::Instance();
+  fGeoScheme->Init("$VMCWORKDIR/parameters/must/must_geoScheme.root");
+
+  fGeoScheme->Show();
+
+  return kSUCCESS;
+}
+// -------------------------------------------------------------------------
+
+ClassImp(CbmMustFindHits)
diff --git a/reco/detectors/must/CbmMustFindHits.h b/reco/detectors/must/CbmMustFindHits.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce883f2a729394db1464903e1b16320c2ee6e4ae
--- /dev/null
+++ b/reco/detectors/must/CbmMustFindHits.h
@@ -0,0 +1,48 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustFindHits header file              -----
+// -----                  Created 2025-01-30 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+/** @file CbmMustDigitize.cxx
+ ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de>
+ ** @since 30.01.2025
+ **/
+
+#ifndef CBMMUSTFINDHITS_H
+#define CBMMUSTFINDHITS_H 1
+
+#include "CbmMustDigi.h"
+#include "CbmMustGeoScheme.h"
+#include "FairTask.h"
+#include "TClonesArray.h"
+#include "TString.h"
+
+#include <vector>
+
+class CbmMustFindHits : public FairTask {
+ public:
+  CbmMustFindHits();
+  virtual ~CbmMustFindHits();
+  virtual void Exec(Option_t* opt);
+
+ private:
+  virtual InitStatus Init();
+  TString fDigiFile = "must_geoScheme.root";  // Digitization file
+
+  TClonesArray* fDigiArray{nullptr};
+  TClonesArray* fHitArray{nullptr};
+  CbmMustGeoScheme* fGeoScheme{nullptr};  // Geometry scheme
+
+  std::pair<double, double> GetIsochrone(const CbmMustDigi* digi);
+
+  CbmMustFindHits(const CbmMustFindHits&);
+  CbmMustFindHits operator=(const CbmMustFindHits&);
+
+  ClassDef(CbmMustFindHits, 1);
+};
+
+#endif
diff --git a/reco/detectors/must/CbmMustRecoLinkDef.h b/reco/detectors/must/CbmMustRecoLinkDef.h
new file mode 100644
index 0000000000000000000000000000000000000000..2da13a8a0684b39b14242e6004eca012af64d135
--- /dev/null
+++ b/reco/detectors/must/CbmMustRecoLinkDef.h
@@ -0,0 +1,13 @@
+/* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Florian Uhlig [committer] */
+
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class CbmMustFindHits + ;
+
+#endif
diff --git a/sim/detectors/CMakeLists.txt b/sim/detectors/CMakeLists.txt
index aa91290cdd33469512652d8b7ca4ce8283d5587d..ebbc2b7d867004821a2940ce36ad44abb2282ebc 100644
--- a/sim/detectors/CMakeLists.txt
+++ b/sim/detectors/CMakeLists.txt
@@ -10,3 +10,4 @@ add_subdirectory(tof)
 add_subdirectory(fsd)
 add_subdirectory(psd)
 add_subdirectory(bmon)
+add_subdirectory(must)
diff --git a/sim/detectors/must/CMakeLists.txt b/sim/detectors/must/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4bc2ceb0b272f280e83953e397a0299fef3c9a5b
--- /dev/null
+++ b/sim/detectors/must/CMakeLists.txt
@@ -0,0 +1,36 @@
+set(INCLUDE_DIRECTORIES
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  )
+
+
+set(SRCS
+  CbmMust.cxx
+  CbmMustDigitize.cxx
+  )
+
+
+set(LIBRARY_NAME CbmMustSim)
+set(LINKDEF ${LIBRARY_NAME}LinkDef.h)
+set(PUBLIC_DEPENDENCIES
+  CbmBase
+  CbmData
+  CbmMustBase
+  FairRoot::Base
+  ROOT::Core
+  ROOT::Hist
+  ROOT::MathCore
+  )
+
+set(PRIVATE_DEPENDENCIES
+  CbmSimBase
+  FairRoot::ParBase
+  ROOT::EG
+  ROOT::Geom
+  ROOT::Gpad
+  ROOT::Physics
+  ROOT::RIO
+  )
+
+generate_cbm_library()
+
+
diff --git a/sim/detectors/must/CbmMust.cxx b/sim/detectors/must/CbmMust.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a82f025c17e46f8d489df0360dac4e8ec7db6710
--- /dev/null
+++ b/sim/detectors/must/CbmMust.cxx
@@ -0,0 +1,482 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmMust source file
+//
+// Class for simulation of MUST
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmMust by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#include "CbmMust.h"
+// from CbmRoot, this library
+#include "CbmDefs.h"
+#include "CbmGeoMust.h"
+#include "CbmGeoMustPar.h"
+#include "CbmMustGeoScheme.h"
+#include "CbmMustLayer.h"
+#include "CbmMustModule.h"
+#include "CbmMustStation.h"
+#include "CbmMustTube.h"
+#include "CbmStack.h"
+// from CbmRoot
+#include "CbmGeometryUtils.h"
+// from FairRoot
+#include <FairGeoInterface.h>
+#include <FairGeoLoader.h>
+#include <FairGeoNode.h>
+#include <FairGeoRootBuilder.h>
+#include <FairLogger.h>
+#include <FairRootManager.h>
+#include <FairRun.h>
+#include <FairRuntimeDb.h>
+#include <FairVolume.h>
+// from ROOT
+#include <TClonesArray.h>
+#include <TGeoMatrix.h>
+#include <TGeoMedium.h>
+#include <TGeoTube.h>
+#include <TGeoVolume.h>
+#include <TLorentzVector.h>
+#include <TObjArray.h>
+#include <TParticle.h>
+#include <TVirtualMC.h>
+// standard
+#include <iostream>
+
+using std::string;
+
+// TODO: read this from geant initialization
+#define innerStrawDiameter 1.
+// #define redefineLambdaChargedDecay 0
+
+// -----   Default constructor   -------------------------------------------
+CbmMust::CbmMust()
+  : fTrackID(0)
+  , fVolumeID(0)
+  , fPos(0, 0, 0, 0)
+  , fPosIn(0, 0, 0, 0)
+  , fPosOut(0, 0, 0, 0)
+  , fPosInLocal(0, 0, 0, 0)
+  , fPosOutLocal(0, 0, 0, 0)
+  , fMomIn(0, 0, 0, 0)
+  , fMomOut(0, 0, 0, 0)
+  , fTime(0)
+  , fLength(0)
+  , fELoss(0)
+  , fMass(0)
+  , fIsInitialized(kFALSE)
+  , fPosIndex(0)
+  , fMustCollection(nullptr)
+  , fpostot(0, 0, 0, 0)
+  , fpostotin(0, 0, 0, 0)
+  , fpostotout(0, 0, 0, 0)
+  , fPassNodes()
+  , valid(kFALSE)
+  , fGeoType(0)
+{
+  fMustCollection = new TClonesArray("CbmMustPoint");
+  fVerboseLevel   = 0;
+}
+// -------------------------------------------------------------------------
+
+// -----   Standard constructor   ------------------------------------------
+CbmMust::CbmMust(const char* name, Bool_t active)
+  : FairDetector(name, active)
+  , fTrackID(0)
+  , fVolumeID(0)
+  , fPos(0, 0, 0, 0)
+  , fPosIn(0, 0, 0, 0)
+  , fPosOut(0, 0, 0, 0)
+  , fPosInLocal(0, 0, 0, 0)
+  , fPosOutLocal(0, 0, 0, 0)
+  , fMomIn(0, 0, 0, 0)
+  , fMomOut(0, 0, 0, 0)
+  , fTime(0)
+  , fLength(0)
+  , fELoss(0)
+  , fMass(0)
+  , fIsInitialized(kFALSE)
+  , fPosIndex(0)
+  , fMustCollection(nullptr)
+  , fpostot(0, 0, 0, 0)
+  , fpostotin(0, 0, 0, 0)
+  , fpostotout(0, 0, 0, 0)
+  , fPassNodes()
+  , valid(kFALSE)
+  , fGeoType(0)
+{
+  fMustCollection = new TClonesArray("CbmMustPoint");
+  fVerboseLevel   = 0;
+  fGeoType        = 1;  // CHECK
+}
+// -------------------------------------------------------------------------
+
+// -----   Destructor   ----------------------------------------------------
+CbmMust::~CbmMust()
+{
+  if (fMustCollection) {
+    fMustCollection->Delete();
+    delete fMustCollection;
+  }
+}
+// -------------------------------------------------------------------------
+
+// -----   Private method GetSquaredDistanceFromWire -----------------------
+float CbmMust::GetSquaredDistanceFromWire()
+{
+  TLorentzVector entryPosition;
+
+  float positionInMother[3], positionInStraw[3];
+
+  gMC->TrackPosition(entryPosition);
+  positionInMother[0] = entryPosition.X();
+  positionInMother[1] = entryPosition.Y();
+  positionInMother[2] = entryPosition.Z();
+  gMC->Gmtod(positionInMother, positionInStraw, 1);
+
+  return positionInStraw[0] * positionInStraw[0] + positionInStraw[1] * positionInStraw[1];
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method ProcessHits  --------------------------------------
+Bool_t CbmMust::ProcessHits(FairVolume* vol)
+{
+  //    LOG(info) << "ProcessHits called!";
+  // TParticle* particle =  gMC->GetStack()->GetCurrentTrack(); //[R.K. 01/2017] unused variable?
+  // TGeoMedium *medium = (TGeoMedium*) vol->getGeoNode()->getRootVolume()->GetMedium(); //[R.K. 01/2017] unused variable?
+  // Double_t epsil = medium->GetParam(6); //[R.K. 01/2017] unused variable?
+
+  TString vol_name(gMC->CurrentVolName());
+  TGeoHMatrix M;
+  gMC->GetTransformation(gMC->CurrentVolPath(), M);
+  TString name(gMC->CurrentVolName());
+  //  LOG(info) << "\"" << gMC->CurrentVolPath() << "\" - \"" << gMC->CurrentVolName() << "\"";
+  if (gMC->TrackCharge() != 0.) {
+
+    if (gMC->IsTrackEntering()) {
+      valid = kTRUE;
+
+      // Set parameters at entrance of volume. Reset ELoss.
+      fELoss  = 0.;
+      fTime   = gMC->TrackTime() * 1.0e09;
+      fLength = gMC->TrackLength();
+      gMC->TrackPosition(fPos);
+      gMC->TrackMomentum(fMomIn);
+      gMC->TrackPosition(fpostotin);         // da cancellare
+      Double_t globalPos[3] = {0., 0., 0.};  // stt1 modified
+      Double_t localPos[3]  = {0., 0., 0.};  // stt1 modified
+
+      globalPos[0] = fPos.X();
+      globalPos[1] = fPos.Y();
+      globalPos[2] = fPos.Z();
+
+      gMC->Gmtod(globalPos, localPos, 1);
+      fPosInLocal.SetXYZM(localPos[0], localPos[1], localPos[2], 0.0);
+    }
+
+    // Sum energy loss for all steps in the active volume
+    fELoss += gMC->Edep();
+
+    // Create CbmMustPoint at exit of active volume -- but not into the wire
+    if (gMC->IsTrackExiting() && valid == kTRUE) {
+      valid     = kFALSE;
+      fTrackID  = gMC->GetStack()->GetCurrentTrackNumber();
+      fVolumeID = static_cast<int>(ECbmModuleId::kEcal);  // vol->getMCid();
+
+      if (fTrackID != 0) {
+        if (fVerboseLevel > 2) LOG(info) << "[MUST] test Vol----------" << vol->getMCid();
+        if (fVerboseLevel > 2) LOG(info) << "fTrackID-----" << fTrackID;
+      }
+
+      fMass = gMC->TrackMass();  // mass (GeV)
+      gMC->TrackPosition(fPosOut);
+      gMC->TrackMomentum(fMomOut);
+      gMC->TrackPosition(fpostotout);        // da cancellare
+      Double_t globalPos[3] = {0., 0., 0.};  // stt1 modified
+      Double_t localPos[3]  = {0., 0., 0.};  // stt1 modified
+
+      gMC->Gdtom(localPos, globalPos, 1);
+
+      fPos.SetXYZM(globalPos[0], globalPos[1], globalPos[2], 0.0);
+
+      globalPos[0] = fPosOut.X();
+      globalPos[1] = fPosOut.Y();
+      globalPos[2] = fPosOut.Z();
+
+      gMC->Gmtod(globalPos, localPos, 1);
+      fPosOutLocal.SetXYZM(localPos[0], localPos[1], localPos[2], 0.0);
+
+      string volPath(gMC->CurrentVolPath());
+
+      fpostot.SetXYZM((fpostotin.X() + fpostotout.X()) / 2., (fpostotin.Y() + fpostotout.Y()) / 2.,
+                      (fpostotin.Z() + fpostotout.Z()) / 2., 0.0);
+
+      LOG(debug) << " --> " << volPath;
+      string strawName = volPath.substr(volPath.find("strawAssembly_") + 14, 8);
+      int statId       = 1;
+      int layerId      = atoi(strawName.substr(1, 2).c_str());
+      int moduleId     = atoi(strawName.substr(3, 2).c_str());
+      int strawId      = atoi(strawName.substr(5, 3).c_str());
+
+      if (1 == 0) {
+        CbmMustGeoScheme* mustGeoScheme = CbmMustGeoScheme::Instance();
+        // add station
+        int detId                   = statId * 1e7;
+        CbmMustStation* mustStation = mustGeoScheme->FindStation(detId);
+        if (!mustStation) {
+          LOG(info) << "STATION --> " << volPath;
+          string statPath = volPath.substr(0, volPath.find("/layer"));
+          LOG(info) << "STATION --> " << statPath;
+          mustGeoScheme->NavigateTo(statPath);
+          TVector3 globPos = mustGeoScheme->GetGlobal();
+          mustStation      = new CbmMustStation(statId, globPos[2]);  // change z!
+        }
+        mustGeoScheme->AddStation(mustStation);
+        // add layer
+        detId                   = detId + layerId * 1e5;
+        CbmMustLayer* mustLayer = mustStation->FindLayer(detId);
+        if (!mustLayer) {
+          LOG(info) << "LAYER --> " << volPath;
+          string layerPath = volPath.substr(0, volPath.find("/module"));
+          LOG(info) << "LAYER --> " << layerPath;
+          mustGeoScheme->NavigateTo(volPath);
+          TVector3 globPos = mustGeoScheme->GetGlobal();
+          mustLayer        = new CbmMustLayer(statId, layerId, globPos[2], globPos[2] - mustStation->GetZ());
+        }
+        mustStation->AddLayer(mustLayer);
+        // add module
+        detId                     = detId + moduleId * 1e3;
+        CbmMustModule* mustModule = mustLayer->FindModule(detId);
+        TVector3 directionVector(0., 1., 0.);
+        if (layerId == 2 || layerId == 3) {
+          double angle = 5. * TMath::DegToRad();
+          if (layerId == 3) angle = -angle;
+          directionVector[0] = TMath::Sin(angle);
+          directionVector[1] = TMath::Cos(angle);
+        }
+        if (!mustModule) {
+          mustGeoScheme->NavigateTo(volPath);
+          TVector3 globPos = mustGeoScheme->GetGlobal();
+          mustModule       = new CbmMustModule(statId, layerId, moduleId, globPos, directionVector);
+        }
+        mustLayer->AddModule(mustModule);
+        // add tube
+        detId                 = detId + strawId;
+        CbmMustTube* mustTube = mustModule->FindTube(detId);
+        if (!mustTube) {
+          mustGeoScheme->NavigateTo(volPath);
+          TVector3 globPos = mustGeoScheme->GetGlobal();
+          mustTube =
+            new CbmMustTube(detId, strawId, globPos[0], globPos[1], globPos[2], directionVector[1], -directionVector[0],
+                            0., directionVector[0], directionVector[1], 0., 0., 0., 1., 0.0127, 0.49, 110.);
+        }
+        mustModule->AddTube(mustTube);
+      }
+
+      LOG(debug) << " l/m/t = " << layerId << "/" << moduleId << "/" << strawId;
+
+      AddHit(fTrackID, fVolumeID, layerId, moduleId, strawId, TVector3(fpostot.X(), fpostot.Y(), fpostot.Z()),
+             TVector3(fPosInLocal.X(), fPosInLocal.Y(), fPosInLocal.Z()),
+             TVector3(fPosOutLocal.X(), fPosOutLocal.Y(), fPosOutLocal.Z()),
+             TVector3(fMomIn.Px(), fMomIn.Py(), fMomIn.Pz()), TVector3(fMomOut.Px(), fMomOut.Py(), fMomOut.Pz()), fTime,
+             fLength, fELoss, fMass);
+
+      if (fTrackID != 0) {
+        if (fVerboseLevel > 2) LOG(info) << "AddHit CbmMust.cxx= " << fTrackID;
+      }
+
+      // Increment number of stt points for TParticle
+      CbmStack* stack = (CbmStack*) gMC->GetStack();
+      stack->AddPoint(ECbmModuleId::kEcal);
+      ResetParameters();
+    }
+  }
+
+  return kTRUE;
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method EndOfEvent   --------------------------------------
+void CbmMust::EndOfEvent()
+{
+  if (fVerboseLevel) Print();
+  fMustCollection->Delete();
+  fPosIndex = 0;
+
+  if (1 == 0) {
+    int nofTubes        = 0;
+    TObjArray* stations = CbmMustGeoScheme::Instance()->GetStations();
+    for (Int_t iobj = 0; iobj < stations->GetEntriesFast(); iobj++) {
+      CbmMustStation* tempStation = (CbmMustStation*) (stations->At(iobj));
+      for (int ilay = 0; ilay < tempStation->GetNLayers(); ilay++) {
+        CbmMustLayer* tempLayer = tempStation->GetLayer(ilay);
+        for (int imod = 0; imod < tempLayer->GetNModules(); imod++) {
+          CbmMustModule* tempModule = tempLayer->GetModule(imod);
+          tempModule->SortTubes();
+          nofTubes += tempModule->GetNTubes();
+        }
+      }
+    }
+
+    LOG(info) << "got " << nofTubes << " tubes";
+    if (nofTubes == 256 && !fGeoSchemeSaved) {
+      CbmMustGeoScheme::Instance()->Show();
+      CbmMustGeoScheme::Instance()->StoreGeoScheme();
+      fGeoSchemeSaved = true;
+    }
+  }
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method Register   ----------------------------------------
+void CbmMust::Register() { FairRootManager::Instance()->Register("MUSTPoint", "Must", fMustCollection, kTRUE); }
+// -------------------------------------------------------------------------
+
+// -----   Public method GetCollection   -----------------------------------
+TClonesArray* CbmMust::GetCollection(Int_t iColl) const
+{
+  if (iColl == 0)
+    return fMustCollection;
+  else
+    return nullptr;
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method Print   -------------------------------------------
+void CbmMust::Print(Option_t*) const
+{
+  Int_t nHits = fMustCollection->GetEntriesFast();
+
+  LOG(info) << " CbmMust: " << nHits << " points registered in this event.";
+
+  if (fVerboseLevel > 1)
+    for (Int_t i = 0; i < nHits; i++)
+      (*fMustCollection)[i]->Print();
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method Reset   -------------------------------------------
+void CbmMust::Reset()
+{
+  fMustCollection->Delete();
+  ResetParameters();
+}
+// -------------------------------------------------------------------------
+
+// -----   Public method CopyClones   --------------------------------------
+void CbmMust::CopyClones(TClonesArray* cl1, TClonesArray* cl2, Int_t offset)
+{
+  Int_t nEntries = cl1->GetEntriesFast();
+
+  LOG(info) << " CbmMust: " << nEntries << " entries to add.";
+
+  TClonesArray& clref = *cl2;
+
+  CbmMustPoint* oldpoint = nullptr;
+  for (Int_t i = 0; i < nEntries; i++) {
+    oldpoint = (CbmMustPoint*) cl1->At(i);
+
+    Int_t index = oldpoint->GetTrackID() + offset;
+
+    oldpoint->SetTrackID(index);
+    new (clref[fPosIndex]) CbmMustPoint(*oldpoint);
+    fPosIndex++;
+  }
+  LOG(info) << " CbmMust: " << cl2->GetEntriesFast() << " merged entries.";
+}
+// -------------------------------------------------------------------------
+
+void CbmMust::Initialize()
+{
+  LOG(info) << " -I- Initializing CbmMust()";
+  FairDetector::Initialize();
+}
+
+// -----   Public method ConstructGeometry   -------------------------------
+void CbmMust::ConstructGeometry()
+{
+
+  TString fileName = GetGeometryFileName();
+
+  // --- Only ROOT geometries are supported
+  if (fileName.EndsWith(".root")) {
+    LOG(info) << "Constructing Must geometry from ROOT file " << fileName.Data();
+    TGeoCombiTrans* fCombiTrans = NULL;
+    Cbm::GeometryUtils::ImportRootGeometry(fgeoName, this, fCombiTrans);
+    return;
+  }
+  LOG(info) << "Constructing Must geometry from text file " << fileName.Data();
+
+  FairGeoLoader* geoLoad    = FairGeoLoader::Instance();
+  FairGeoInterface* geoFace = geoLoad->getGeoInterface();
+  CbmGeoMust* Geo           = new CbmGeoMust();
+  Geo->setGeomFile(GetGeometryFileName());
+  geoFace->addGeoModule(Geo);
+
+  Bool_t rc = geoFace->readSet(Geo);
+  if (rc) Geo->create(geoLoad->getGeoBuilder());
+
+  TList* volList = Geo->getListOfVolumes();
+
+  // store geo parameter
+  FairRun* fRun       = FairRun::Instance();
+  FairRuntimeDb* rtdb = FairRun::Instance()->GetRuntimeDb();
+  CbmGeoMustPar* par;
+  par = (CbmGeoMustPar*) (rtdb->getContainer("CbmGeoMustPar"));
+  rtdb->getListOfContainers()->Print();
+  TObjArray* fSensNodes = par->GetGeoSensitiveNodes();
+  fPassNodes            = par->GetGeoPassiveNodes();
+
+  TListIter iter(volList);
+  FairGeoNode* node   = nullptr;
+  FairGeoVolume* aVol = nullptr;
+
+  while ((node = (FairGeoNode*) iter.Next())) {
+    aVol = dynamic_cast<FairGeoVolume*>(node);
+    // if (fGeoType == 2)
+    //  LOG(info) << "Volume " << aVol->GetName() << " is" << (node->isSensitive() ? "" : " not") << " sensitive";
+    if (node->isSensitive()) {
+      fSensNodes->AddLast(aVol);
+    }
+    else {
+      fPassNodes->AddLast(aVol);
+    }
+  }
+
+  par->SetGeometryType(fGeoType);
+  if (fGeoType == 1) {
+    par->SetTubeInRad(0.4903 / 2.);  // cm
+    par->SetTubeOutRad(0.00127);     // cm
+  }
+  else {
+    LOG(fatal) << "[MUST] GeoType " << fGeoType << " not supported";
+  }
+
+  par->setChanged();
+  par->setInputVersion(fRun->GetRunId(), 1);
+  ProcessNodes(volList);
+}
+// -------------------------------------------------------------------------
+
+// -----   Private method AddHit   -----------------------------------------
+CbmMustPoint* CbmMust::AddHit(Int_t trackID, Int_t detID, Int_t layID, Int_t modID, Int_t strID, TVector3 pos,
+                              TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t time,
+                              Double_t length, Double_t eLoss, Double_t mass)
+{
+  TClonesArray& clref = *fMustCollection;
+
+  Int_t size = clref.GetEntriesFast();
+
+  CbmMustPoint* pointnew = new (clref[size]) CbmMustPoint(trackID, detID, layID, modID, strID, pos, posInLocal,
+                                                          posOutLocal, momIn, momOut, time, length, eLoss, mass);
+
+  return pointnew;
+}
+// -------------------------------------------------------------------------
+
+ClassImp(CbmMust)
diff --git a/sim/detectors/must/CbmMust.h b/sim/detectors/must/CbmMust.h
new file mode 100644
index 0000000000000000000000000000000000000000..dcc47e30468ac65326444b064a3b0680d938f4fd
--- /dev/null
+++ b/sim/detectors/must/CbmMust.h
@@ -0,0 +1,195 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+////////////////////////////////////////////////////////////////////////////
+// CbmMust header file
+//
+// Class for simulation of MUST
+//
+// authors: Radoslaw Karabowicz, GSI, 2024
+//
+// modified from CbmMust by Nafija Ibrišimović in 2023
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef CBMMUST_H
+#define CBMMUST_H
+
+// from CbmRoot, this library
+#include "CbmGeoMustPar.h"
+// from CbmRoot, CbmData
+#include <CbmMustPoint.h>
+// from FairRoot
+#include <FairDetector.h>
+#include <FairRun.h>
+// from ROOT
+#include <TClonesArray.h>
+#include <TLorentzVector.h>
+#include <TVector3.h>
+// standard
+#include <sstream>
+#include <string>
+
+class TClonesArray;
+class FairVolume;
+
+class CbmMust : public FairDetector {
+
+ public:
+  /** Default constructor **/
+  CbmMust();
+
+  /** Standard constructor.
+   *@param name    detetcor name
+   *@param active  sensitivity flag
+   **/
+  CbmMust(const char* name, Bool_t active);
+
+  /** Destructor **/
+  virtual ~CbmMust();
+
+  /** Virtual method ProcessHits
+   **
+   ** Defines the action to be taken when a step is inside the
+   ** active volume. Creates CbmMustPoints and adds them to the
+   ** collection.
+   *@param vol  Pointer to the active volume
+   **/
+  virtual Bool_t ProcessHits(FairVolume* vol = 0) override;
+
+  /** Virtual method EndOfEvent
+   **
+   ** If verbosity level is set, print hit collection at the
+   ** end of the event and resets it afterwards.
+   **/
+  virtual void EndOfEvent() override;
+
+  /** @brief Check whether a volume is sensitive.
+		 **
+		 ** @param(name)  Volume name
+		 ** @value        kTRUE if volume is sensitive, else kFALSE
+		 **
+		 ** The decision is based on the volume name (has to contain "Sensor").
+		 ** Virtual from FairModule.
+		 **/
+  virtual Bool_t IsSensitive(const std::string& name) override
+  {
+    return (TString(name).Contains("active") ? kTRUE : kFALSE);
+  }
+
+  /** Virtual method Register
+   **
+   ** Registers the hit collection in the ROOT manager.
+   **/
+  virtual void Register() override;
+
+  /** Accessor to the hit collection **/
+  virtual TClonesArray* GetCollection(Int_t iColl) const override;
+
+  /** Virtual method Print
+   **
+   ** Screen output of hit collection.
+   **/
+  virtual void Print(Option_t* /*option*/ = "") const override;
+
+  /** Virtual method Reset
+   **
+   ** Clears the hit collection
+   **/
+  virtual void Reset() override;
+
+  virtual void Initialize() override;
+
+  /** Virtual method CopyClones
+   **
+   ** Copies the hit collection with a given track index offset
+   *@param cl1     Origin
+   *@param cl2     Target
+   *@param offset  Index offset
+   **/
+  virtual void CopyClones(TClonesArray* cl1, TClonesArray* cl2, Int_t offset) override;
+
+  /** Virtual method Construct geometry
+   **
+   ** Constructs the STT geometry
+   **/
+  virtual void ConstructGeometry() override;
+
+ private:
+  /** GFTrack information to be stored until the track leaves the
+      active volume. **/
+  Int_t fTrackID;               //!  track index
+  Int_t fVolumeID;              //!  volume id
+  TLorentzVector fPos;          //!  wire position in global frame
+  TLorentzVector fPosIn;        //!  entry position in global frame
+  TLorentzVector fPosOut;       //!  exit position in global frame
+  TLorentzVector fPosInLocal;   //!  entry position in straw frame
+  TLorentzVector fPosOutLocal;  //!  exit position in straw frame
+  TLorentzVector fMomIn;        //!  momentum
+  TLorentzVector fMomOut;       //!  momentum
+  Double_t fTime;               //!  time
+  Double_t fLength;             //!  length
+  Double_t fELoss;              //!  energy loss
+  Double_t fMass;               //!  particle mass
+  Bool_t fIsInitialized;
+
+  Int_t fPosIndex;                //!
+  TClonesArray* fMustCollection;  //! Hit collection
+  TLorentzVector fpostot;         // global frame hit position (in)// da cancellare
+  TLorentzVector fpostotin;       // global frame hit position (in)// da cancellare
+  TLorentzVector fpostotout;      // global frame hit position (in)// da cancellare
+
+  TObjArray* fPassNodes;  //!
+  // geometry type
+  Bool_t valid;
+  Int_t fGeoType;
+  bool fGeoSchemeSaved{false};
+
+  /** Private method AddHit
+   **
+   ** Adds a CbmTrdPoint to the HitCollection
+   **/
+  CbmMustPoint* AddHit(Int_t trackID, Int_t detID, Int_t layID, Int_t modID, Int_t strID, TVector3 pos,
+                       TVector3 posInLocal, TVector3 posOutLocal, TVector3 momIn, TVector3 momOut, Double_t time,
+                       Double_t length, Double_t eLoss, Double_t mass);
+
+  /** Private method ResetParameters
+   **
+   ** Resets the private members for the track parameters
+   **/
+  void ResetParameters();
+
+  /** Private method GetSquaredDistanceFromWire
+   **
+   ** Returns the square of the distance of the current trackpoint to the wire
+   *@return     distance
+   **/
+  float GetSquaredDistanceFromWire();
+
+  CbmMust(const CbmMust& L);
+  CbmMust& operator=(const CbmMust&) { return *this; }
+
+  ClassDef(CbmMust, 1)
+};
+
+inline void CbmMust::ResetParameters()
+{
+  fTrackID = fVolumeID = 0;
+  fPos.SetXYZM(0.0, 0.0, 0.0, 0.0);
+  fPosInLocal.SetXYZM(0.0, 0.0, 0.0, 0.0);
+  fPosOutLocal.SetXYZM(0.0, 0.0, 0.0, 0.0);
+  fMomIn.SetXYZM(0.0, 0.0, 0.0, 0.0);
+  fMomOut.SetXYZM(0.0, 0.0, 0.0, 0.0);
+  fTime = fLength = fELoss = 0;
+  fPosIndex                = 0;
+  fpostot.SetXYZM(0.0, 0.0, 0.0, 0.0);     // da cancellare
+  fpostotin.SetXYZM(0.0, 0.0, 0.0, 0.0);   // da cancellare
+  fpostotout.SetXYZM(0.0, 0.0, 0.0, 0.0);  // da cancellare
+  fPosIn.SetXYZM(0.0, 0.0, 0.0, 0.0);
+  fPosOut.SetXYZM(0.0, 0.0, 0.0, 0.0);
+  fMass          = 0;
+  fIsInitialized = kFALSE;
+  valid          = kFALSE;
+}
+
+#endif  // CBMMUST_H
diff --git a/sim/detectors/must/CbmMustDigitize.cxx b/sim/detectors/must/CbmMustDigitize.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9e3c402723bced36417d7df99f25fd257adda5f3
--- /dev/null
+++ b/sim/detectors/must/CbmMustDigitize.cxx
@@ -0,0 +1,118 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustDigitize source file              -----
+// -----                  Created 2025-01-30 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+/** @file CbmMustDigitize.cxx
+ ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de>
+ ** @since 30.01.2025
+ **/
+
+// Include class header
+#include "CbmMustDigitize.h"
+
+// Includes from ROOT
+#include "TClonesArray.h"
+
+// Includes from FairRoot
+#include "FairEventHeader.h"
+#include "FairField.h"
+#include "FairLink.h"
+#include "FairMCEventHeader.h"
+#include "FairMCPoint.h"
+#include "FairRunAna.h"
+#include "FairRunSim.h"
+#include "FairRuntimeDb.h"
+
+#include <Logger.h>
+
+// Includes from CbmRoot
+#include "CbmMCTrack.h"
+#include "CbmMustDigi.h"
+#include "CbmMustPoint.h"
+
+// -----   Standard constructor   ------------------------------------------
+CbmMustDigitize::CbmMustDigitize() : FairTask("MustDigitizer") {}
+// -------------------------------------------------------------------------
+
+
+// -----   Destructor   ----------------------------------------------------
+CbmMustDigitize::~CbmMustDigitize() {}
+// -------------------------------------------------------------------------
+
+// -----   Task execution   ------------------------------------------------
+void CbmMustDigitize::Exec(Option_t* /*opt*/)
+{
+  assert(fPointArray);
+  fDigiArray->Delete();
+
+  //    LOG(info) << "got " << fPointArray->GetEntriesFast() << " points";
+  for (Int_t iPoint = 0; iPoint < fPointArray->GetEntriesFast(); iPoint++) {
+    const CbmMustPoint* point = (const CbmMustPoint*) fPointArray->At(iPoint);
+    //        LOG(info) << "point from " << point->GetXInLocal() << "," << point->GetYInLocal() << "," << point->GetZInLocal()
+    //                  << " to " << point->GetXOutLocal() << "," << point->GetYOutLocal() << "," << point->GetZOutLocal();
+    int detectorId = 1e7 + point->GetLayerID() * 1e5 + point->GetModuleID() * 1e3 + point->GetStrawID();
+    int skew       = 0;
+    if (point->GetLayerID() == 2) skew = 1;
+    if (point->GetLayerID() == 3) skew = -11;
+
+    double driftTime = GetDriftTime(point);
+
+    // ideal output...
+    CbmMustDigi* digi = new ((*fDigiArray)[iPoint]) CbmMustDigi(detectorId, skew, driftTime, 5, 1);
+  }
+}
+// -------------------------------------------------------------------------
+
+// -----   Private function to get drift time   ----------------------------
+double CbmMustDigitize::GetDriftTime(const CbmMustPoint* point)
+{
+  double closestDist =
+    TMath::Sqrt((point->GetXInLocal() + point->GetXOutLocal()) * (point->GetXInLocal() + point->GetXOutLocal())
+                + (point->GetYInLocal() + point->GetYOutLocal()) * (point->GetYInLocal() + point->GetYOutLocal()));
+  //        LOG(info) << "closest distance = " << closestDist << " cm ---> " << closestDist*400. << " ns";
+  return closestDist * 400.;
+}
+// -------------------------------------------------------------------------
+
+// -----   Finish run    ---------------------------------------------------
+void CbmMustDigitize::Finish() {}
+// -------------------------------------------------------------------------
+
+// -----   Initialisation    -----------------------------------------------
+InitStatus CbmMustDigitize::Init()
+{
+  FairRootManager* ioman = FairRootManager::Instance();
+  if (!ioman) {
+    std::cout << "-E- CbmMustDigitize::Init: "  /// todo replace with logger!
+              << "RootManager not instantiated!" << std::endl;
+    return kFATAL;
+  }
+
+  fPointArray = static_cast<TClonesArray*>(ioman->GetObject("MUSTPoint"));
+  if (!fPointArray) {
+    std::cout << "-W- CbmMustDigitize::Init: "
+              << "No Point array!" << std::endl;
+    return kERROR;
+  }
+
+  // Create and register output array
+  fDigiArray = new TClonesArray("CbmMustDigi");
+  ioman->Register("MUSTDigi", "MUST", fDigiArray, kTRUE);
+
+  // Set static initialisation flag
+  fIsInitialised = kTRUE;
+
+  return kSUCCESS;
+}
+// -------------------------------------------------------------------------
+
+// -----   Private method ReInit   -----------------------------------------
+InitStatus CbmMustDigitize::ReInit() { return kSUCCESS; }
+// -------------------------------------------------------------------------
+
+ClassImp(CbmMustDigitize)
diff --git a/sim/detectors/must/CbmMustDigitize.h b/sim/detectors/must/CbmMustDigitize.h
new file mode 100644
index 0000000000000000000000000000000000000000..8a28b69f2d036ce82a595540d4ef7f3de1951250
--- /dev/null
+++ b/sim/detectors/must/CbmMustDigitize.h
@@ -0,0 +1,61 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Radosław Karabowicz [committer] */
+
+// -------------------------------------------------------------------------
+// -----                      CbmMustDigitize header file              -----
+// -----                  Created 2025-01-30 by R. Karabowicz          -----
+// -------------------------------------------------------------------------
+
+#ifndef CBMMUSTDIGITIZE_H
+#define CBMMUSTDIGITIZE_H 1
+
+#include "CbmDefs.h"
+#include "CbmDigitize.h"
+#include "CbmMustDigi.h"
+#include "CbmMustPoint.h"
+
+/** @class CbmMustDigitize
+ ** @brief Task class for simulating the detector response of the MUST
+ ** @author Radoslaw Karabowicz <r.karabowicz@gsi.de>
+ ** @since 30.01.2025
+ ** @version 1.0
+ **
+ **/
+class CbmMustDigitize : public FairTask {
+
+ public:
+  /** Constructor **/
+  CbmMustDigitize();
+
+  /** Destructor **/
+  virtual ~CbmMustDigitize();
+
+  /** Virtual method Exec **/
+  void Exec(Option_t* opt) override;
+
+  /** Re-initialisation **/
+  virtual InitStatus ReInit();
+
+ private:
+  Bool_t fIsInitialised;  ///< kTRUE if Init() was called
+
+  TClonesArray* fPointArray{nullptr};  ///< Input array of CbmMustPoint
+  TClonesArray* fDigiArray{nullptr};
+
+  double GetDriftTime(const CbmMustPoint* point);
+
+  /** End-of-run action **/
+  void Finish() override;
+
+  /** Initialisation **/
+  InitStatus Init() override;
+
+  /** Prevent usage of copy constructor and assignment operator **/
+  CbmMustDigitize(const CbmMustDigitize&);
+  CbmMustDigitize operator=(const CbmMustDigitize&);
+
+  ClassDef(CbmMustDigitize, 1);
+};
+
+#endif
diff --git a/sim/detectors/must/CbmMustSimLinkDef.h b/sim/detectors/must/CbmMustSimLinkDef.h
new file mode 100644
index 0000000000000000000000000000000000000000..3f56058f4eb7eb602992b3621e7ea034d0d71fe6
--- /dev/null
+++ b/sim/detectors/must/CbmMustSimLinkDef.h
@@ -0,0 +1,14 @@
+/* Copyright (C) 2020 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Volker Friese [committer] */
+
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class CbmMust + ;
+#pragma link C++ class CbmMustDigitize + ;
+
+#endif /* __CINT__ */