From 4162a7b806f91bb1b4063fe12b60f58c0d43d4ea Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Tue, 17 May 2022 15:17:19 +0200
Subject: [PATCH] L1Algo: added possibility for active stations selection

---
 reco/L1/CbmL1.cxx                    | 22 +++++--
 reco/L1/L1Algo/L1Algo.cxx            |  6 +-
 reco/L1/L1Algo/L1BaseStationInfo.cxx | 70 +++++++++++++---------
 reco/L1/L1Algo/L1BaseStationInfo.h   | 48 ++++++++-------
 reco/L1/L1Algo/L1CATrackFinder.cxx   |  2 +-
 reco/L1/L1Algo/L1InitManager.cxx     | 90 ++++++++++++++++------------
 reco/L1/L1Algo/L1InitManager.h       | 62 +++++++++++--------
 7 files changed, 177 insertions(+), 123 deletions(-)

diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index ddccf46dd3..e70660615d 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -933,11 +933,11 @@ InitStatus CbmL1::Init()
   geo.push_back(fGhostSuppression);
 
   // Provide crosscheck number of stations for the fpInitManager
-  fpInitManager->SetStationsNumberCrosscheck(L1DetectorID::kMvd, NMvdStations);
-  fpInitManager->SetStationsNumberCrosscheck(L1DetectorID::kSts, NStsStations);
-  fpInitManager->SetStationsNumberCrosscheck(L1DetectorID::kMuch, NMuchStations);
-  fpInitManager->SetStationsNumberCrosscheck(L1DetectorID::kTrd, NTrdStations);
-  fpInitManager->SetStationsNumberCrosscheck(L1DetectorID::kTof, NTOFStation);
+  fpInitManager->SetNstationsCrosscheck(L1DetectorID::kMvd, NMvdStations);
+  fpInitManager->SetNstationsCrosscheck(L1DetectorID::kSts, NStsStations);
+  fpInitManager->SetNstationsCrosscheck(L1DetectorID::kMuch, NMuchStations);
+  fpInitManager->SetNstationsCrosscheck(L1DetectorID::kTrd, NTrdStations);
+  fpInitManager->SetNstationsCrosscheck(L1DetectorID::kTof, NTOFStation);
 
   {
     if (fSTAPDataMode % 2 == 1) {  // 1,3
@@ -991,6 +991,7 @@ InitStatus CbmL1::Init()
     fscal mvdFrontSigma = mvdStationPar->GetXRes(iSt) / 10000;
     fscal mvdBackSigma  = mvdStationPar->GetYRes(iSt) / 10000;
     stationInfo.SetFrontBackStripsGeometry(mvdFrontPhi, mvdFrontSigma, mvdBackPhi, mvdBackSigma);
+    stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
     fpInitManager->AddStation(stationInfo);
     LOG(info) << "- MVD station " << iSt << " at z = " << stationInfo.GetZdouble();
   }
@@ -1020,6 +1021,7 @@ InitStatus CbmL1::Init()
     fscal stsFrontSigma = cbmSts->GetSensorPitch(0) / sqrt(12);
     fscal stsBackSigma  = stsFrontSigma;
     stationInfo.SetFrontBackStripsGeometry(stsFrontPhi, stsFrontSigma, stsBackPhi, stsBackSigma);
+    stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
     fpInitManager->AddStation(stationInfo);
     LOG(info) << "- STS station " << iSt << " at z = " << stationInfo.GetZdouble();
   }
@@ -1049,6 +1051,7 @@ InitStatus CbmL1::Init()
     fscal muchFrontSigma = 0.35;
     fscal muchBackSigma  = 0.35;
     stationInfo.SetFrontBackStripsGeometry(muchFrontPhi, muchFrontSigma, muchBackPhi, muchBackSigma);
+    stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
     fpInitManager->AddStation(stationInfo);
     LOG(info) << "- MuCh station " << iSt << " at z = " << stationInfo.GetZdouble();
   }
@@ -1080,6 +1083,7 @@ InitStatus CbmL1::Init()
     fscal trdFrontSigma = 0.15;
     fscal trdBackSigma  = 0.15;
     stationInfo.SetFrontBackStripsGeometry(trdFrontPhi, trdFrontSigma, trdBackPhi, trdBackSigma);
+    stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
     fpInitManager->AddStation(stationInfo);
     LOG(info) << "- TRD station " << iSt << " at z = " << stationInfo.GetZdouble();
   }
@@ -1104,10 +1108,18 @@ InitStatus CbmL1::Init()
     fscal tofFrontSigma = 0.42;
     fscal tofBackSigma  = 0.23;
     stationInfo.SetFrontBackStripsGeometry(tofFrontPhi, tofFrontSigma, tofBackPhi, tofBackSigma);
+    stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
     fpInitManager->AddStation(stationInfo);
     LOG(info) << "- TOF station " << iSt << " at z = " << stationInfo.GetZdouble();
   }
 
+  //fpInitManager->PrintStations(/*verbosity = */2);
+  //std::cout  << "Active stations map: ";
+  //for (auto index: fpInitManager->GetActiveStationsIndexMap()) {
+  //  std::cout << index << ' ';
+  //}
+  //std::cout << '\n';
+
   /****************************************
    **                                    **
    ** TRACKING ITERATIONS INITIALIZATION **
diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx
index d523443caf..60a4f47d19 100644
--- a/reco/L1/L1Algo/L1Algo.cxx
+++ b/reco/L1/L1Algo/L1Algo.cxx
@@ -78,8 +78,8 @@ void L1Algo::Init(const bool UseHitErrors, const TrackingMode mode, const bool M
 
 
   //int NMvdStations = static_cast<int>(geo[ind++]);  // TODO: get rid of NMbdStations (S. Zh.)
-  int nStationsSts     = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(1));
-  fNstationsBeforePipe = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(0));
+  int nStationsSts     = fInitManager.GetNstations(static_cast<L1DetectorID>(1));
+  fNstationsBeforePipe = fInitManager.GetNstations(static_cast<L1DetectorID>(0));
   //int NStsStations = static_cast<int>(geo[ind++]);  // TODO: get rid of NStsStations (S. Zh.)
 
   fNfieldStations = nStationsSts + fNstationsBeforePipe;  // TODO: Provide special getter for it (S.Zharko, 12.05.2022)
@@ -100,7 +100,7 @@ void L1Algo::Init(const bool UseHitErrors, const TrackingMode mode, const bool M
   fRealTargetZ = fInitManager.GetTargetPosition()[2];
 
   // Get number of station
-  fNstations = fInitManager.GetStationsNumber();
+  fNstations = fInitManager.GetNstations();
 
   // Get field near target
   fVtxFieldValue  = fInitManager.GetTargetFieldValue();
diff --git a/reco/L1/L1Algo/L1BaseStationInfo.cxx b/reco/L1/L1Algo/L1BaseStationInfo.cxx
index 6d9ebafae0..0d12f7d31e 100644
--- a/reco/L1/L1Algo/L1BaseStationInfo.cxx
+++ b/reco/L1/L1Algo/L1BaseStationInfo.cxx
@@ -44,8 +44,8 @@ L1BaseStationInfo::L1BaseStationInfo(L1DetectorID detectorID, int stationID) noe
   , fStationID(stationID)
 {
   LOG(debug) << "L1BaseStationInfo: Constructor (detectorID, stationID) called for " << this << '\n';  // Temporary
-  fInitController.SetFlag(InitKey::keDetectorID);
-  fInitController.SetFlag(InitKey::keStationID);
+  fInitController.SetFlag(EInitKey::kDetectorID);
+  fInitController.SetFlag(EInitKey::kStationID);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -60,6 +60,7 @@ L1BaseStationInfo::~L1BaseStationInfo() noexcept
 L1BaseStationInfo::L1BaseStationInfo(const L1BaseStationInfo& other) noexcept
   : fDetectorID(other.fDetectorID)
   , fStationID(other.fStationID)
+  , fTrackingStatus(other.fTrackingStatus)
   , fXmax(other.fXmax)
   , fYmax(other.fYmax)
   , fZPos(other.fZPos)
@@ -115,6 +116,8 @@ void L1BaseStationInfo::Print(int verbosity) const
     LOG(info) << "L1BaseStationInfo object: at " << this;
     LOG(info) << "\tStation ID:              " << fStationID;
     LOG(info) << "\tDetector ID:             " << static_cast<int>(fDetectorID);
+    LOG(info) << "\tStation z position:      " << fZPos;
+    LOG(info) << "\tTracking status:         " << fTrackingStatus;
     fL1Station.Print(verbosity - 1);
     LOG(info) << "\tAdditional fields:";
     LOG(info) << "\t\tXmax:                    " << fXmax;
@@ -153,9 +156,9 @@ const L1Station& L1BaseStationInfo::GetL1Station() const
 //
 void L1BaseStationInfo::SetDetectorID(L1DetectorID inID)
 {
-  if (!fInitController.GetFlag(InitKey::keDetectorID)) {
+  if (!fInitController.GetFlag(EInitKey::kDetectorID)) {
     fDetectorID = inID;
-    fInitController.SetFlag(InitKey::keDetectorID);
+    fInitController.SetFlag(EInitKey::kDetectorID);
   }
   else {
     LOG(warn) << "L1BaseStationInfo::SetDetectorID: Attempt of detector ID redifinition";
@@ -167,7 +170,7 @@ void L1BaseStationInfo::SetDetectorID(L1DetectorID inID)
 void L1BaseStationInfo::SetRmax(double inRmax)
 {
   fL1Station.Rmax = inRmax;
-  fInitController.SetFlag(InitKey::keRmax);
+  fInitController.SetFlag(EInitKey::kRmax);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -175,14 +178,14 @@ void L1BaseStationInfo::SetRmax(double inRmax)
 void L1BaseStationInfo::SetRmin(double inRmin)
 {
   fL1Station.Rmin = inRmin;
-  fInitController.SetFlag(InitKey::keRmin);
+  fInitController.SetFlag(EInitKey::kRmin);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetFieldSlice(const double* Cx, const double* Cy, const double* Cz)
 {
-  if (fInitController.GetFlag(InitKey::keFieldSlice)) {
+  if (fInitController.GetFlag(EInitKey::kFieldSlice)) {
     LOG(warn) << "L1BaseStationInfo::SetFieldSlice: Attempt to redifine field slice for station with detectorID = "
               << static_cast<int>(fDetectorID) << " and stationID = " << fStationID << ". Redifinition ignored";
     return;
@@ -194,24 +197,24 @@ void L1BaseStationInfo::SetFieldSlice(const double* Cx, const double* Cy, const
     fL1Station.fieldSlice.cz[idx] = Cz[idx];
   }
 
-  fInitController.SetFlag(InitKey::keFieldSlice);
+  fInitController.SetFlag(EInitKey::kFieldSlice);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetFieldSlice(const std::function<void(const double (&xyz)[3], double (&B)[3])>& getFieldValue)
 {
-  if (fInitController.GetFlag(InitKey::keFieldSlice)) {
+  if (fInitController.GetFlag(EInitKey::kFieldSlice)) {
     LOG(warn) << "L1BaseStationInfo::SetFieldSlice: Attempt to redifine field slice for station with detectorID = "
               << static_cast<int>(fDetectorID) << " and stationID = " << fStationID << ". Redifinition ignored";
     return;
   }
 
-  L1MASSERT(0, fInitController.GetFlag(InitKey::keZ),
+  L1MASSERT(0, fInitController.GetFlag(EInitKey::kZ),
             "Attempt to set magnetic field slice before setting z position of the station");
-  L1MASSERT(0, fInitController.GetFlag(InitKey::keXmax),
+  L1MASSERT(0, fInitController.GetFlag(EInitKey::kXmax),
             "Attempt to set magnetic field slice before Xmax size of the station");
-  L1MASSERT(0, fInitController.GetFlag(InitKey::keYmax),
+  L1MASSERT(0, fInitController.GetFlag(EInitKey::kYmax),
             "Attempt to set magnetic field slice before Ymax size of the station");
   // TODO: Change names of variables according to convention (S.Zh.)
   constexpr int M = L1Parameters::kMaxFieldApproxPolynomialOrder;
@@ -281,7 +284,7 @@ void L1BaseStationInfo::SetFieldSlice(const std::function<void(const double (&xy
     fL1Station.fieldSlice.cz[j] = A[j][N + 2] / A[j][j];
   }
 
-  fInitController.SetFlag(InitKey::keFieldSlice);
+  fInitController.SetFlag(EInitKey::kFieldSlice);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -289,7 +292,7 @@ void L1BaseStationInfo::SetFieldSlice(const std::function<void(const double (&xy
 void L1BaseStationInfo::SetFieldStatus(int fieldStatus)
 {
   fL1Station.fieldStatus = fieldStatus;
-  fInitController.SetFlag(InitKey::keFieldStatus);
+  fInitController.SetFlag(EInitKey::kFieldStatus);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -326,10 +329,10 @@ void L1BaseStationInfo::SetFrontBackStripsGeometry(double frontPhi, double front
   fL1Station.yInfo.sigma2  = fL1Station.XYInfo.C11;
   //-----------------------------------------------------------------------------------------------------//
 
-  fInitController.SetFlag(InitKey::keStripsFrontPhi);
-  fInitController.SetFlag(InitKey::keStripsFrontSigma);
-  fInitController.SetFlag(InitKey::keStripsBackPhi);
-  fInitController.SetFlag(InitKey::keStripsBackSigma);
+  fInitController.SetFlag(EInitKey::kStripsFrontPhi);
+  fInitController.SetFlag(EInitKey::kStripsFrontSigma);
+  fInitController.SetFlag(EInitKey::kStripsBackPhi);
+  fInitController.SetFlag(EInitKey::kStripsBackSigma);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -342,17 +345,17 @@ void L1BaseStationInfo::SetMaterial(double inThickness, double inRL)
   fL1Station.materialInfo.RL          = inRL;
   fL1Station.materialInfo.RadThick    = fL1Station.materialInfo.thick / fL1Station.materialInfo.RL;
   fL1Station.materialInfo.logRadThick = log(fL1Station.materialInfo.RadThick);
-  fInitController.SetFlag(InitKey::keMaterialInfoThick);
-  fInitController.SetFlag(InitKey::keMaterialInfoRL);
+  fInitController.SetFlag(EInitKey::kMaterialInfoThick);
+  fInitController.SetFlag(EInitKey::kMaterialInfoRL);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetStationID(int inID)
 {
-  if (!fInitController.GetFlag(InitKey::keStationID)) {
+  if (!fInitController.GetFlag(EInitKey::kStationID)) {
     fStationID = inID;
-    fInitController.SetFlag(InitKey::keStationID);
+    fInitController.SetFlag(EInitKey::kStationID);
   }
   else {
     LOG(warn) << "L1BaseStationInfo::SetStationID: Attempt of station ID redifinition";
@@ -363,9 +366,9 @@ void L1BaseStationInfo::SetStationID(int inID)
 //
 void L1BaseStationInfo::SetStationType(int inType)
 {
-  if (!fInitController.GetFlag(InitKey::keType)) {
+  if (!fInitController.GetFlag(EInitKey::kType)) {
     fL1Station.type = inType;
-    fInitController.SetFlag(InitKey::keType);
+    fInitController.SetFlag(EInitKey::kType);
   }
   else {
     LOG(warn) << "L1BaseStationInfo::SetStationType: Attempt of station type redifinition";
@@ -377,7 +380,7 @@ void L1BaseStationInfo::SetStationType(int inType)
 void L1BaseStationInfo::SetXmax(double aSize)
 {
   fXmax = aSize;
-  fInitController.SetFlag(InitKey::keXmax);
+  fInitController.SetFlag(EInitKey::kXmax);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -385,7 +388,7 @@ void L1BaseStationInfo::SetXmax(double aSize)
 void L1BaseStationInfo::SetYmax(double aSize)
 {
   fYmax = aSize;
-  fInitController.SetFlag(InitKey::keYmax);
+  fInitController.SetFlag(EInitKey::kYmax);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -393,7 +396,7 @@ void L1BaseStationInfo::SetYmax(double aSize)
 void L1BaseStationInfo::SetTimeInfo(int inTimeInfo)
 {
   fL1Station.timeInfo = inTimeInfo;
-  fInitController.SetFlag(InitKey::keTimeInfo);
+  fInitController.SetFlag(EInitKey::kTimeInfo);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -401,7 +404,15 @@ void L1BaseStationInfo::SetTimeInfo(int inTimeInfo)
 void L1BaseStationInfo::SetTimeResolution(double dt)
 {
   fL1Station.dt = dt;
-  fInitController.SetFlag(InitKey::keTimeResolution);
+  fInitController.SetFlag(EInitKey::kTimeResolution);
+}
+
+//----------------------------------------------------------------------------------------------------------------------//
+//
+void L1BaseStationInfo::SetTrackingStatus(bool flag)
+{
+  fTrackingStatus = flag;
+  fInitController.SetFlag(EInitKey::kTrackingStatus);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -410,7 +421,7 @@ void L1BaseStationInfo::SetZ(double inZ)
 {
   fL1Station.z = inZ;  // setting simd vector of single-precision floats, which is passed to high performanced L1Algo
   fZPos        = inZ;  // setting precised value to use in field approximation etc
-  fInitController.SetFlag(InitKey::keZ);
+  fInitController.SetFlag(EInitKey::kZ);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -419,6 +430,7 @@ void L1BaseStationInfo::Swap(L1BaseStationInfo& other) noexcept
 {
   std::swap(fDetectorID, other.fDetectorID);
   std::swap(fStationID, other.fStationID);
+  std::swap(fTrackingStatus, other.fTrackingStatus);
   std::swap(fXmax, other.fXmax);
   std::swap(fYmax, other.fYmax);
   std::swap(fZPos, other.fZPos);
diff --git a/reco/L1/L1Algo/L1BaseStationInfo.h b/reco/L1/L1Algo/L1BaseStationInfo.h
index 77e1418f3e..a080a0476c 100644
--- a/reco/L1/L1Algo/L1BaseStationInfo.h
+++ b/reco/L1/L1Algo/L1BaseStationInfo.h
@@ -28,33 +28,34 @@ enum class L1DetectorID;
 class L1BaseStationInfo {
 public:
   /// Enumeration of fields, which must be initialized so the object can pass the threshold
-  enum class InitKey
+  enum class EInitKey
   {
     // Basic fields initialization
-    keDetectorID,  ///< detector ID
-    keStationID,   ///< station ID
-    keXmax,        ///< max size in X direction
-    keYmax,        ///< max size in Y direction
+    kDetectorID,      ///< detector ID
+    kStationID,       ///< station ID
+    kTrackingStatus,  ///< flag, if station is used in tracking or not
+    kXmax,            ///< max size in X direction
+    kYmax,            ///< max size in Y direction
     // L1Station initialization
-    keType,               ///< station type
-    keTimeInfo,           ///< if time info is used (flag)
-    keFieldStatus,        ///< if station is placed in field (flag)
-    keZ,                  ///< z coordinate of the station position
-    keRmin,               ///< internal radius of station (gap size)
-    keRmax,               ///< exteranl radius of station
-    keMaterialInfoThick,  ///< thickness of the station
-    keMaterialInfoRL,     ///< rad length of the station
-    keFieldSlice,         ///< L1Station.L1FieldSlice object initialization
-    keStripsFrontPhi,     ///< strips geometry initialization
-    keStripsFrontSigma,   ///<
-    keStripsBackPhi,      ///<
-    keStripsBackSigma,    ///<
-    keTimeResolution,     ///< time resolution
+    kType,               ///< station type
+    kTimeInfo,           ///< if time info is used (flag)
+    kFieldStatus,        ///< if station is placed in field (flag)
+    kZ,                  ///< z coordinate of the station position
+    kRmin,               ///< internal radius of station (gap size)
+    kRmax,               ///< exteranl radius of station
+    kMaterialInfoThick,  ///< thickness of the station
+    kMaterialInfoRL,     ///< rad length of the station
+    kFieldSlice,         ///< L1Station.L1FieldSlice object initialization
+    kStripsFrontPhi,     ///< strips geometry initialization
+    kStripsFrontSigma,   ///<
+    kStripsBackPhi,      ///<
+    kStripsBackSigma,    ///<
+    kTimeResolution,     ///< time resolution
     // The last item is equal to the number of bits in fInitFlags
-    keEnd
+    kEnd
   };
 
-  using L1ObjectInitController_t = L1ObjectInitController<static_cast<int>(InitKey::keEnd), InitKey>;
+  using L1ObjectInitController_t = L1ObjectInitController<static_cast<int>(EInitKey::kEnd), EInitKey>;
 
   //
   // CONSTRUCTORS AND DESTRUCTORS
@@ -125,6 +126,8 @@ public:
   int GetStationType() const { return fL1Station.type; }
   /// Gets time resolution
   fvec GetTimeResolution() const { return fL1Station.dt; }
+  /// Gets tracking status: true - station is active for tracking, false - station exists, but not used in tracking
+  bool GetTrackingStatus() const { return fTrackingStatus; }
   /// Gets maximum distance between station center and its edge in x direction
   double GetXmax() const { return fXmax; }
   /// Gets maximum distance between station center and its edge in y direction
@@ -181,6 +184,8 @@ public:
   void SetTimeInfo(int inTimeInfo);
   /// Sets time resolution
   void SetTimeResolution(double dt);
+  /// Sets tracking status: true - station is active for tracking, false - station exists, but not used in tracking
+  void SetTrackingStatus(bool flag);
   /// Sets maximum distance between station center and its edge in x direction
   void SetXmax(double aSize);
   /// Sets maximum distance between station center and its edge in y direction
@@ -198,6 +203,7 @@ public:
 private:
   L1DetectorID fDetectorID {static_cast<L1DetectorID>(0)};  ///< Detector ID
   int fStationID {-1};                                      ///< Station ID
+  bool fTrackingStatus {false};                             ///< Tracking status: true - station is used for tracking
   double fXmax {0};         ///< Maximum distance between station center and its edge in x direction
   double fYmax {0};         ///< Maximum distance between station center and its edge in y direction
   double fZPos {0};         ///< z position of the station in double precision, used in field approximation
diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx
index cf53d35b1b..1b1ec5a1c5 100644
--- a/reco/L1/L1Algo/L1CATrackFinder.cxx
+++ b/reco/L1/L1Algo/L1CATrackFinder.cxx
@@ -1810,7 +1810,7 @@ void L1Algo::CATrackFinder()
       vStsHitPointsUnused                        = vStsHitPointsUnused_buf;
       vStsHitPointsUnused_buf                    = vStsHitsUnused_temp2;
     }
-    // TODO: Replace NStations with fInitManager.GetStationsNumber() (S.Zharko)
+    // TODO: Replace NStations with fInitManager.GetNstationsGeom() (S.Zharko)
     for (int ist = 0; ist < fNstations; ++ist) {
       for (L1HitIndex_t ih = StsHitsUnusedStartIndex[ist]; ih < StsHitsUnusedStopIndex[ist]; ++ih) {
         //SG!!
diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx
index 655d5cb058..b24bea8544 100644
--- a/reco/L1/L1Algo/L1InitManager.cxx
+++ b/reco/L1/L1Algo/L1InitManager.cxx
@@ -25,20 +25,21 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
   // Check if other fields were defined already
   // Active detector IDs
 
-  L1MASSERT(0, fInitController.GetFlag(InitKey::keActiveDetectorIDs),
+  L1MASSERT(0, fInitController.GetFlag(EInitKey::kActiveDetectorIDs),
             "Attempt to add a station info before the active detetors set had been initialized");
 
   // Number of stations check
-  L1MASSERT(0, fInitController.GetFlag(InitKey::keStationsNumberCrosscheck),
+  L1MASSERT(0, fInitController.GetFlag(EInitKey::kStationsNumberCrosscheck),
             "Attempt to add a station info before the numbers of stations for each detector had been initialized");
 
   // Field function
-  L1MASSERT(0, fInitController.GetFlag(InitKey::keFieldFunction),
+  L1MASSERT(0, fInitController.GetFlag(EInitKey::kFieldFunction),
             "Attempt to add a station info before the magnetic field function had been intialized");
 
   // Check activeness of this station type
-  bool isDetectorActive = fActiveDetectorIDs.find(inStation.GetDetectorID()) != fActiveDetectorIDs.end();
-  if (isDetectorActive) {
+  bool isStationActive =
+    inStation.GetTrackingStatus() && fActiveDetectorIDs.find(inStation.GetDetectorID()) != fActiveDetectorIDs.end();
+  if (isStationActive) {
     // initialize magnetic field slice
     L1BaseStationInfo inStationCopy = L1BaseStationInfo(inStation);  // make a copy of station so it can be initialized
     inStationCopy.SetFieldSlice(fFieldFunction);
@@ -64,10 +65,14 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
               << ")";
       L1MASSERT(0, insertionResult.second, aStream.str().c_str());
     }
+    fActiveStationsIndexMap.push_back(fStationsInfo.size() - 1);
+  }
+  else {
+    fActiveStationsIndexMap.push_back(-1);
   }
   LOG(debug) << "L1InitManager: adding a station with stationID = " << inStation.GetStationID()
              << " and detectorID = " << static_cast<int>(inStation.GetDetectorID())
-             << ". Is active: " << isDetectorActive;
+             << ". Is active: " << isStationActive;
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
@@ -80,7 +85,7 @@ void L1InitManager::CheckInit()
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const
+int L1InitManager::GetNstations(L1DetectorID detectorID) const
 {
   auto ifDetectorIdDesired = [&detectorID](const L1BaseStationInfo& station) {
     return station.GetDetectorID() == detectorID;
@@ -92,19 +97,19 @@ int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const
 //
 void L1InitManager::InitTargetField(double zStep)
 {
-  if (fInitController.GetFlag(InitKey::kePrimaryVertexField)) {
+  if (fInitController.GetFlag(EInitKey::kPrimaryVertexField)) {
     LOG(warn) << "L1InitManager::InitTargetField: attempt to reinitialize the field value and field region "
               << "near target. Ignore";
     return;
   }
 
   // Check for field function
-  L1MASSERT(0, fInitController.GetFlag(InitKey::keFieldFunction),
+  L1MASSERT(0, fInitController.GetFlag(EInitKey::kFieldFunction),
             "Attempt to initialze the field value and field region near target before initializing field function");
 
   // Check for target defined
   L1MASSERT(
-    0, fInitController.GetFlag(InitKey::keTargetPos),
+    0, fInitController.GetFlag(EInitKey::kTargetPos),
     "Attempt to initialize the field value and field region near target before the target position initialization");
 
   constexpr int nDimensions {3};
@@ -126,7 +131,7 @@ void L1InitManager::InitTargetField(double zStep)
   fTargetFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]);
   fTargetFieldValue = B[0];
 
-  fInitController.SetFlag(InitKey::kePrimaryVertexField);
+  fInitController.SetFlag(EInitKey::kPrimaryVertexField);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
@@ -152,9 +157,9 @@ void L1InitManager::PrintStations(int verbosityLevel) const
 void L1InitManager::PushBackCAIteration(const L1CAIteration& iteration)
 {
   // TODO: probably some checks must be inserted here (S.Zharko)
-  bool control = fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck);
+  bool control = fInitController.GetFlag(EInitKey::kCAIterationsNumberCrosscheck);
   //std::cout << "L1InitManager::PushBackCAIteration " << control << '\n';
-  L1MASSERT(0, control,  //fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck),
+  L1MASSERT(0, control,  //fInitController.GetFlag(EInitKey::kCAIterationsNumberCrosscheck),
             "Attempt to push back a CA track finder iteration before the number of iterations was defined");
 
   L1Vector<L1CAIteration>& iterationsContainer = fpParameters->CAIterationsContainer();
@@ -167,7 +172,7 @@ void L1InitManager::SetActiveDetectorIDs(const L1DetectorIDSet_t& detectorIDs)
 {
   // TODO: To think about redifinition possibilities: should it be allowed or not? (S.Zh.)
   fActiveDetectorIDs = detectorIDs;
-  fInitController.SetFlag(InitKey::keActiveDetectorIDs);
+  fInitController.SetFlag(EInitKey::kActiveDetectorIDs);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
@@ -179,16 +184,16 @@ void L1InitManager::SetCAIterationsNumberCrosscheck(int nIterations)
 
   // NOTE: should be called to prevent multiple copyings of objects between the memory realocations
   iterationsContainer.reserve(nIterations);
-  fInitController.SetFlag(InitKey::keCAIterationsNumberCrosscheck);
+  fInitController.SetFlag(EInitKey::kCAIterationsNumberCrosscheck);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
 void L1InitManager::SetFieldFunction(const L1FieldFunction_t& fieldFunction)
 {
-  if (!fInitController.GetFlag(InitKey::keFieldFunction)) {
+  if (!fInitController.GetFlag(EInitKey::kFieldFunction)) {
     fFieldFunction = fieldFunction;
-    fInitController.SetFlag(InitKey::keFieldFunction);
+    fInitController.SetFlag(EInitKey::kFieldFunction);
   }
   else {
     LOG(warn) << "L1InitManager::SetFieldFunction: attempt to reinitialize the field function. Ignored";
@@ -199,48 +204,55 @@ void L1InitManager::SetFieldFunction(const L1FieldFunction_t& fieldFunction)
 //
 void L1InitManager::SetGhostSuppression(int ghostSuppression)
 {
-  if (fInitController.GetFlag(InitKey::keGhostSuppression)) {
+  if (fInitController.GetFlag(EInitKey::kGhostSuppression)) {
     LOG(warn) << "L1InitManager::SetGhostSuppression: attempt of reinitializating the ghost suppresion flag. Ignore";
     return;
   }
   fGhostSuppression = ghostSuppression;
-  fInitController.SetFlag(InitKey::keGhostSuppression);
+  fInitController.SetFlag(EInitKey::kGhostSuppression);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
 void L1InitManager::SetMomentumCutOff(float momentumCutOff)
 {
-  if (fInitController.GetFlag(InitKey::keMomentumCutOff)) {
+  if (fInitController.GetFlag(EInitKey::kMomentumCutOff)) {
     LOG(warn) << "L1InitManager::SetMomentumCutOff: attempt of reinitializating the momentum cutoff value. Ignore";
     return;
   }
   fMomentumCutOff = momentumCutOff;
-  fInitController.SetFlag(InitKey::keMomentumCutOff);
+  fInitController.SetFlag(EInitKey::kMomentumCutOff);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::SetStationsNumberCrosscheck(L1DetectorID detectorID, int nStations)
+void L1InitManager::SetNstationsCrosscheck(L1DetectorID detectorID, int nStations)
 {
   // NOTE: We add and check only those detectors which will be active (?)
   // For INACTIVE detectors the initialization code for it inside CbmL1/BmnL1 can (and must) be still in,
   // but it will be ignored inside L1InitManager.
   if (fActiveDetectorIDs.find(detectorID) != fActiveDetectorIDs.end()) {
-    fStationsNumberCrosscheck[detectorID] = nStations;
+    fNstationsActualCrosscheck[detectorID] = nStations;
   }
 
   // Check if all the station numbers for active detectors are initialized now:
-  LOG(debug) << "SetStationsNumberCrosscheck called for detectorID = " << static_cast<int>(detectorID);
-  if (!fInitController.GetFlag(InitKey::keStationsNumberCrosscheck)) {
+  LOG(debug) << "SetNstationsCrosscheck called for detectorID = " << static_cast<int>(detectorID);
+  if (!fInitController.GetFlag(EInitKey::kStationsNumberCrosscheck)) {
     bool ifInitialized = true;
     for (auto item : fActiveDetectorIDs) {
-      if (fStationsNumberCrosscheck.find(item) == fStationsNumberCrosscheck.end()) {
+      if (fNstationsActualCrosscheck.find(item) == fNstationsActualCrosscheck.end()) {
         ifInitialized = false;
         break;
       }
     }
-    fInitController.SetFlag(InitKey::keStationsNumberCrosscheck, ifInitialized);
+    fInitController.SetFlag(EInitKey::kStationsNumberCrosscheck, ifInitialized);
+  }
+  if (fInitController.GetFlag(EInitKey::kStationsNumberCrosscheck)) {
+    int nStationsExpected = 0;
+    for (auto item : fNstationsActualCrosscheck) {
+      nStationsExpected += item.second;
+    }
+    fActiveStationsIndexMap.reserve(nStationsExpected);
   }
 }
 
@@ -248,7 +260,7 @@ void L1InitManager::SetStationsNumberCrosscheck(L1DetectorID detectorID, int nSt
 //
 void L1InitManager::SetTargetPosition(double x, double y, double z)
 {
-  if (fInitController.GetFlag(InitKey::keTargetPos)) {
+  if (fInitController.GetFlag(EInitKey::kTargetPos)) {
     LOG(warn) << "L1InitManager::SetTargetPosition: attempt to reinitialize the target position. Ignore";
     return;
   }
@@ -256,19 +268,19 @@ void L1InitManager::SetTargetPosition(double x, double y, double z)
   fTargetPos[0] = x;
   fTargetPos[1] = y;
   fTargetPos[2] = z;
-  fInitController.SetFlag(InitKey::keTargetPos);
+  fInitController.SetFlag(EInitKey::kTargetPos);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
 void L1InitManager::SetTrackingLevel(int trackingLevel)
 {
-  if (fInitController.GetFlag(InitKey::keTrackingLevel)) {
+  if (fInitController.GetFlag(EInitKey::kTrackingLevel)) {
     LOG(warn) << "L1InitManager::SetTrackingLevel: attempt of reinitialization the tracking level. Ignore";
     return;
   }
   fTrackingLevel = trackingLevel;
-  fInitController.SetFlag(InitKey::keTrackingLevel);
+  fInitController.SetFlag(EInitKey::kTrackingLevel);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
@@ -288,7 +300,7 @@ void L1InitManager::TransferL1StationArray(std::array<L1Station, L1Parameters::k
   // 2) Check, if destinationArraySize is enough for the transfer
   //
   {
-    int nStationsTotal = this->GetStationsNumber();
+    int nStationsTotal = this->GetNstations();
     std::stringstream aStream;
     aStream << "Destination array size (" << destinationArray.size()
             << ") is smaller then the actual number of active tracking stations (" << nStationsTotal << ")";
@@ -315,7 +327,7 @@ void L1InitManager::CheckCAIterationsInit()
   // 1) Check number of iterations
   //
   bool ifInitPassed = true;
-  if (!fInitController.GetFlag(InitKey::keCAIterations)) {
+  if (!fInitController.GetFlag(EInitKey::kCAIterations)) {
     int nIterationsActual   = fpParameters->CAIterationsContainer().size();
     int nIterationsExpected = fCAIterationsNumberCrosscheck;
     if (nIterationsActual != nIterationsExpected) {
@@ -324,7 +336,7 @@ void L1InitManager::CheckCAIterationsInit()
       ifInitPassed = false;
     }
   }
-  fInitController.SetFlag(InitKey::keCAIterations, ifInitPassed);
+  fInitController.SetFlag(EInitKey::kCAIterations, ifInitPassed);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
@@ -332,14 +344,14 @@ void L1InitManager::CheckCAIterationsInit()
 void L1InitManager::CheckStationsInfoInit()
 {
   bool ifInitPassed = true;
-  if (!fInitController.GetFlag(InitKey::keStationsInfo)) {
+  if (!fInitController.GetFlag(EInitKey::kStationsInfo)) {
     //
     // 1) Check numbers of stations passed
     //
     // loop over active detectors
     for (const auto& itemDetector : fActiveDetectorIDs) {
-      int nStationsActual   = GetStationsNumber(itemDetector);
-      int nStationsExpected = fStationsNumberCrosscheck.at(itemDetector);
+      int nStationsActual   = GetNstations(itemDetector);
+      int nStationsExpected = fNstationsActualCrosscheck.at(itemDetector);
       if (nStationsActual != nStationsExpected) {
         LOG(error) << "L1InitManager::IsStationsInfoInitialized: Incorrect number of L1BaseStationInfo objects passed"
                    << " to the L1Manager for L1DetectorID = " << static_cast<int>(itemDetector) << ": "
@@ -352,7 +364,7 @@ void L1InitManager::CheckStationsInfoInit()
     //
     // 2) Check for maximum allowed number of stations
     //
-    int nStationsTotal = GetStationsNumber();
+    int nStationsTotal = GetNstations();
     if (nStationsTotal > L1Parameters::kMaxNstations) {
       std::stringstream aStream;
       aStream << "Actual total number of registered stations (" << nStationsTotal << ") is larger then designed one ("
@@ -363,5 +375,5 @@ void L1InitManager::CheckStationsInfoInit()
       L1MASSERT(0, false, aStream.str().c_str());
     }
   }
-  fInitController.SetFlag(InitKey::keStationsInfo, ifInitPassed);
+  fInitController.SetFlag(EInitKey::kStationsInfo, ifInitPassed);
 }
diff --git a/reco/L1/L1Algo/L1InitManager.h b/reco/L1/L1Algo/L1InitManager.h
index 5d1161734f..a1e8a4fd69 100644
--- a/reco/L1/L1Algo/L1InitManager.h
+++ b/reco/L1/L1Algo/L1InitManager.h
@@ -16,6 +16,7 @@
 #include "L1ObjectInitController.h"
 #include "L1Parameters.h"
 #include "L1Utils.h"
+#include "L1Vector.h"
 
 //#include <string>
 #include <bitset>
@@ -52,36 +53,36 @@ enum class L1DetectorID;
 ///
 /// 3. Initialize number of stations for each detector:
 ///
-///    initMan->SetStationsNumberCrosscheck(L1DetectorID::kMvd, NMvdStations)
-///    initMan->SetStationsNumberCrosscheck(L1DetectorID::kMvd, NStsStations);
+///    initMan->SetNstationsCrosscheck(L1DetectorID::kMvd, NMvdStations)
+///    initMan->SetNstationsCrosscheck(L1DetectorID::kSts, NStsStations);
 ///
 /// 4. Initialize each station using L1BaseStationInfo:
 ///
 // TODO: Implement mechanism of reinitialization (S.Zharko)
 class L1InitManager {
 private:
-  enum class InitKey
+  enum class EInitKey
   {
     // NOTE: Please, keep the numbers of enum items in the existing order: it helps to debug the initialization with
     //       this->GetObjectInitController().ToString() method call (S.Zharko)
-    keActiveDetectorIDs,             ///< 0) If the detector sequence is set
-    keStationsNumberCrosscheck,      ///< 1) If the crosscheck station numbers were setup
-    keFieldFunction,                 ///< 2) If magnetic field getter funciton is set
-    keTargetPos,                     ///< 3) If target position was defined
-    kePrimaryVertexField,            ///< 4) If magnetic field value and region defined at primary vertex
-    keStationsInfo,                  ///< 5) If all the planned stations were added to the manager
-    keCAIterationsNumberCrosscheck,  ///< 6) If the number of CA track finder is initialized
-    keCAIterations,                  ///< 7) If the CA track finder iterations were initialized
-    keTrackingLevel,                 ///< 8)
-    keGhostSuppression,              ///< 9)
-    keMomentumCutOff,                ///< 10)
-    keEnd                            ///< 11) [technical] number of entries in the enum
+    kActiveDetectorIDs,             ///< 0) If the detector sequence is set
+    kStationsNumberCrosscheck,      ///< 1) If the crosscheck station numbers were setup
+    kFieldFunction,                 ///< 2) If magnetic field getter funciton is set
+    kTargetPos,                     ///< 3) If target position was defined
+    kPrimaryVertexField,            ///< 4) If magnetic field value and region defined at primary vertex
+    kStationsInfo,                  ///< 5) If all the planned stations were added to the manager
+    kCAIterationsNumberCrosscheck,  ///< 6) If the number of CA track finder is initialized
+    kCAIterations,                  ///< 7) If the CA track finder iterations were initialized
+    kTrackingLevel,                 ///< 8)
+    kGhostSuppression,              ///< 9)
+    kMomentumCutOff,                ///< 10)
+    kEnd                            ///< 11) [technical] number of entries in the enum
   };
 
   using L1DetectorIDIntMap_t     = std::unordered_map<L1DetectorID, int, L1Utils::EnumClassHash>;
   using L1DetectorIDSet_t        = std::set<L1DetectorID>;
   using L1FieldFunction_t        = std::function<void(const double (&xyz)[3], double (&B)[3])>;
-  using L1ObjectInitController_t = L1ObjectInitController<static_cast<int>(InitKey::keEnd), InitKey>;
+  using L1ObjectInitController_t = L1ObjectInitController<static_cast<int>(EInitKey::kEnd), EInitKey>;
 
 public:
   //
@@ -120,8 +121,10 @@ public:
   //
   // GETTERS
   //
-  /// Gets a set of actie detectors for this analysis
+  /// Gets a set of active detectors for this analysis
   const L1DetectorIDSet_t& GetActiveDetectorIDs() const { return fActiveDetectorIDs; }
+  /// Gets a vector of active stations indeces. If the station is inactive, it's index equals -1
+  const L1Vector<int>& GetActiveStationsIndexMap() const { return fActiveStationsIndexMap; }
   /// Gets ghost suppression flag
   int GetGhostSuppression() const { return fGhostSuppression; }
   /// Gets momentum cutoff
@@ -131,9 +134,9 @@ public:
   /// Gets a pointer to L1Parameters instance with a posibility of its fields modification
   const L1Parameters* GetParameters() const { return fpParameters; }
   /// Gets a total number of stations (NOTE: this number includes both active and unactive stations!)
-  int GetStationsNumber() const { return static_cast<int>(fStationsInfo.size()); }
+  int GetNstations() const { return static_cast<int>(fStationsInfo.size()); }
   /// Gets a number of stations for a particualr detector ID
-  int GetStationsNumber(L1DetectorID detectorID) const;
+  int GetNstations(L1DetectorID detectorID) const;
   // TODO: define enum of dimensions.... (S.Zh.)
   /// Gets a L1FieldRegion object at primary vertex
   const L1FieldRegion& GetTargetFieldRegion() const { return fTargetFieldRegion; }
@@ -176,8 +179,8 @@ public:
   void SetMomentumCutOff(float momentumCutOff);
   ///
   void SetTrackingLevel(int trackingLevel);
-  /// Sets a number of stations for a particular tracking detector ID to provide initialization cross-check
-  void SetStationsNumberCrosscheck(L1DetectorID detectorID, int nStations);
+  /// Sets a number of actual stations for a particular tracking detector ID to provide initialization cross-check
+  void SetNstationsCrosscheck(L1DetectorID detectorID, int nStations);
   /// Sets target poisition
   void SetTargetPosition(double x, double y, double z);
 
@@ -186,10 +189,10 @@ public:
 
 
 private:
-  /// Checker for L1CAIteration container initialization (sets InitKey::keCAIterations)
+  /// Checker for L1CAIteration container initialization (sets EInitKey::kCAIterations)
   /// \return true If all L1CAIteration objects were initialized properly
   void CheckCAIterationsInit();
-  /// Checker for L1BaseStationInfo set initialization (sets InitKey::keStationsInfo)
+  /// Checker for L1BaseStationInfo set initialization (sets EInitKey::kStationsInfo)
   /// \return true If all L1BaseStationInfo objects were initialized properly. Similar effect can be achieved by
   void CheckStationsInfoInit();
 
@@ -206,8 +209,17 @@ private:
 
   std::set<L1BaseStationInfo> fStationsInfo {};  ///< Set of L1BaseStationInfo objects
 
-  /// Map of station numbers used for initialization crosscheck
-  L1DetectorIDIntMap_t fStationsNumberCrosscheck {};
+  /// Map of the actual detector indeces to the active detector indeces
+  /// The vector maps actual station index (which is defined by ) to the index of station in tracking. If the station is inactive, its index is equal to -1.
+  /// Example: let stations 1 and 4 be inactive. Then:
+  ///   actual index:  0  1  2  3  4  5  6  7  8  9
+  ///   active index:  0 -1  1  2 -1  3  4  5  6  7
+  L1Vector<int> fActiveStationsIndexMap {};
+
+  /// Actual number of stations in the setup
+  L1DetectorIDIntMap_t fNstationsActualCrosscheck {};
+  /// Number of stations active in tracking
+  L1DetectorIDIntMap_t fNstationsActiveCrosscheck {};
   /// A function which returns magnetic field vector B in a radius-vector xyz
   L1FieldFunction_t fFieldFunction {[](const double (&)[3], double (&)[3]) {}};
   // NOTE: Stations of daetectors which will not be assigned as active, will not be included in the tracking!!!!!!!
-- 
GitLab