diff --git a/core/detectors/tof/CbmTofCreateDigiPar.cxx b/core/detectors/tof/CbmTofCreateDigiPar.cxx
index 5114d18495532a78e9cd68aab5704a2fa489ecaf..94849055d9038be501f7dbdcd014b5e7da0e13bd 100644
--- a/core/detectors/tof/CbmTofCreateDigiPar.cxx
+++ b/core/detectors/tof/CbmTofCreateDigiPar.cxx
@@ -147,8 +147,8 @@ InitStatus CbmTofCreateDigiPar::Init()
     gGeoManager->FindNode(fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
     TGeoNode* tGeoNode = gGeoManager->GetCurrentNode();
     nodemap.insert(std::pair<Int_t, TGeoNode*>(iAddr, tGeoNode));
-    LOG(debug) << Form("Digipar for %d, addr 0x%08x: Node=%p, x %6.2f, y %6.2f, z %6.2f ", iCell, iAddr, tGeoNode,
-                       fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
+    LOG(debug2) << Form("Digipar for %d, addr 0x%08x: Node=%p, x %6.2f, y %6.2f, z %6.2f ", iCell, iAddr, tGeoNode,
+                        fChannelInfo->GetX(), fChannelInfo->GetY(), fChannelInfo->GetZ());
   }
   fDigiPar->SetNodeMap(nodemap);
 
diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt
index 2740dfcbd1b2b9009e11f518206685a81e331f69..10f7756defcb531c9980bca17fe1b0dd5abdc7db 100644
--- a/reco/L1/CMakeLists.txt
+++ b/reco/L1/CMakeLists.txt
@@ -270,6 +270,7 @@ Install(FILES CbmL1Counters.h
               L1Algo/L1TrackParFit.h
               L1Algo/L1Triplet.h
               L1Algo/L1Vector.h
+              L1Algo/L1ObjectInitController.h
               L1Algo/L1MaterialInfo.h
               L1Algo/L1UMeasurementInfo.h
               L1Algo/L1XYMeasurementInfo.h
diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index d04bafadd323f47662b808c890a5a767775f475f..4f7590f2037cf6ae96852714043ff3b0905ed921 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -808,7 +808,7 @@ InitStatus CbmL1::Init()
       LOG(error) << "-E- CbmL1: Read geometry from file " << fSTAPDataDir + "geo_algo.txt was NOT successful.";
   }
 
-  algo->SetL1Parameters(fL1Parameters);
+  //algo->SetParameters(fParameters);
 
 
 #ifdef FEATURING_L1ALGO_INIT
@@ -818,7 +818,7 @@ InitStatus CbmL1::Init()
   {  //L1Algo new init start
 
     // Step 0: Get reference to the L1Algo initialization manager
-    L1InitManager* initMan = algo->GetL1InitManager();
+    L1InitManager* initMan = algo->GetInitManager();
 
     // Step 1: Initialize magnetic field function
     // Set magnetic field slices
@@ -970,7 +970,7 @@ InitStatus CbmL1::Init()
       fscal tofBackSigma  = 1.;
       stationInfo.SetFrontBackStripsGeometry(tofFrontPhi, tofFrontSigma, tofBackPhi, tofBackSigma);
     }
-    initMan->PrintStations(/*vebosity = */ 1);
+    //initMan->PrintStations(/*vebosity = */ 1);
 
     // Step 7: initialize iterations and form a vector of them
     {
@@ -1088,7 +1088,6 @@ InitStatus CbmL1::Init()
         initMan->PushBackCAIteration(trackingIterAllSec);
       }
       else {
-        std::cout << "HERE";
         initMan->SetCAIterationsNumberCrosscheck(9);
         // Initialize CA track finder iterations sequence
         initMan->PushBackCAIteration(trackingIterFastPrim);
@@ -1101,7 +1100,6 @@ InitStatus CbmL1::Init()
         initMan->PushBackCAIteration(trackingIterFastPrim2);
         initMan->PushBackCAIteration(trackingIterAllSecJump);
       }
-      initMan->PrintCAIterations();
 
       // Set special cuts
     }
diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h
index 30f6ded6cf850fcc4ca5343389e99aabb8da296b..f40650d36119c34c80be3dd457b27a27a46baf3d 100644
--- a/reco/L1/CbmL1.h
+++ b/reco/L1/CbmL1.h
@@ -118,7 +118,8 @@ enum class L1CAIterationType
 //
 /// L1Algo runtime constants modification can be performed in run_reco.C. Example:
 ///
-///   l1->GetL1Parameters()->SetMaxDoubletsPerSinglet(149);
+///   l1->GetInitManager()->GetParameters()->SetMaxDoubletsPerSinglet(149);
+/// TODO: L1InitManager - main interface of communication between cbmroot/bmnroot and L1Algo (S.Zharko)
 ///
 class CbmL1 : public FairTask {
 private:
@@ -157,7 +158,7 @@ public:
 
   ~CbmL1(/*if (targetFieldSlice) delete;*/);
 
-  L1Parameters* GetL1Parameters() { return &fL1Parameters; }
+  //L1Parameters* GetParameters() { return &fParameters; }
 
   /// Gets a set of active detectors used in tracking
   // TODO: think about return (value, reference or const reference?) (S.Zh.)
@@ -272,7 +273,8 @@ public:
 
 private:
   static CbmL1* fInstance;
-  L1Parameters fL1Parameters;
+
+  L1InitManager* fpInitManager {nullptr};  ///< Pointer to L1InitManager object of L1 algorithm core
 
   std::set<L1DetectorID> fActiveTrackingDetectorIDs {L1DetectorID::kMvd,
                                                      L1DetectorID::kSts};  ///< Set of detectors active in tracking
diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx
index 0fd6b67e52ce42ccbdecdf80357a5721894cfe07..bebda2986c90a210e4d5296f66fc92760045e07d 100644
--- a/reco/L1/L1Algo/L1Algo.cxx
+++ b/reco/L1/L1Algo/L1Algo.cxx
@@ -61,8 +61,6 @@ void L1Algo::SetNThreads(unsigned int n)
 
 void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const TrackingMode mode, const bool MissingHits)
 {
-  fL1Parameters.Print();  // TODO: Wrap this line into debug (S.Zh.)
-
   for (int iProc = 0; iProc < 4; iProc++) {
     for (int i = 0; i < 8; i++) {
       threadNumberToCpuMap[2 * i + 0 + iProc * 20] = 4 * i + iProc;
@@ -231,12 +229,19 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra
   // NEW INITIALIZATION (BETA)
   //
 
+  // Final init checks (the function provides purity of fields initialization and turn on the last bits of
+  // the L1ObjectInitController):
+  fInitManager.CheckInit();  // NOTE: after passing this frontier L1Algo is (will be) accounted as initialized
+
+  // Check initialization
+  LOG(info) << "InitManager " << fInitManager.GetInitController().ToString();
+
   // Get number of stations
-  int NStationsNew = fInitManager.GetStationsNumber();
+  int nStationsNew = fInitManager.GetStationsNumber();
   // TODO: we must to get rid of station specification in the L1Algo (S.Zh.)
-  int NMvdStationsNew   = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(0));
-  int NStsStationsNew   = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(1));
-  int NfieldStationsNew = NMvdStationsNew + NStsStationsNew;
+  int nMvdStationsNew   = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(0));
+  int nStsStationsNew   = fInitManager.GetStationsNumber(static_cast<L1DetectorID>(1));
+  int nFieldStationsNew = nMvdStationsNew + nStsStationsNew;
 
   // Get field near target
   L1FieldValue vtxFieldValueNew   = fInitManager.GetTargetFieldValue();
@@ -245,7 +250,6 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra
   // Fill L1Station array
   fInitManager.TransferL1StationArray(fStationsNew);
 
-
   LOG(info) << "**********************************************************************";
   LOG(info) << "*  New L1Algo initialization cross check  (tmp log, to be removed!)  *";
   LOG(info) << "**********************************************************************";
@@ -255,10 +259,10 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra
   LOG(info) << "\tSTS:   " << NStsStations;
   LOG(info) << "\tField: " << fNfieldStations;
   LOG(info) << "** Number of stations (new) **";
-  LOG(info) << "\tTotal: " << NStationsNew;
-  LOG(info) << "\tMVD:   " << NMvdStationsNew;
-  LOG(info) << "\tSTS:   " << NStsStationsNew;
-  LOG(info) << "\tField: " << NfieldStationsNew;
+  LOG(info) << "\tTotal: " << nStationsNew;
+  LOG(info) << "\tMVD:   " << nMvdStationsNew;
+  LOG(info) << "\tSTS:   " << nStsStationsNew;
+  LOG(info) << "\tField: " << nFieldStationsNew;
 
   LOG(info) << "** Magnetic field near target (original)**";
   LOG(info) << "\tField Value:  " << '\n' << vtxFieldValue.ToString(/*indent = */ 1) << '\n';
@@ -280,6 +284,9 @@ void L1Algo::Init(const L1Vector<fscal>& geo, const bool UseHitErrors, const Tra
     LOG(info) << "Station Global No: " << iSt;
     LOG(info) << '\n' << fStationsNew[iSt].ToString(/*verbosity = */ 3);
   }
+
+  // Print L1Parameters
+  fParameters.Print(/*verbosity=*/0);
 }
 
 
@@ -448,5 +455,3 @@ void L1Algo::CreateHitPoint(const L1Hit& hit, L1HitPoint& point)
 // }
 //
 //   inline int L1Algo::UnPackIndex(const int& i, int& a, int& b, int& c) {
-//       return   (a) + ((b)*10000) + (c*100000000);
-// }
diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h
index 6513fa82e1a3740cc2e02931723ac7feb83420d4..5f4077e342e1f8a6252d3de4ebf6875691d4957b 100644
--- a/reco/L1/L1Algo/L1Algo.h
+++ b/reco/L1/L1Algo/L1Algo.h
@@ -81,7 +81,8 @@ class L1AlgoEfficiencyPerformance;
 #endif
 typedef int Tindex;
 
-
+/// Central class of L1 tracking
+///
 class L1Algo {
 public:
   L1Algo(unsigned int nThreads = 1);
@@ -360,20 +361,19 @@ public:
 
 
   /// Sets L1Algo parameters object
-  void SetL1Parameters(const L1Parameters& other) { fL1Parameters = other; }
-  /// Gets a constant reference to the L1Algo parameters object
-  const L1Parameters& GetL1Parameters() const { return fL1Parameters; }
-  // TODO: We should think about, where non-constexpr L1Algo parameters can be modified. At the moment we can create a
-  //       L1Parameters object somewhere outside the L1Algo, fill its fields there and then pass it directly to
-  //       the L1Algo instance. (S.Zh.)
-  L1InitManager* GetL1InitManager() { return &fInitManager; }
+  void SetParameters(const L1Parameters& other) { fParameters = other; }
+
+  /// Gets a pointer to the L1Algo parameters object
+  L1Parameters* GetParameters() { return &fParameters; }
+  /// Gets a pointer to the L1Algo initialization object
+  L1InitManager* GetInitManager() { return &fInitManager; }
 
   fvec GetCbmTargetZ() const { return fCbmTargetZ; }
 
 private:
-  /// Object containing L1Parameters. Default consturctor is used
-  L1Parameters fL1Parameters;  ///< Object of L1Algo parameters class
-  L1InitManager fInitManager;  ///< Object of L1Algo initialization manager class
+  L1Parameters fParameters {};                ///< Object of L1Algo parameters class
+  L1InitManager fInitManager {&fParameters};  ///< Object of L1Algo initialization manager class
+
 
   /// =================================  FUNCTIONAL PART  =================================
 
diff --git a/reco/L1/L1Algo/L1BaseStationInfo.cxx b/reco/L1/L1Algo/L1BaseStationInfo.cxx
index 81ebddd8ad04253ef964b0b490af4879dfc50287..648cb0fd32f06692b5cbb38ff3da68be1c7ebc37 100644
--- a/reco/L1/L1Algo/L1BaseStationInfo.cxx
+++ b/reco/L1/L1Algo/L1BaseStationInfo.cxx
@@ -20,7 +20,6 @@
 #include "L1BaseStationInfo.h"
 #include "L1Def.h"
 #include "L1Parameters.h"
-
 // C++ STL
 #include <iomanip>
 #include <sstream>
@@ -44,8 +43,8 @@ L1BaseStationInfo::L1BaseStationInfo(L1DetectorID detectorID, int stationID) noe
   , fStationID(stationID)
 {
   LOG(debug) << "L1BaseStationInfo: Constructor (detectorID, stationID) called for " << this << '\n';  // Temporary
-  fInitFlags[keDetectorID] = true;
-  fInitFlags[keStationID]  = true;
+  fInitController.SetFlag(InitKey::keDetectorID);
+  fInitController.SetFlag(InitKey::keStationID);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -64,7 +63,7 @@ L1BaseStationInfo::L1BaseStationInfo(const L1BaseStationInfo& other) noexcept
   , fYmax(other.fYmax)
   , fZPos(other.fZPos)
   , fL1Station(other.fL1Station)
-  , fInitFlags(other.fInitFlags)
+  , fInitController(other.fInitController)
 {
   LOG(debug) << "L1BaseStationInfo: Copy constructor called: " << &other << " was copied into " << this;
 }
@@ -98,18 +97,6 @@ L1BaseStationInfo& L1BaseStationInfo::operator=(L1BaseStationInfo&& other) noexc
   return *this;
 }
 
-//----------------------------------------------------------------------------------------------------------------------//
-//
-void L1BaseStationInfo::Swap(L1BaseStationInfo& other) noexcept
-{
-  std::swap(fDetectorID, other.fDetectorID);
-  std::swap(fStationID, other.fStationID);
-  std::swap(fXmax, other.fXmax);
-  std::swap(fYmax, other.fYmax);
-  std::swap(fZPos, other.fZPos);
-  std::swap(fL1Station, other.fL1Station);
-  std::swap(fInitFlags, other.fInitFlags);
-}
 
 //
 // BASIC METHODS
@@ -139,19 +126,18 @@ void L1BaseStationInfo::Print(int verbosity) const
 void L1BaseStationInfo::Reset()
 {
   L1BaseStationInfo other;
-  std::swap(*this, other);
+  this->Swap(other);
 }
 
 
 //
 // GETTERS
 //
-
 //----------------------------------------------------------------------------------------------------------------------//
 //
 const L1Station& L1BaseStationInfo::GetL1Station() const
 {
-  bool isStationInitialized = IsInitialized();
+  bool isStationInitialized = fInitController.IsFinalized();
   if (!isStationInitialized) {
     LOG(error)
       << "L1BaseStationInfo::GetL1Station: attempt to get an L1Staion object from uninitialized L1BaseStation with "
@@ -161,31 +147,17 @@ const L1Station& L1BaseStationInfo::GetL1Station() const
   return fL1Station;
 }
 
-
 //
 // SETTERS
 //
 
-//----------------------------------------------------------------------------------------------------------------------//
-//
-void L1BaseStationInfo::SetStationID(int inID)
-{
-  if (!fInitFlags[keStationID]) {
-    fStationID              = inID;
-    fInitFlags[keStationID] = true;
-  }
-  else {
-    LOG(warn) << "L1BaseStationInfo::SetStationID: Attempt of station ID redifinition";
-  }
-}
-
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetDetectorID(L1DetectorID inID)
 {
-  if (!fInitFlags[keDetectorID]) {
-    fDetectorID              = inID;
-    fInitFlags[keDetectorID] = true;
+  if (!fInitController.GetFlag(InitKey::keDetectorID)) {
+    fDetectorID = inID;
+    fInitController.SetFlag(InitKey::keDetectorID);
   }
   else {
     LOG(warn) << "L1BaseStationInfo::SetDetectorID: Attempt of detector ID redifinition";
@@ -194,70 +166,25 @@ void L1BaseStationInfo::SetDetectorID(L1DetectorID inID)
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
-void L1BaseStationInfo::SetStationType(int inType)
-{
-  if (!fInitFlags[keType]) {
-    fL1Station.type    = inType;
-    fInitFlags[keType] = true;
-  }
-  else {
-    LOG(warn) << "L1BaseStationInfo::SetStationType: Attempt of station type redifinition";
-  }
-}
-
-//----------------------------------------------------------------------------------------------------------------------//
-//
-void L1BaseStationInfo::SetTimeInfo(int inTimeInfo)
-{
-  fL1Station.timeInfo    = inTimeInfo;
-  fInitFlags[keTimeInfo] = true;
-}
-
-//----------------------------------------------------------------------------------------------------------------------//
-//
-void L1BaseStationInfo::SetZ(double inZ)
+void L1BaseStationInfo::SetRmax(double inRmax)
 {
-  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
-  fInitFlags[keZ] = true;
+  fL1Station.Rmax = inRmax;
+  fInitController.SetFlag(InitKey::keRmax);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetRmin(double inRmin)
 {
-  fL1Station.Rmin    = inRmin;
-  fInitFlags[keRmin] = true;
-}
-
-//----------------------------------------------------------------------------------------------------------------------//
-//
-void L1BaseStationInfo::SetRmax(double inRmax)
-{
-  fL1Station.Rmax    = inRmax;
-  fInitFlags[keRmax] = true;
-}
-
-//----------------------------------------------------------------------------------------------------------------------//
-//
-void L1BaseStationInfo::SetMaterial(double inThickness, double inRL)
-{
-#ifndef L1_NO_ASSERT  // check for zero denominator
-  L1_ASSERT(inRL, "Attempt of entering zero inRL (radiational length) value");
-#endif
-  fL1Station.materialInfo.thick       = inThickness;
-  fL1Station.materialInfo.RL          = inRL;
-  fL1Station.materialInfo.RadThick    = fL1Station.materialInfo.thick / fL1Station.materialInfo.RL;
-  fL1Station.materialInfo.logRadThick = log(fL1Station.materialInfo.RadThick);
-  fInitFlags[keMaterialInfoThick]     = true;
-  fInitFlags[keMaterialInfoRL]        = true;
+  fL1Station.Rmin = inRmin;
+  fInitController.SetFlag(InitKey::keRmin);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetFieldSlice(const double* Cx, const double* Cy, const double* Cz)
 {
-  if (fInitFlags[keFieldSlice]) {
+  if (fInitController.GetFlag(InitKey::keFieldSlice)) {
     LOG(warn) << "L1BaseStationInfo::SetFieldSlice: Attempt to redifine field slice for station with detectorID = "
               << static_cast<int>(fDetectorID) << " and stationID = " << fStationID << ". Redifinition ignored";
     return;
@@ -269,23 +196,26 @@ void L1BaseStationInfo::SetFieldSlice(const double* Cx, const double* Cy, const
     fL1Station.fieldSlice.cz[idx] = Cz[idx];
   }
 
-  fInitFlags[keFieldSlice] = true;
+  fInitController.SetFlag(InitKey::keFieldSlice);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetFieldSlice(const std::function<void(const double (&xyz)[3], double (&B)[3])>& getFieldValue)
 {
-  if (fInitFlags[keFieldSlice]) {
+  if (fInitController.GetFlag(InitKey::keFieldSlice)) {
     LOG(warn) << "L1BaseStationInfo::SetFieldSlice: Attempt to redifine field slice for station with detectorID = "
               << static_cast<int>(fDetectorID) << " and stationID = " << fStationID << ". Redifinition ignored";
     return;
   }
 
 #ifndef L1_NO_ASSERT  // check for zero denominator
-  L1_ASSERT(fInitFlags[keZ], "Attempt to set magnetic field slice before setting z position of the station");
-  L1_ASSERT(fInitFlags[keXmax], "Attempt to set magnetic field slice before setting Xmax size of the station");
-  L1_ASSERT(fInitFlags[keYmax], "Attempt to set magnetic field slice before setting Ymax size of the station");
+  L1_ASSERT(fInitController.GetFlag(InitKey::keZ),
+            "Attempt to set magnetic field slice before setting z position of the station");
+  L1_ASSERT(fInitController.GetFlag(InitKey::keXmax),
+            "Attempt to set magnetic field slice before Xmax size of the station");
+  L1_ASSERT(fInitController.GetFlag(InitKey::keYmax),
+            "Attempt to set magnetic field slice before Ymax size of the station");
 #endif
   // TODO: Change names of variables according to convention (S.Zh.)
   constexpr int M = L1Parameters::kMaxFieldApproxPolynomialOrder;
@@ -355,7 +285,7 @@ void L1BaseStationInfo::SetFieldSlice(const std::function<void(const double (&xy
     fL1Station.fieldSlice.cz[j] = A[j][N + 2] / A[j][j];
   }
 
-  fInitFlags[keFieldSlice] = true;
+  fInitController.SetFlag(InitKey::keFieldSlice);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
@@ -369,7 +299,6 @@ void L1BaseStationInfo::SetFrontBackStripsGeometry(double frontPhi, double front
   double sBack  = sin(backPhi);
 
   // NOTE: Here additional double variables are used to save the precission
-
   fL1Station.frontInfo.cos_phi = cFront;
   fL1Station.frontInfo.sin_phi = sFront;
   fL1Station.frontInfo.sigma2  = frontSigma * frontSigma;
@@ -378,21 +307,6 @@ void L1BaseStationInfo::SetFrontBackStripsGeometry(double frontPhi, double front
   fL1Station.backInfo.sin_phi = sBack;
   fL1Station.backInfo.sigma2  = backSigma * backSigma;
 
-  //if (fabs(b_phi - f_phi) < .1) {
-  //  double th  = b_phi - f_phi;
-  //  double det = cos(th);
-  //  det *= det;
-  //  fL1Station.XYInfo.C00 = (s_b * s_b * f_sigma * f_sigma + s_f * s_f * b_sigma * b_sigma) / det;
-  //  fL1Station.XYInfo.C10 = -(s_b * c_b * f_sigma * f_sigma + s_f * c_f * b_sigma * b_sigma) / det;
-  //  fL1Station.XYInfo.C11 = (c_b * c_b * f_sigma * f_sigma + c_f * c_f * b_sigma * b_sigma) / det;
-  //} else {
-  //  double det = c_f * s_b - s_f * c_b;
-  //  det *= det;
-  //  fL1Station.XYInfo.C00 = (s_b * s_b * f_sigma * f_sigma + s_f * s_f * b_sigma * b_sigma) / det;
-  //  fL1Station.XYInfo.C10 = -(s_b * c_b * f_sigma * f_sigma + s_f * c_f * b_sigma * b_sigma) / det;
-  //  fL1Station.XYInfo.C11 = (c_b * c_b * f_sigma * f_sigma + c_f * c_f * b_sigma * b_sigma) / det;
-  //}
-
   double det = (fabs(backPhi - frontPhi) < 0.1) ? cos(backPhi - frontPhi) : (cFront * sBack - sFront * cBack);
   det *= det;
   fL1Station.XYInfo.C00 = (sBack * sBack * frontSigma * frontSigma + sFront * sFront * backSigma * backSigma) / det;
@@ -408,26 +322,97 @@ void L1BaseStationInfo::SetFrontBackStripsGeometry(double frontPhi, double front
   fL1Station.yInfo.sigma2  = fL1Station.XYInfo.C11;
   //-----------------------------------------------------------------------------------------------------//
 
-  fInitFlags[keStripsFrontPhi]   = true;
-  fInitFlags[keStripsFrontSigma] = true;
-  fInitFlags[keStripsBackPhi]    = true;
-  fInitFlags[keStripsBackSigma]  = true;
+  fInitController.SetFlag(InitKey::keStripsFrontPhi);
+  fInitController.SetFlag(InitKey::keStripsFrontSigma);
+  fInitController.SetFlag(InitKey::keStripsBackPhi);
+  fInitController.SetFlag(InitKey::keStripsBackSigma);
+}
+
+//----------------------------------------------------------------------------------------------------------------------//
+//
+void L1BaseStationInfo::SetMaterial(double inThickness, double inRL)
+{
+#ifndef L1_NO_ASSERT  // check for zero denominator
+  L1_ASSERT(inRL, "Attempt of entering zero inRL (radiational length) value");
+#endif
+  fL1Station.materialInfo.thick       = inThickness;
+  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);
+}
+
+//----------------------------------------------------------------------------------------------------------------------//
+//
+void L1BaseStationInfo::SetStationID(int inID)
+{
+  if (!fInitController.GetFlag(InitKey::keStationID)) {
+    fStationID = inID;
+    fInitController.SetFlag(InitKey::keStationID);
+  }
+  else {
+    LOG(warn) << "L1BaseStationInfo::SetStationID: Attempt of station ID redifinition";
+  }
+}
+
+//----------------------------------------------------------------------------------------------------------------------//
+//
+void L1BaseStationInfo::SetStationType(int inType)
+{
+  if (!fInitController.GetFlag(InitKey::keType)) {
+    fL1Station.type = inType;
+    fInitController.SetFlag(InitKey::keType);
+  }
+  else {
+    LOG(warn) << "L1BaseStationInfo::SetStationType: Attempt of station type redifinition";
+  }
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetXmax(double aSize)
 {
-  fXmax              = aSize;
-  fInitFlags[keXmax] = true;
+  fXmax = aSize;
+  fInitController.SetFlag(InitKey::keXmax);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
 //
 void L1BaseStationInfo::SetYmax(double aSize)
 {
-  fYmax              = aSize;
-  fInitFlags[keYmax] = true;
+  fYmax = aSize;
+  fInitController.SetFlag(InitKey::keYmax);
+}
+
+//----------------------------------------------------------------------------------------------------------------------//
+//
+void L1BaseStationInfo::SetTimeInfo(int inTimeInfo)
+{
+  fL1Station.timeInfo = inTimeInfo;
+  fInitController.SetFlag(InitKey::keTimeInfo);
+}
+
+//----------------------------------------------------------------------------------------------------------------------//
+//
+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);
+}
+
+//----------------------------------------------------------------------------------------------------------------------//
+//
+void L1BaseStationInfo::Swap(L1BaseStationInfo& other) noexcept
+{
+  std::swap(fDetectorID, other.fDetectorID);
+  std::swap(fStationID, other.fStationID);
+  std::swap(fXmax, other.fXmax);
+  std::swap(fYmax, other.fYmax);
+  std::swap(fZPos, other.fZPos);
+  std::swap(fL1Station, other.fL1Station);
+  std::swap(fInitController, other.fInitController);
 }
 
 //----------------------------------------------------------------------------------------------------------------------//
diff --git a/reco/L1/L1Algo/L1BaseStationInfo.h b/reco/L1/L1Algo/L1BaseStationInfo.h
index 17f511e2548216dc9b6b061024c55998bcef2b5e..9120ccd6d0f3c380547f70f5f173946217afbcd4 100644
--- a/reco/L1/L1Algo/L1BaseStationInfo.h
+++ b/reco/L1/L1Algo/L1BaseStationInfo.h
@@ -15,43 +15,48 @@
 #ifndef L1BaseStationInfo_h
 #define L1BaseStationInfo_h 1
 
+// L1 Core
+#include "L1ObjectInitController.h"
+#include "L1Station.h"
 // C++ std
-#include <bitset>
 #include <functional>
 #include <string>
 
-#include "L1Station.h"
-
 enum class L1DetectorID;
 
 /// A base class which provides interface to L1Algo station geometry
 class L1BaseStationInfo {
-private:
-  enum
-  {  // Here we list all the fields, which must be initialized by user
+public:
+  /// Enumeration of fields, which must be initialized so the object can pass the threshold
+  enum class InitKey
+  {
     // Basic fields initialization
-    keDetectorID,
-    keStationID,
-    keXmax,
-    keYmax,
+    keDetectorID,  ///< detector ID
+    keStationID,   ///< station ID
+    keXmax,        ///< max size in X direction
+    keYmax,        ///< max size in Y direction
     // L1Station initialization
-    keType,
-    keTimeInfo,
-    keZ,
-    keRmin,
-    keRmax,
-    keMaterialInfoThick,
-    keMaterialInfoRL,
-    keFieldSlice,
-    keStripsFrontPhi,
-    keStripsFrontSigma,
-    keStripsBackPhi,
-    keStripsBackSigma,
+    keType,               ///< station type
+    keTimeInfo,           ///< if time info is used (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,    ///<
     // The last item is equal to the number of bits in fInitFlags
     keEnd
   };
 
-public:
+  using L1ObjectInitController_t = L1ObjectInitController<static_cast<int>(InitKey::keEnd), InitKey>;
+
+  //
+  // CONSTRUCTORS AND DESTRUCTORS
+  //
   /// Default constructor
   L1BaseStationInfo() noexcept;
   /// Constructor from stationID and detectorID
@@ -62,28 +67,14 @@ public:
   L1BaseStationInfo(const L1BaseStationInfo& other) noexcept;
   /// Move constructor
   L1BaseStationInfo(L1BaseStationInfo&& other) noexcept;
-  /// Copy operator=
+  /// Copy assignment operator
   L1BaseStationInfo& operator=(const L1BaseStationInfo& other) noexcept;
-  /// Move operator=
+  /// Move assignment operator
   L1BaseStationInfo& operator=(L1BaseStationInfo&& other) noexcept;
-  /// Swap method for easier implementation of above ones (NOTE: all the fields must be accounted carefully here)
-  void Swap(L1BaseStationInfo& other) noexcept;
 
   //
   // BASIC METHODS
   //
-
-  /// Checks if all the necessary fields are initialized by user
-  bool IsInitialized() const { return fInitFlags.size() == fInitFlags.count(); }
-  /// Prints registered fields
-  /// verbosity = 0: print only station id, detector id and address in one line
-  /// verbosity = 1: print basic L1Station fields
-  /// verbosity = 2: print all L1Staion fields
-  void Print(int verbosity = 0) const;
-  /// Print initialization flags (debug function)
-  void PrintInit() const;
-  /// Resets fields to the default values
-  void Reset();
   /// Less operator for L1BaseStationInfo object to perform their sorts. Sorting is carried out first by fDetectorID,
   /// and then by fStationID
   bool operator<(const L1BaseStationInfo& right) const
@@ -91,84 +82,65 @@ public:
     return fDetectorID != right.fDetectorID ? fDetectorID < right.fDetectorID : fStationID < right.fStationID;
   }
 
-
   //
   // GETTERS
   //
-
-  /// Gets station ID
-  int GetStationID() const { return fStationID; }
   /// Gets detector ID
   L1DetectorID GetDetectorID() const { return fDetectorID; }
-  /// Gets station type
-  int GetStationType() const { return fL1Station.type; }
-  /// Gets SIMD vectorized z position of the station
-  fvec GetZsimdVec() const { return fL1Station.z; }
-  /// Gets double precised z position of the station
-  double GetZdouble() const { return fZPos; }
-  /// Gets min transverse size of the station
-  fvec GetRmin() const { return fL1Station.Rmin; }
-  /// Gets max transverse size of the station
-  fvec GetRmax() const { return fL1Station.Rmax; }
-
-  /// Gets material thickness
-  fvec GetMaterialThickness() const { return fL1Station.materialInfo.thick; }
-  /// Gets the radiation length of the station material
-  fvec GetMaterialRadLength() const { return fL1Station.materialInfo.RL; }
-  /// Gets the relative material thickness in units of the radiational length
-  fvec GetMaterialRadThick() const { return fL1Station.materialInfo.RadThick; }
-  /// Gets log of the relative material thickness in units of the radiational length
-  fvec GetMaterialLogRadThick() const { return fL1Station.materialInfo.logRadThick; }
-
   /// Gets a coefficient with idx for the field x-component approximation
   fvec GetFieldSliceCx(int idx) const { return fL1Station.fieldSlice.cx[idx]; }
   /// Gets a coefficient with idx for the field y-component approximation
   fvec GetFieldSliceCy(int idx) const { return fL1Station.fieldSlice.cy[idx]; }
   /// Gets a coefficient with idx for the field z-component approximation
   fvec GetFieldSliceCz(int idx) const { return fL1Station.fieldSlice.cz[idx]; }
-
   /// Gets array of the coefficients for the field x-component approximation
   const fvec* GetFieldSliceCx() const { return fL1Station.fieldSlice.cx; }
   /// Gets array of the coefficients for the field y-component approximation
   const fvec* GetFieldSliceCy() const { return fL1Station.fieldSlice.cy; }
   /// Gets array of the coefficients for the field z-component approximation
   const fvec* GetFieldSliceCz() const { return fL1Station.fieldSlice.cz; }
-
+  /// Gets a const reference to the L1ObjectInitController object
+  const L1ObjectInitController_t& GetInitController() const { return fInitController; }
+  /// Gets a reference to L1Station info field of the L1BaseStation info
+  const L1Station& GetL1Station() const;
+  /// Gets material thickness
+  fvec GetMaterialThickness() const { return fL1Station.materialInfo.thick; }
+  /// Gets the radiation length of the station material
+  fvec GetMaterialRadLength() const { return fL1Station.materialInfo.RL; }
+  /// Gets the relative material thickness in units of the radiational length
+  fvec GetMaterialRadThick() const { return fL1Station.materialInfo.RadThick; }
+  /// Gets log of the relative material thickness in units of the radiational length
+  fvec GetMaterialLogRadThick() const { return fL1Station.materialInfo.logRadThick; }
+  /// Gets min transverse size of the station
+  fvec GetRmin() const { return fL1Station.Rmin; }
+  /// Gets max transverse size of the station
+  fvec GetRmax() const { return fL1Station.Rmax; }
+  /// Gets station ID
+  int GetStationID() const { return fStationID; }
+  /// Gets station type
+  int GetStationType() const { return fL1Station.type; }
   /// 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
   double GetYmax() const { return fYmax; }
+  /// Gets double precised z position of the station
+  double GetZdouble() const { return fZPos; }
+  /// Gets SIMD vectorized z position of the station
+  fvec GetZsimdVec() const { return fL1Station.z; }
 
-  /// Gets a reference to L1Station info field of the L1BaseStation info
-  const L1Station& GetL1Station() const;
-  /// Gets a reference to Bitset object of initialization bits
-  const std::bitset<L1BaseStationInfo::keEnd>& GetInitFlags() const { return fInitFlags; }
-
+  /// Prints registered fields
+  /// verbosity = 0: print only station id, detector id and address in one line
+  /// verbosity = 1: print basic L1Station fields
+  /// verbosity = 2: print all L1Staion fields
+  void Print(int verbosity = 0) const;
+  /// Resets fields to the default values
+  void Reset();
 
   //
   //  SETTERS
   //
-
-  /// Sets station ID
-  void SetStationID(int inID);
   /// Sets detector ID
   void SetDetectorID(L1DetectorID inID);
-
-  /// Sets type of station
-  void SetStationType(int inType);  // TODO: this is a temporary solution (S.Zh.)
-  /// Sets flag: 0 - time information is not provided by this detector type
-  //             1 - time information is provided by the detector and can be used in tracking
-  void SetTimeInfo(int inTimeInfo);
-  /// Sets nominal z position of the station
-  void SetZ(double inZ);
-  /// Sets min transverse size of the station
-  void SetRmin(double inRmin);
-  /// Sets max transverse size of the station
-  void SetRmax(double inRmax);
-  /// Sets station thickness and radiational length
-  /// \param thickness         thickness of station
-  /// \param radiationalLength radiational length of station
-  void SetMaterial(double thickness, double radiationalLength);
   /// Sets field approximation at the station plain
   /// \param Cx Array of approximation coefficients for x field component
   /// \param Cy Array of approximation coefficients for y field component
@@ -184,10 +156,31 @@ public:
   /// \param b_phi   Stereoangle of back strips
   /// \param b_sigma Sigma of back strips
   void SetFrontBackStripsGeometry(double fPhi, double fSigma, double bPhi, double bSigma);
+  /// Sets station thickness and radiational length
+  /// \param thickness         thickness of station
+  /// \param radiationalLength radiational length of station
+  void SetMaterial(double thickness, double radiationalLength);
+  /// Sets max transverse size of the station
+  void SetRmax(double inRmax);
+  /// Sets min transverse size of the station
+  void SetRmin(double inRmin);
+  /// Sets station ID
+  void SetStationID(int inID);
+  /// Sets type of station
+  void SetStationType(int inType);  // TODO: this is a temporary solution (S.Zh.)
+  /// Sets flag: 0 - time information is not provided by this detector type
+  ///            1 - time information is provided by the detector and can be used in tracking
+  void SetTimeInfo(int inTimeInfo);
   /// 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
   void SetYmax(double aSize);
+  /// Sets nominal z position of the station
+  void SetZ(double inZ);
+
+  /// Swap method for easier implementation of above ones (NOTE: all the fields must be accounted carefully here)
+  void Swap(L1BaseStationInfo& other) noexcept;
+
   /// String representation of class contents
   /// \param indentLevel    number of indent characters in the output
   std::string ToString(int verbosityLevel = 0, int indentLevel = 0) const;
@@ -199,7 +192,7 @@ private:
   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
   L1Station fL1Station {};  ///< L1Station structure, describes a station in L1Algo
-  std::bitset<L1BaseStationInfo::keEnd> fInitFlags;  ///< Class fileds initialization flags
+  L1ObjectInitController_t fInitController {};  ///< Class fileds initialization flags
 };
 
 /// swap function for two L1BaseStationInfo objects, expected to be used instead of std::swap
diff --git a/reco/L1/L1Algo/L1CAIteration.cxx b/reco/L1/L1Algo/L1CAIteration.cxx
index b96eacd1a36aafb4a75d50f77035cc3d9d8468d3..9bd07054db86b0c50157327093f62e76af39d591 100644
--- a/reco/L1/L1Algo/L1CAIteration.cxx
+++ b/reco/L1/L1Algo/L1CAIteration.cxx
@@ -89,8 +89,9 @@ L1CAIteration::L1CAIteration(const std::string& name) noexcept : fName(name)
 //
 void L1CAIteration::Print(int verbosityLevel) const
 {
-  LOG(info) << "CA Track Finder Iteration: " << fName;
+  if (verbosityLevel == 0) { LOG(info) << "  - " << fName; }
   if (verbosityLevel > 0) {
+    LOG(info) << "L1CAIteration: " << fName;
     LOG(info) << "\tTrack chi2 cut: " << fTrackChi2Cut;
     LOG(info) << "\tTriplet chi2 cut: " << fTripletChi2Cut;
     LOG(info) << "\tDoublet chi2 cut: " << fDoubletChi2Cut;
diff --git a/reco/L1/L1Algo/L1CAIteration.h b/reco/L1/L1Algo/L1CAIteration.h
index e81bd35272e7e3097627adbe6f7877499ba7b708..372f12d163a6fc0e758413ab4a3ebf609144a6df 100644
--- a/reco/L1/L1Algo/L1CAIteration.h
+++ b/reco/L1/L1Algo/L1CAIteration.h
@@ -7,7 +7,6 @@
  * @file L1CAIteration.h
  * @brief Class for L1 CA Track Finder Iteration 
  * @since 01.15.2022
- *
  ***********************************************************************************************************/
 
 #ifndef L1CAIteration_h
diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx
index 56dff8798412053eff3ae5bbb99e6db5b832b247..6cc6f718f7b6c1b3a633864bff23d6c6ae6fc94c 100644
--- a/reco/L1/L1Algo/L1CATrackFinder.cxx
+++ b/reco/L1/L1Algo/L1CATrackFinder.cxx
@@ -539,10 +539,10 @@ inline void L1Algo::f20(
 
 #ifndef FAST_CODE
 //TODO: optimise triplet portion limit and put a warning
-// assert(Ndoublets < fL1Parameters.GetMaxDoubletsPerSinglet());
+// assert(Ndoublets < fParameters.GetMaxDoubletsPerSinglet());
 #endif  // FAST_CODE
 
-      if (Ndoublets >= fL1Parameters.GetMaxDoubletsPerSinglet()) {
+      if (Ndoublets >= fParameters.GetMaxDoubletsPerSinglet()) {
         n2 = n2 - Ndoublets;
         i1_2.reduce(i1_2.size() - Ndoublets);
         hitsm_2.reduce(hitsm_2.size() - Ndoublets);
@@ -867,9 +867,9 @@ inline void L1Algo::f30(  // input
 
 #ifndef FAST_CODE
 //TODO: optimise triplet portion limit and put a warning
-// assert(Ntriplets < fL1Parameters.GetMaxTripletPerDoublets());
+// assert(Ntriplets < fParameters.GetMaxTripletPerDoublets());
 #endif  // FAST_CODE
-          if (Ntriplets >= fL1Parameters.GetMaxTripletPerDoublets()) {
+          if (Ntriplets >= fParameters.GetMaxTripletPerDoublets()) {
 
             n3 = n3 - Ntriplets;
 
diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx
index 9a867b145fe2a77bf0b4d686cac7f4145c20d2cb..9a94d47a8bda5cf14a16486c3614413dc328a09a 100644
--- a/reco/L1/L1Algo/L1InitManager.cxx
+++ b/reco/L1/L1Algo/L1InitManager.cxx
@@ -6,13 +6,15 @@
  * @file L1InitManager.cxx
  * @bried Input data management class for L1Algo
  * @since 19.01.2022
- *
  ***********************************************************************************************************/
 
 #include "L1InitManager.h"
 
 #include <algorithm>
 
+//-----------------------------------------------------------------------------------------------------------------------
+//
+L1InitManager::L1InitManager(L1Parameters* pParameters) : fpParameters(pParameters) {}
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
@@ -20,25 +22,25 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
 {
   // Check if other fields were defined already
   // Active detector IDs
-  if (!fInitFlags[L1InitManager::keActiveDetectorIDs]) {
+  if (!fInitController.GetFlag(InitKey::keActiveDetectorIDs)) {
     LOG(error) << "L1InitManager::AddStation: station initialization called before the active detectors set had been "
                   "initialized";
-    assert((fInitFlags[L1InitManager::keActiveDetectorIDs]));
+    assert((fInitController.GetFlag(InitKey::keActiveDetectorIDs)));
   }
 
   // Number of stations check
-  if (!fInitFlags[L1InitManager::keStationsNumberCrosscheck]) {
+  if (!fInitController.GetFlag(InitKey::keStationsNumberCrosscheck)) {
     LOG(error)
       << "L1InitManager::AddStation: station initialization called before the numbers of stations for each detector "
       << "had been initialized";
-    assert((fInitFlags[L1InitManager::keStationsNumberCrosscheck]));
+    assert((fInitController.GetFlag(InitKey::keStationsNumberCrosscheck)));
   }
 
   // Field function
-  if (!fInitFlags[L1InitManager::keFieldFunction]) {
+  if (!fInitController.GetFlag(InitKey::keFieldFunction)) {
     LOG(error)
       << "L1InitManager::AddStation: station initialization called before the magnetic field function was intialized";
-    assert((fInitFlags[L1InitManager::keFieldFunction]));
+    assert((fInitController.GetFlag(InitKey::keFieldFunction)));
   }
 
   // Check activeness of this station type
@@ -47,10 +49,12 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
     // initialize magnetic field slice
     L1BaseStationInfo inStationCopy = L1BaseStationInfo(inStation);  // make a copy of station so it can be initialized
     inStationCopy.SetFieldSlice(fFieldFunction);
-    bool isStationInitialized = inStationCopy.IsInitialized();
+    bool isStationInitialized = inStationCopy.GetInitController().IsFinalized();
     if (!isStationInitialized) {
-      LOG(debug) << "L1InitManager::AddStation: station init flags (original)" << inStation.GetInitFlags();
-      LOG(debug) << "L1InitManager::AddStation: station init flags (copy)    " << inStation.GetInitFlags();
+      LOG(debug) << "L1InitManager::AddStation:(original) L1BaseStationInfo "
+                 << inStation.GetInitController().ToString();
+      LOG(debug) << "L1InitManager::AddStation:(copy)     L1BaseStationInfo "
+                 << inStation.GetInitController().ToString();
       LOG(error) << "L1InitManager::AddStation: attempt to add incompletely initialized object with detectorID = "
                  << static_cast<int>(inStationCopy.GetDetectorID())
                  << " and stationID = " << inStationCopy.GetStationID();
@@ -76,121 +80,129 @@ void L1InitManager::AddStation(const L1BaseStationInfo& inStation)
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::Init() const
-{  // To be implemented
-  // Plans:
-  //  1. Must make a final check of the inititalization and turn on a corresponding trigger in L1Algo class to accept
-  //     the incoming data
+void L1InitManager::CheckInit()
+{
+  this->CheckCAIterationsInit();
+  this->CheckStationsInfoInit();
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::PrintStations(int verbosityLevel) const
+int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const
 {
-  for (const auto& station : fStationsInfo) {
-    station.Print(verbosityLevel);
-  }
+  auto ifDetectorIdDesired = [&detectorID](const L1BaseStationInfo& station) {
+    return station.GetDetectorID() == detectorID;
+  };
+  return std::count_if(fStationsInfo.begin(), fStationsInfo.end(), ifDetectorIdDesired);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::PrintCAIterations(int verbosityLevel) const
+void L1InitManager::InitTargetField(double zStep)
 {
-  for (const auto& iteration : fCAIterationsContainer) {
-    iteration.Print(verbosityLevel);
+  if (fInitController.GetFlag(InitKey::kePrimaryVertexField)) {
+    LOG(warn) << "L1InitManager::InitTargetField: attempt to reinitialize the field value and field region "
+              << "near target. Ignore";
+    return;
   }
+
+  // Check for field function
+  if (!fInitController.GetFlag(InitKey::keFieldFunction)) {
+    LOG(error) << "L1InitManager::InitTargetField: attempt to initialze the field value and field region near "
+               << "target before initializing field function";
+    assert((fInitController.GetFlag(InitKey::keFieldFunction)));
+  }
+
+  // Check for target defined
+  if (!fInitController.GetFlag(InitKey::keTargetPos)) {
+    LOG(error) << "L1InitManager::InitTargetField: attempt to initialize the field value and field region near "
+               << "target before the target position initialization";
+    assert((fInitController.GetFlag(InitKey::keTargetPos)));
+  }
+
+  constexpr int nDimensions {3};
+  constexpr int nPointsNodal {3};
+
+  std::array<double, nPointsNodal> inputNodalZ {fTargetPos[2], fTargetPos[2] + zStep, fTargetPos[2] + 2. * zStep};
+  std::array<L1FieldValue, nPointsNodal> B {};
+  std::array<fvec, nPointsNodal> z {};
+  // loop over nodal points
+  for (int idx = 0; idx < nPointsNodal; ++idx) {
+    double point[nDimensions] {0., 0., inputNodalZ[idx]};
+    double field[nDimensions] {};
+    fFieldFunction(point, field);
+    z[idx]   = inputNodalZ[idx];
+    B[idx].x = field[0];
+    B[idx].y = field[1];
+    B[idx].z = field[2];
+  }  // loop over nodal points: end
+  fTargetFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]);
+  fTargetFieldValue = B[0];
+
+  fInitController.SetFlag(InitKey::kePrimaryVertexField);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::PushBackCAIteration(const L1CAIteration& iteration)
+void L1InitManager::PrintCAIterations(int verbosityLevel) const
 {
-  // TODO: probably some checks must be inserted here
-  if (!fInitFlags[L1InitManager::keCAIterationsNumberCrosscheck]) {
-    LOG(error) << "L1InitManager::PushBackCAIteration: attempt to push back a CA track finder iteration before the "
-               << "number of iterations was defined";
-    assert((fInitFlags[L1InitManager::keCAIterationsNumberCrosscheck]));
+  for (const auto& iteration : fpParameters->CAIterationsContainer()) {
+    iteration.Print(verbosityLevel);
   }
-  fCAIterationsContainer.push_back(iteration);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray)
+void L1InitManager::PrintStations(int verbosityLevel) const
 {
-  /// First of all, we must check if L1Station was properly initialized
-  // TODO: actually, false condition will never reached (must think about it, may be remove assertions from
-  // CheckStationInfo and leave only warnings and flag) (S.Zh.)
-  bool ifStationsInitialized = CheckStationsInfo();
-  if (!ifStationsInitialized) {
-    LOG(error) << "L1InitManager::TransferL1StationArray: attempt to pass unitialized L1Station array to L1Algo core";
-    assert((ifStationsInitialized));
-  }
-
-  /// Check if destinationArraySize is enough for the transfer
-  int totalStationsNumber       = this->GetStationsNumber();
-  bool ifDestinationArraySizeOk = totalStationsNumber <= static_cast<int>(destinationArray.size());
-  if (!ifDestinationArraySizeOk) {
-    LOG(error) << "L1InitManager::TransferL1StationArray: destination array size (" << destinationArray.size()
-               << ") is smaller then actual number of active tracking stations (" << totalStationsNumber << ")";
-    assert((ifDestinationArraySizeOk));
-  }
-
-  auto destinationArrayIterator = destinationArray.begin();
-  for (const auto& item : fStationsInfo) {
-    *destinationArrayIterator = std::move(item.GetL1Station());
-    ++destinationArrayIterator;
+  for (const auto& station : fStationsInfo) {
+    station.Print(verbosityLevel);
   }
-  LOG(info) << "L1InitManager: L1Station vector was successfully transfered to L1Algo core :)";
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::TransferCAIterationsContainer(L1Vector<L1CAIteration>& destinationVector)
+void L1InitManager::PushBackCAIteration(const L1CAIteration& iteration)
 {
-  bool ifCAIterationsInitialized = CheckCAIterations();
-  if (!ifCAIterationsInitialized) {
-    LOG(error) << "L1InitManager::TransferCAIterationsContainer: the CA track finder iterations container was not "
-               << "initialized properly";
-    assert((ifCAIterationsInitialized));
+  // TODO: probably some checks must be inserted here
+  if (!fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck)) {
+    LOG(error) << "L1InitManager::PushBackCAIteration: attempt to push back a CA track finder iteration before the "
+               << "number of iterations was defined";
+    assert((fInitController.GetFlag(InitKey::keCAIterationsNumberCrosscheck)));
   }
-  std::copy(fCAIterationsContainer.begin(), fCAIterationsContainer.end(), destinationVector.begin());
+  //fCAIterationsContainer.push_back(iteration);
+  L1Vector<L1CAIteration>& iterationsContainer = fpParameters->CAIterationsContainer();
+  iterationsContainer.push_back(iteration);
 }
 
-//
-// GETTERS
-//
-
 //-----------------------------------------------------------------------------------------------------------------------
 //
-int L1InitManager::GetStationsNumber(L1DetectorID detectorID) const
+void L1InitManager::SetActiveDetectorIDs(const std::set<L1DetectorID>& detectorIDs)
 {
-  auto ifDetectorIdDesired = [&detectorID](const L1BaseStationInfo& station) {
-    return station.GetDetectorID() == detectorID;
-  };
-  return std::count_if(fStationsInfo.begin(), fStationsInfo.end(), ifDetectorIdDesired);
+  // TODO: To think about redifinition possibilities: should it be allowed or not? (S.Zh.)
+  fActiveDetectorIDs = detectorIDs;
+  fInitController.SetFlag(InitKey::keActiveDetectorIDs);
 }
 
-//
-// SETTERS
-//
-
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::SetActiveDetectorIDs(const std::set<L1DetectorID>& detectorIDs)
+void L1InitManager::SetCAIterationsNumberCrosscheck(int nIterations)
 {
-  // TODO: To think about redifinition possibilities: should it be allowed or not? (S.Zh.)
-  fActiveDetectorIDs                             = detectorIDs;
-  fInitFlags[L1InitManager::keActiveDetectorIDs] = true;
+  fCAIterationsNumberCrosscheck                = nIterations;
+  L1Vector<L1CAIteration>& iterationsContainer = fpParameters->CAIterationsContainer();
+
+  // NOTE: should be called to prevent multiple copyings of objects between the memory realocations
+  iterationsContainer.reserve(nIterations);
+  fInitController.SetFlag(InitKey::keCAIterationsNumberCrosscheck);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::SetFieldFunction(const std::function<void(const double (&xyz)[3], double (&B)[3])>& fieldFunction)
+void L1InitManager::SetFieldFunction(const L1FieldFunction_t& fieldFunction)
 {
-  if (!fInitFlags[L1InitManager::keFieldFunction]) {
-    fFieldFunction                             = fieldFunction;
-    fInitFlags[L1InitManager::keFieldFunction] = true;
+  if (!fInitController.GetFlag(InitKey::keFieldFunction)) {
+    fFieldFunction = fieldFunction;
+    fInitController.SetFlag(InitKey::keFieldFunction);
   }
   else {
     LOG(warn) << "L1InitManager::SetFieldFunction: attempt to reinitialize the field function. Ignored";
@@ -210,154 +222,129 @@ void L1InitManager::SetStationsNumberCrosscheck(L1DetectorID detectorID, int nSt
 
   // Check if all the station numbers for active detectors are initialized now:
   LOG(debug) << "SetStationsNumberCrosscheck called for detectorID = " << static_cast<int>(detectorID);
-  if (!fInitFlags[L1InitManager::keStationsNumberCrosscheck]) {
+  if (!fInitController.GetFlag(InitKey::keStationsNumberCrosscheck)) {
     bool ifInitialized = true;
     for (auto item : fActiveDetectorIDs) {
       if (fStationsNumberCrosscheck.find(item) == fStationsNumberCrosscheck.end()) {
-        LOG(warn) << "L1InitManager::SetStationsNumberCrosscheck: uninitialized number of stations for detectorID = "
-                  << static_cast<int>(item);
         ifInitialized = false;
         break;
       }
     }
-    fInitFlags[L1InitManager::keStationsNumberCrosscheck] = ifInitialized;
+    fInitController.SetFlag(InitKey::keStationsNumberCrosscheck, ifInitialized);
   }
-  LOG(debug) << "InitResult: " << fInitFlags[L1InitManager::keStationsNumberCrosscheck];
-}
-
-//-----------------------------------------------------------------------------------------------------------------------
-//
-void L1InitManager::SetCAIterationsNumberCrosscheck(int nIterations)
-{
-  fCAIterationsNumberCrosscheck                             = nIterations;
-  fInitFlags[L1InitManager::keCAIterationsNumberCrosscheck] = true;
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
 void L1InitManager::SetTargetPosition(double x, double y, double z)
 {
-  if (fInitFlags[L1InitManager::keTargetPos]) {
+  if (fInitController.GetFlag(InitKey::keTargetPos)) {
     LOG(warn) << "L1InitManager::SetTargetPosition: attempt to reinitialize the target position. Ignore";
     return;
   }
 
-  fTargetPos[0]                          = x;
-  fTargetPos[1]                          = y;
-  fTargetPos[2]                          = z;
-  fInitFlags[L1InitManager::keTargetPos] = true;
+  fTargetPos[0] = x;
+  fTargetPos[1] = y;
+  fTargetPos[2] = z;
+  fInitController.SetFlag(InitKey::keTargetPos);
 }
 
 //-----------------------------------------------------------------------------------------------------------------------
 //
-void L1InitManager::InitTargetField(double zStep)
+void L1InitManager::TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray)
 {
-  if (fInitFlags[L1InitManager::kePrimaryVertexField]) {
-    LOG(warn) << "L1InitManager::InitTargetField: attempt to reinitialize the field value and field region "
-              << "near target. Ignore";
-    return;
+  //
+  // 1) Check, if all fields of this were initialized
+  //
+  if (!fInitController.IsFinalized()) {
+    LOG(error) << "L1InitManager::TransferL1StationArray: attempt to pass L1Station array to L1Algo core before "
+               << "all necessary fields initialization";
+    LOG(error) << "L1InitManager " << fInitController.ToString();
+    assert((fInitController.IsFinalized()));
   }
 
-  // Check for field function
-  if (!fInitFlags[L1InitManager::keFieldFunction]) {
-    LOG(error) << "L1InitManager::InitTargetField: attempt to initialze the field value and field region near "
-               << "target before initializing field function";
-    assert((fInitFlags[L1InitManager::keFieldFunction]));
+  //
+  // 2) Check, if destinationArraySize is enough for the transfer
+  //
+  int nStationsTotal            = this->GetStationsNumber();
+  bool ifDestinationArraySizeOk = nStationsTotal <= static_cast<int>(destinationArray.size());
+  if (!ifDestinationArraySizeOk) {
+    LOG(error) << "L1InitManager::TransferL1StationArray: destination array size (" << destinationArray.size()
+               << ") is smaller then actual number of active tracking stations (" << nStationsTotal << ")";
+    assert((ifDestinationArraySizeOk));
   }
 
-  // Check for target defined
-  if (!fInitFlags[L1InitManager::keTargetPos]) {
-    LOG(error) << "L1InitManager::InitTargetField: attempt to initialize the field value and field region near "
-               << "target before the target position initialization";
-    assert((fInitFlags[L1InitManager::keTargetPos]));
+  auto destinationArrayIterator = destinationArray.begin();
+  for (const auto& item : fStationsInfo) {
+    *destinationArrayIterator = std::move(item.GetL1Station());
+    ++destinationArrayIterator;
   }
+  LOG(info) << "L1InitManager: L1Station vector was successfully transfered to L1Algo core :)";
+}
 
-  constexpr int numberOfDimensions {3};
-  constexpr int numberOfReferencePoints {3};
+//
+// INIT CHECKERS
+//
 
-  std::array<double, numberOfReferencePoints> inputNodalZ {fTargetPos[2], fTargetPos[2] + zStep,
-                                                           fTargetPos[2] + 2. * zStep};
-  std::array<L1FieldValue, numberOfReferencePoints> B = {};
-  std::array<fvec, numberOfReferencePoints> z         = {};
-  for (int idx = 0; idx < numberOfReferencePoints; ++idx) {
-    double point[numberOfDimensions] = {0., 0., inputNodalZ[idx]};
-    double field[numberOfDimensions] = {};
-    fFieldFunction(point, field);
-    z[idx]   = inputNodalZ[idx];
-    B[idx].x = field[0];
-    B[idx].y = field[1];
-    B[idx].z = field[2];
+//-----------------------------------------------------------------------------------------------------------------------
+//
+void L1InitManager::CheckCAIterationsInit()
+{
+  //
+  // 1) Check number of iterations
+  //
+  bool ifInitPassed = true;
+  if (!fInitController.GetFlag(InitKey::keCAIterations)) {
+    int nIterationsActual   = fpParameters->CAIterationsContainer().size();
+    int nIterationsExpected = fCAIterationsNumberCrosscheck;
+    if (nIterationsActual != nIterationsExpected) {
+      LOG(warn) << "L1InitManager::CheckCAIterations: incorrect number of iterations registered: " << nIterationsActual
+                << " of " << nIterationsExpected << " expected";
+      ifInitPassed = false;
+    }
   }
-  fTargetFieldRegion.Set(B[0], z[0], B[1], z[1], B[2], z[2]);
-  fTargetFieldValue = B[0];
-
-  fInitFlags[L1InitManager::kePrimaryVertexField] = true;
+  fInitController.SetFlag(InitKey::keCAIterations, ifInitPassed);
 }
 
-
 //-----------------------------------------------------------------------------------------------------------------------
-//
-bool L1InitManager::CheckStationsInfo()
+// TODO: REWRITE! and add const qualifier (S.Zharko)
+void L1InitManager::CheckStationsInfoInit()
 {
-  if (!fInitFlags[L1InitManager::keStationsInfo]) {
-    bool ifInitPassed = true;
-
-    if (!fInitFlags[L1InitManager::keIfStationNumbersChecked]) {
-      for (const auto& itemDetector : fActiveDetectorIDs) {
-        int actualStationsNumber   = GetStationsNumber(itemDetector);
-        int expectedStationsNumber = fStationsNumberCrosscheck.at(itemDetector);
-        if (actualStationsNumber != expectedStationsNumber) {
-          LOG(error) << "L1InitManager::CheckStationsInfo: Incorrect number of L1BaseStationInfo objects passed to the "
-                        "L1Manager "
-                     << "for L1DetectorID = " << static_cast<int>(itemDetector) << ": " << actualStationsNumber
-                     << " of " << expectedStationsNumber << " expected";
-          ifInitPassed = false;
-        }
+  bool ifInitPassed = true;
+  if (!fInitController.GetFlag(InitKey::keStationsInfo)) {
+    //
+    // 1) Check numbers of stations passed
+    //
+    // loop over active detectors
+    for (const auto& itemDetector : fActiveDetectorIDs) {
+      int nStationsActual   = GetStationsNumber(itemDetector);
+      int nStationsExpected = fStationsNumberCrosscheck.at(itemDetector);
+      if (nStationsActual != nStationsExpected) {
+        LOG(error) << "L1InitManager::IsStationsInfoInitialized: Incorrect number of L1BaseStationInfo objects passed"
+                   << " to the L1Manager for L1DetectorID = " << static_cast<int>(itemDetector) << ": "
+                   << nStationsActual << " of " << nStationsExpected << " expected";
+        ifInitPassed = false;
       }
-      fInitFlags[L1InitManager::keIfStationNumbersChecked] = ifInitPassed;
-    }
+    }  // loop over active detectors: end
+
     if (!ifInitPassed) {
-      LOG(error) << "L1InitManager::CheckStationsInfo: initialization failed";
+      LOG(error) << "L1InitManager::IsStationsInfo: initialization failed";
       assert((ifInitPassed));
     }
 
-    // Check for maximum allowed number of stations
-    int totalStationsNumber = GetStationsNumber();
-    if (totalStationsNumber > L1Parameters::kMaxNstations) {
-      LOG(fatal) << "Actual total number of registered stations (" << totalStationsNumber
+    //
+    // 2) Check for maximum allowed number of stations
+    //
+    int nStationsTotal = GetStationsNumber();
+    if (nStationsTotal > L1Parameters::kMaxNstations) {
+      LOG(fatal) << "Actual total number of registered stations (" << nStationsTotal
                  << ") is larger then designed one (" << L1Parameters::kMaxNstations
                  << "). Please, select another set of active tracking detectors";
-      // TODO: We have to provide an instruction of how to increase the kMaxNstations number keeping the code consistent (S.Zh.)
-      assert((totalStationsNumber <= L1Parameters::kMaxNstations));
+      // TODO: We have to provide an instruction of how to increase the kMaxNstations
+      //       number keeping the code consistent (S.Zharko)
+      ifInitPassed = false;
+      assert((nStationsTotal <= L1Parameters::kMaxNstations));
     }
-
-    fInitFlags[L1InitManager::keStationsInfo] = true;
-  }
-  else {
-    LOG(warn) << "L1InitManager: L1BaseStationInfo set has already been initialized";
   }
-  // NOTE: we return a flag here to reduce a number of calls outside the funcition. In other hands we keep this flag
-  // to be consistent with other class fields initialization rules
-  return fInitFlags[L1InitManager::keStationsInfo];
-}
-
-//-----------------------------------------------------------------------------------------------------------------------
-//
-bool L1InitManager::CheckCAIterations()
-{
-  // Check number of iterations
-  if (!fInitFlags[L1InitManager::keCAIterations]) {
-    int actualIterationsNumber   = fCAIterationsContainer.size();
-    int expectedIterationsNumber = fCAIterationsNumberCrosscheck;
-    if (actualIterationsNumber != expectedIterationsNumber) {
-      LOG(warn) << "L1InitManager::CheckCAIterations: incorrect number of iterations registered: "
-                << actualIterationsNumber << " of " << expectedIterationsNumber << " expected";
-      fInitFlags[L1InitManager::keCAIterations] = false;
-    }
-    else {
-      fInitFlags[L1InitManager::keCAIterations] = true;
-    }
-  }
-
-  return fInitFlags[L1InitManager::keCAIterations];
+  fInitController.SetFlag(InitKey::keStationsInfo, ifInitPassed);
 }
diff --git a/reco/L1/L1Algo/L1InitManager.h b/reco/L1/L1Algo/L1InitManager.h
index 29986cbba36eaddd0d86f7e7d06f81f042b41297..f6540bc7aaeec9ef364519d20fe79e408ca1a6f1 100644
--- a/reco/L1/L1Algo/L1InitManager.h
+++ b/reco/L1/L1Algo/L1InitManager.h
@@ -6,7 +6,6 @@
  * @file L1InitManager.h
  * @bried Input data management class for L1Algo
  * @since 24.12.2021
- *
  ***********************************************************************************************************/
 #ifndef L1InitManager_h
 #define L1InitManager_h 1
@@ -14,6 +13,7 @@
 #include "L1BaseStationInfo.h"
 #include "L1CAIteration.h"
 #include "L1Field.h"
+#include "L1ObjectInitController.h"
 #include "L1Parameters.h"
 #include "L1Utils.h"
 
@@ -55,32 +55,38 @@ enum class L1DetectorID;
 ///    initMan->SetStationsNumberCrosscheck(L1DetectorID::kMvd, NMvdStations)
 ///    initMan->SetStationsNumberCrosscheck(L1DetectorID::kMvd, NStsStations);
 ///
-/// 3. Initialize each station using L1BaseStationInfo:
+/// 4. Initialize each station using L1BaseStationInfo:
 ///
 class L1InitManager {
 private:
-  enum
+  enum class InitKey
   {
-    keActiveDetectorIDs,             ///< If the detector sequence is set
-    keStationsNumberCrosscheck,      ///< If the crosscheck station numbers were setup
-    keFieldFunction,                 ///< If magnetic field getter funciton is set
-    keTargetPos,                     ///< If target position was defined
-    kePrimaryVertexField,            ///< If magnetic field value and region defined at primary vertex
-    keIfStationNumbersChecked,       ///< If the station number was already checked
-    keStationsInfo,                  ///< If all the planned stations were added to the manager
-    keL1StationTransfered,           ///< If the L1Station vector was already transfered to destination array
-    keCAIterationsNumberCrosscheck,  ///< If the CA trackfinder iterations were initialized
-    keCAIterations,                  ///< If the CA trackfinder iterations were initialized
-    keEnd
+    // 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
+    keEnd                            ///< 8 - 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>;
+
 public:
   //
   // CONSTRUCTORS AND DESTRUCTOR
   //
-
   /// Default constructor
-  L1InitManager() = default;
+  L1InitManager() = delete;
+  /// Constructor from ptr to L1Paramters object
+  L1InitManager(L1Parameters* pParameters);
   /// Destructor
   ~L1InitManager() = default;
   /// Copy constructor is forbidden
@@ -92,103 +98,101 @@ public:
   /// Move assignment operator is forbidden
   L1InitManager& operator=(L1InitManager&& /*other*/) = delete;
 
-
   //
   // BASIC METHODS
   //
-
-
   /// Adds another station of a given type using reference to a L1BaseStationInfo object
-  void AddStation(const L1BaseStationInfo& inStation);
+  void AddStation(const L1BaseStationInfo& station);
   /// Adds another station of a given type using pointer to a L1BaseStationInfo object
-  void AddStation(const L1BaseStationInfo* inStationRawPtr) { AddStation(*inStationRawPtr); }
+  void AddStation(const L1BaseStationInfo* pStation) { AddStation(*pStation); }
   /// Adds another station of a given type using std::unique_ptr-wraped pointer to L1BaseStationInfo
-  void AddStation(const std::unique_ptr<L1BaseStationInfo>& inStationUPtr) { AddStation(*inStationUPtr); }
-
-  /// Initializes L1Algo: transfers all caputred data to the L1 tracking core
-  void Init() const;
-  /// Prints a list of stations
-  void PrintStations(int verbosityLevel = 0) const;
-  /// Prints a list of CA track finder iterations
-  void PrintCAIterations(int verbosityLevel = 0) const;
-
-  /// Pushes an CA track finder iteration into a sequence of iteration using reference
-  void PushBackCAIteration(const L1CAIteration& iteration);
-  /// Pushes an CA track finder iteration into a sequence of iteration using raw pointer
-  void PushBackCAIteration(const L1CAIteration* iterationRawPtr) { PushBackCAIteration(*iterationRawPtr); }
-  /// Pushes an CA track finder iteration into a sequence of iteration using std::unique_ptr
-  void PushBackCAIteration(const std::unique_ptr<L1CAIteration>& iterationUPtr) { PushBackCAIteration(*iterationUPtr); }
-
-  /// Transfers an array of L1Stations formed inside a set of L1BaseStationInfo to a destination std::array
-  void TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray);
-  /// Transfers a vector of the CA track finder iterations
-  void TransferCAIterationsContainer(L1Vector<L1CAIteration>& destinationVector);
+  void AddStation(const std::unique_ptr<L1BaseStationInfo>& puStation) { AddStation(*puStation); }
+  /// Provides final checks of large fields initialization calling Check"Object"Init() privat methods,
+  /// must be called in the begining of L1Algo::Init()
+  void CheckInit();
+  // NOTE: This method calls checkers of large fields initializations like a station or an iteration. The method must be
+  //       called in the L1Algo class. (S.Zharko)
 
   //
   // GETTERS
   //
-
   /// Gets a set of actie detectors for this analysis
-  std::set<L1DetectorID> GetActiveDetectorIDs() const { return fActiveDetectorIDs; }
+  const L1DetectorIDSet_t& GetActiveDetectorIDs() const { return fActiveDetectorIDs; }
+  /// Gets a const reference to L1ObjectInitController
+  const L1ObjectInitController_t& GetInitController() const { return fInitController; }
+  /// 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()); }
   /// Gets a number of stations for a particualr detector ID
   int GetStationsNumber(L1DetectorID detectorID) const;
-  /// Gets a target position
-  const std::array<double, 3>& GetTargetPosition() const { return fTargetPos; }
   // TODO: define enum of dimensions.... (S.Zh.)
   /// Gets a L1FieldRegion object at primary vertex
   const L1FieldRegion& GetTargetFieldRegion() const { return fTargetFieldRegion; }
   /// Gets a L1FieldValue object at primary vertex
   const L1FieldValue& GetTargetFieldValue() const { return fTargetFieldValue; }
+  /// Gets a target position
+  const std::array<double, 3>& GetTargetPosition() const { return fTargetPos; }
+
+  /// Calculates L1FieldValue and L1FieldReference values for a selected step in z coordinate from the target position
+  /// \param zStep step between nodal points
+  // TODO: Consider posibility for linear approximation (S.Zh.)
+  void InitTargetField(double zStep);
+
+  /// Prints a list of CA track finder iterations
+  void PrintCAIterations(int verbosityLevel = 0) const;
+  /// Prints a list of stations
+  void PrintStations(int verbosityLevel = 0) const;
+
+  /// Pushes an CA track finder iteration into a sequence of iteration using reference
+  void PushBackCAIteration(const L1CAIteration& iteration);
+  /// Pushes an CA track finder iteration into a sequence of iteration using raw pointer
+  void PushBackCAIteration(const L1CAIteration* pIteration) { PushBackCAIteration(*pIteration); }
+  /// Pushes an CA track finder iteration into a sequence of iteration using std::unique_ptr
+  void PushBackCAIteration(const std::unique_ptr<L1CAIteration>& puIteration) { PushBackCAIteration(*puIteration); }
 
   //
   // SETTERS
   //
-
   /// Sets a set of active tracking detector IDs
-  void SetActiveDetectorIDs(const std::set<L1DetectorID>& detectorIDs);
+  void SetActiveDetectorIDs(const L1DetectorIDSet_t& detectorIDs);
+  /// Sets a number of CA track finder iterations to provide initialization cross-check
+  void SetCAIterationsNumberCrosscheck(int nIterations);
   /// Sets a magnetic field function, which will be applied for all the stations
-  void SetFieldFunction(const std::function<void(const double (&xyz)[3], double (&B)[3])>& fieldFcn);
+  void SetFieldFunction(const L1FieldFunction_t& fieldFcn);
   /// 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 CA track finder iterations to provide initialization cross-check
-  void SetCAIterationsNumberCrosscheck(int nIterations);
   /// Sets target poisition
   void SetTargetPosition(double x, double y, double z);
 
-  /// Calculates L1FieldValue and L1FieldReference values for a selected step in z coordinate from the target position
-  /// \param zStep step between nodal points
-  // TODO: Consider posibility for linear approximation (S.Zh.)
-  void InitTargetField(double zStep);
+  /// Transfers an array of L1Stations formed inside a set of L1BaseStationInfo to a destination std::array
+  void TransferL1StationArray(std::array<L1Station, L1Parameters::kMaxNstations>& destinationArray);
 
 
 private:
-  /// Checker for L1BaseStationInfo set initialization
-  /// \return true If all L1BaseStationInfo objects were initialized properly. Similar effect can be achieved by
-  /// calling the fInitFlags[L1InitManager::keStationsInfo] flag
-  bool CheckStationsInfo();
-  /// Checker for L1CAIteration container initialization
+  /// Checker for L1CAIteration container initialization (sets InitKey::keCAIterations)
   /// \return true If all L1CAIteration objects were initialized properly
-  bool CheckCAIterations();
+  void CheckCAIterationsInit();
+  /// Checker for L1BaseStationInfo set initialization (sets InitKey::keStationsInfo)
+  /// \return true If all L1BaseStationInfo objects were initialized properly. Similar effect can be achieved by
+  void CheckStationsInfoInit();
 
   /* Basic fields */
 
-  std::bitset<L1InitManager::keEnd> fInitFlags {};  ///< Initialization flags
-  std::set<L1DetectorID> fActiveDetectorIDs {};     ///< Set of tracking detectors, active during this analysis session
+  L1ObjectInitController_t fInitController {};  ///< Initialization flags
+  L1DetectorIDSet_t fActiveDetectorIDs {};      ///< Set of tracking detectors, active during this analysis session
 
   /* Target fields */
 
-  std::array<double, 3> fTargetPos {};  ///< Nominal target position coordinates
+  std::array<double, /*nDimensions=*/3> fTargetPos {};  ///< Nominal target position coordinates
 
   /* Stations related fields */
 
   std::set<L1BaseStationInfo> fStationsInfo {};  ///< Set of L1BaseStationInfo objects
   /// Map of station numbers used for initialization crosscheck
-  std::unordered_map<L1DetectorID, int, L1Utils::EnumClassHash> fStationsNumberCrosscheck {};
+  L1DetectorIDIntMap_t fStationsNumberCrosscheck {};
   /// A function which returns magnetic field vector B in a radius-vector xyz
-  std::function<void(const double (&xyz)[3], double (&B)[3])> fFieldFunction {
-    [](const double (&)[3], double (&)[3]) {}};
+  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!!!!!!!
   // NOTE: fTotalNumberOfStations is excess field for logic, but it's imortant to track L1Algo initialization
 
@@ -199,11 +203,12 @@ private:
 
   /* CA track finder iterations related */
 
-  L1Vector<L1CAIteration> fCAIterationsContainer {};  ///> Container for CA track finder iterations
+  //L1Vector<L1CAIteration> fCAIterationsContainer {};  ///> Container for CA track finder iterations
   int fCAIterationsNumberCrosscheck {-1};  ///> Number of iterations to be passed (must be used for cross-checks)
 
-  /// Pointer to L1Parameters object, which will be copied to L1Algo after checks
-  L1Parameters* fParametersPtr {nullptr};
+  /// Pointer to L1Parameters object
+  // NOTE: Owner of the object is L1Algo instance
+  L1Parameters* fpParameters {nullptr};
 };
 
 #endif
diff --git a/reco/L1/L1Algo/L1ObjectInitController.h b/reco/L1/L1Algo/L1ObjectInitController.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a384508902f2f7f2a1a3d7d476b98407e32f60b
--- /dev/null
+++ b/reco/L1/L1Algo/L1ObjectInitController.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergey Gorbunov, Sergei Zharko [committer] */
+
+#ifndef L1ObjectInitController_h
+#define L1ObjectInitController_h 1
+
+/// @file   L1ObjectInitController.h
+/// @author Sergei Zharko
+/// @date   22.02.2022
+
+#include "FairLogger.h"
+
+#include <bitset>
+#include <cassert>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+/// L1ObjectInitController is a class, which provides flags system
+/// and functionality needed for L1 algorithm objects initialization
+///
+// TODO: Possible improvement: introduce another template parameter, which represents a local enum class...
+template<int NumberOfFlags, class InitKeyEnum>
+class L1ObjectInitController {
+public:
+  /// Gets an initialization status of the flag placed at bitIndex
+  /// \param bitIndex    index of bit
+  bool GetFlag(InitKeyEnum bitKey) const
+  {
+#ifndef FAST_CODE
+    int bitIndex = static_cast<int>(bitKey);
+    if (bitIndex >= NumberOfFlags || bitIndex < 0) {
+      LOG(fatal) << "L1OnjectInitController::GetFlagStatus: attempt of flag access with index = " << bitIndex
+                 << " outside the range [0, " << NumberOfFlags << ']';
+      assert((!(bitIndex >= NumberOfFlags || bitIndex < 0)));
+    }
+#endif  // FAST_CODE
+    return fInitFlags[static_cast<int>(bitKey)];
+  }
+
+  /// Checks, if the object is finalized, i.e. all its fields were setup
+  bool IsFinalized() const { return fInitFlags.size() == fInitFlags.count(); }
+
+  /// Sets an initialization status of the flag placed at bitIndex
+  /// \param bitIndex    index of bit
+  /// \param newStatus   flag value (true is default)
+  void SetFlag(InitKeyEnum bitKey, bool newStatus = true)
+  {
+#ifndef FAST_CODE
+    int bitIndex = static_cast<int>(bitKey);
+    if (bitIndex >= NumberOfFlags || bitIndex < 0) {
+      LOG(fatal) << "L1OnjectInitController::GetFlagStatus: attempt of flag access with index = " << bitIndex
+                 << " outside the range [0, " << NumberOfFlags << ']';
+      assert((!(bitIndex >= NumberOfFlags || bitIndex < 0)));
+    }
+#endif  // FAST_CODE
+    fInitFlags[static_cast<int>(bitKey)] = newStatus;
+  }
+
+  /// String representation of initialization flags contents
+  /// \param indentLevel   number of indent charachets int output
+  std::string ToString(int indentLevel = 0) const
+  {
+    std::stringstream aStream {};
+    constexpr char indentChar = '\t';
+    std::string indent(indentLevel, indentChar);
+    aStream << indent << "L1ObjectInitController: flag values";
+    aStream << '\n' << indent << "index: ";
+    for (int idx = 0; idx < NumberOfFlags; ++idx) {
+      aStream << std::setw(3) << std::setfill(' ') << idx << ' ';
+    }
+    aStream << '\n' << indent << "value: ";
+    for (int idx = 0; idx < NumberOfFlags; ++idx) {
+      aStream << "  " << static_cast<int>(fInitFlags[idx]) << ' ';
+    }
+    return aStream.str();
+  }
+
+private:
+  std::bitset<NumberOfFlags> fInitFlags {};  ///< object of flags sets
+};
+
+#endif  // L1ObjectInitController_h
diff --git a/reco/L1/L1Algo/L1Parameters.cxx b/reco/L1/L1Algo/L1Parameters.cxx
index 03c56812868d171705a334e960fe11214ac6567c..2927946e6779e79c1f74ecffc716846c21991e21 100644
--- a/reco/L1/L1Algo/L1Parameters.cxx
+++ b/reco/L1/L1Algo/L1Parameters.cxx
@@ -11,7 +11,7 @@
 
 #include <FairLogger.h>
 
-void L1Parameters::Print() const
+void L1Parameters::Print(int verbosityLevel) const
 {
   LOG(info) << "== L1Algo parameters ==============================================================";
   LOG(info) << "";
@@ -27,6 +27,9 @@ void L1Parameters::Print() const
   LOG(info) << "    Max number of doublets per singlet: " << fMaxDoubletsPerSinglet;
   LOG(info) << "    Max number of triplets per doublet: " << fMaxTripletPerDoublets;
   LOG(info) << "";
-  LOG(info) << "  TRACK FINDER ITERATION DEPENDENT CONSTANTS";
+  LOG(info) << "  TRACK FINDER ITERATIONS";
+  for (const auto& iteration : fCAIterationsContainer) {
+    iteration.Print(verbosityLevel);
+  }
   LOG(info) << "===================================================================================";
 }
diff --git a/reco/L1/L1Algo/L1Parameters.h b/reco/L1/L1Algo/L1Parameters.h
index 74396339d3551c7bb977609462a8ccc91d7b5532..16613ea84d8ab694e1b2bfc39b4464073682f42a 100644
--- a/reco/L1/L1Algo/L1Parameters.h
+++ b/reco/L1/L1Algo/L1Parameters.h
@@ -60,7 +60,7 @@ public:
   //
 
   /// Prints configuration
-  void Print() const;
+  void Print(int verbosityLevel = 0) const;
 
   // TODO: change constant names with actual (human) names