diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h
index 7b4f244a78554358684b28aeed5e9c1a560545b9..9b4685bb30be32ae297ab86886336a72eac754d5 100644
--- a/reco/L1/L1Algo/L1Algo.h
+++ b/reco/L1/L1Algo/L1Algo.h
@@ -36,6 +36,7 @@ class L1AlgoDraw;
 //#endif
 //#define MERGE_CLONES
 
+#define FEATURING_L1ALGO_INIT
 
 #include <iomanip>
 #include <iostream>
@@ -48,6 +49,8 @@ class L1AlgoDraw;
 #include "L1Hit.h"
 #include "L1HitPoint.h"
 #include "L1HitsSortHelper.h"
+#include "L1InitManager.h"
+#include "L1Parameters.h"
 #include "L1Portion.h"
 #include "L1Station.h"
 #include "L1Track.h"
@@ -135,7 +138,6 @@ public:
 
 
   L1Vector<L1Triplet> fTriplets[L1Parameters::kMaxNstations][L1Parameters::kMaxNthreads] {
-    //<--------
     {"L1Algo::fTriplets"}};  // created triplets at station + thread
 
   // Track candidates created out of adjacent triplets before the final track selection.
@@ -359,10 +361,12 @@ public:
   // TODO: We should think about, where non-constexpr L1Alog 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.
+  L1InitManager * GetL1InitManager() { return &fL1InitManager; }
 
 private:
   /// Object containing L1Parameters. Default consturctor is used
-  L1Parameters fL1Parameters;
+  L1Parameters fL1Parameters;    ///< Object of L1Algo parameters class
+  L1InitManager fL1InitManager;  ///< Object of L1Algo initialization manager class
 
   /// =================================  FUNCTIONAL PART  =================================
 
diff --git a/reco/L1/L1Algo/L1BaseStationInfo.h b/reco/L1/L1Algo/L1BaseStationInfo.h
index ae09356723001e8e95bb65354892edc40f6784f9..f298ea92178bc7df0971190f2e8ef5afd1b0a4bf 100644
--- a/reco/L1/L1Algo/L1BaseStationInfo.h
+++ b/reco/L1/L1Algo/L1BaseStationInfo.h
@@ -21,10 +21,18 @@
 #include "L1Parameters.h"
 #include "L1Station.h"
 
+// FairRoot
+#include "FairField.h"
+
+// Root
+#include "TMatrixD.h"
+#include "TVectorD.h"
+
 // C++ std
 #include <bitset>
 #include <iomanip>
 #include <string>
+#include <functional>
 //#include <cmath>
 
 /// A base class which provides interface to L1Algo station geometry
@@ -34,6 +42,9 @@ private:
   enum
   {  // Here we list all the fields, which must be initialized by user
     // Basic fields initialization
+    kEStationID,
+    kEXmax,
+    kEYmax,
     // L1Station initialization
     kEtype,
     kEtimeInfo,
@@ -84,11 +95,31 @@ public:
   //
   //  Setters
   //
+  /// Sets station ID
+  void SetStationID(int inID)
+  {
+    if (! fInitFlags[kEStationID]) {
+      fStationID = inID;
+      fInitFlags[kEStationID] = true;
+    }
+#ifndef FAST_CODE
+    else {
+      LOG(WARNING) << __FILE__ << ":" << __LINE__ << " Attempt of station ID redifinition\n";
+    }
+#endif // ! FAST_CODE
+  }
   /// Sets type of station
   void SetStationType(int inType)
   {
-    fL1Station.type    = inType;
-    fInitFlags[kEtype] = true;
+    if (! fInitFlags[kEtype]) {
+      fL1Station.type    = inType;
+      fInitFlags[kEtype] = true;
+    }
+#ifndef FAST_CODE
+    else {
+      LOG(WARNING) << __FILE__ << ":" << __LINE__ << " Attempt of station type redifinition\n";
+    }
+#endif // ! FAST_CODE
   }
   // TODO: Temporary method, a type must be selected automatically in the derived classes
   void SetTimeInfo(int inTimeInfo)
@@ -101,7 +132,8 @@ public:
   /// Sets nominal z position of the station
   void SetZ(double inZ)
   {
-    fL1Station.z    = inZ;
+    fL1Station.z = inZ; // setting simd vector of single-precision floats, which is passed to high performanced L1Algo
+    fZPos = inZ; // setting precise value to use in field approximation etc
     fInitFlags[kEz] = true;
   }
   /// Sets min transverse size of the station
@@ -138,8 +170,90 @@ public:
       fL1Station.fieldSlice.cx[idx] = Cx[idx];
       fL1Station.fieldSlice.cy[idx] = Cy[idx];
       fL1Station.fieldSlice.cz[idx] = Cz[idx];
-      fInitFlags[kEfieldSlice]      = true;
     }
+    fInitFlags[kEfieldSlice]      = true;
+  }
+  /// Sets arrays of the approcimation 
+  /// \param getField A user function, which gets a xyz array of position coordinates and fills B array
+  ///                 of magnetic field components in position
+  void SetFieldSlice(const std::function<void(const double (&xyz)[3], double (&B)[3])>& getFieldValue)
+  {
+    std::cout << ">>>>>>> CALL: SetFieldSlice\n";
+#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");
+#endif
+    constexpr int M = L1Parameters::kMaxFieldApproxPolynomialOrder;
+    constexpr int N = L1Parameters::kMaxNFieldApproxCoefficients;
+    constexpr int D = 3; ///> number of dimensions
+
+    // SLE initialization
+    double A[N][N + D] = {}; // augmented matrix
+    double dx = (fXmax / N / 2 < 1.) ? fXmax / N / 4. : 1.;
+    double dy = (fYmax / N / 2 < 1.) ? fYmax / N / 4. : 1.;
+    
+    for (double x = -fXmax; x <= fXmax; x += dx) {
+      for (double y = -fYmax; y <= fYmax; y += dy) {
+        double r = sqrt(fabs(x * x / fXmax / fXmax + y / fYmax * y / fYmax));
+        if (r > 1.) {
+          continue;
+        }
+        double p[D] = {x, y, fZPos};
+        double B[D] = {};
+        getFieldValue(p, B);
+
+        double m[N] = {1};
+        m[0] = 1;
+        for (int i = 1; i <= M; ++i) {
+          int k = (i - 1) * (i) / 2;
+          int l = i * (i + 1) / 2;
+          for (int j = 0; j < i; ++j) {
+            m[l + j] = x * m[k + j];
+          }
+          m[l + i] = y * m[k + i - 1];
+        }
+
+        double w = 1. / (r * r + 1);
+        for (int i = 0; i < N; ++i) {
+          // fill the left part of the matrix 
+          for (int j = 0; j < N; ++j) {
+            A[i][j] += w * m[i] * m[j];
+          }
+          // fill the right part of the matrix
+          for (int j = 0; j < D; ++j) {
+            A[i][N + j] += w * B[j] * m[i];
+          }
+        }
+      }
+    }
+
+    // SLE solution (Gaussian elimination)
+    //   
+    for (int kCol = 0; kCol < N - 1; ++kCol) {
+      for (int jRow = kCol + 1; jRow < N; ++jRow) {
+        double factor = A[jRow][kCol] / A[kCol][kCol];
+        for (int iCol = kCol; iCol < N + D; ++iCol) {
+          A[jRow][iCol] -= factor * A[kCol][iCol];
+        }
+      }
+    }
+    for (int kCol = N - 1; kCol > 0; --kCol) {
+      for (int jRow = kCol - 1; jRow >= 0; --jRow) {
+        double factor = A[jRow][kCol] / A[kCol][kCol];
+        for (int iCol = kCol; iCol < N + D; ++iCol) {
+          A[jRow][iCol] -= factor * A[kCol][iCol];
+        }
+      }
+    }
+
+    for (int j = 0; j < N; ++j) {
+      fL1Station.fieldSlice.cx[j] = A[j][N + 0] / A[j][j];
+      fL1Station.fieldSlice.cy[j] = A[j][N + 1] / A[j][j];
+      fL1Station.fieldSlice.cz[j] = A[j][N + 2] / A[j][j];
+    }
+
+    fInitFlags[kEfieldSlice] = true;
   }
 
   /// Sets stereo angles and sigmas for front and back strips, automatically set frontInfo, backInfo,
@@ -201,13 +315,31 @@ public:
     fInitFlags[kEstripsBackPhi]    = true;
     fInitFlags[kEstripsBackSigma]  = true;
   }
+  /// Sets maximum distance between station center and its edge in x direction
+  void SetXmax(double aSize)
+  {
+    fXmax = aSize;
+    fInitFlags[kEXmax] = true;
+  }
+  /// Sets maximum distance between station center and its edge in y direction
+  void SetYmax(double aSize)
+  {
+    fYmax = aSize;
+    fInitFlags[kEYmax] = true;
+  }
 
   //
   // Getters
   //
 
-  /// Gets nominal z position of the station
-  fvec GetZ() const { return fL1Station.z; }
+  /// Gets station ID
+  int GetStationID() const { return fStationID; }
+  /// 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
@@ -238,6 +370,11 @@ public:
   /// Gets array of the coefficients for the field z-component approximation
   const fvec* GetFieldSliceCz() const { return fL1Station.fieldSlice.cz; }
 
+  /// 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; }
+
 
   //-------------------------------------------------------------------------------------------------------//
   //    Other methods                                                                                      //
@@ -248,7 +385,9 @@ public:
   {
     LOG(INFO) << "== L1Algo: station info ===========================================================";
     LOG(INFO) << "";
+    LOG(INFO) << "    Station ID:              " << fStationID;
     LOG(INFO) << "  L1Station fields:";
+    LOG(INFO) << "    Station type ID:         " << fL1Station.type;
     LOG(INFO) << "    z position:              " << fL1Station.z[0];
     LOG(INFO) << "    Rmin:                    " << fL1Station.Rmin[0];
     LOG(INFO) << "    Rmax:                    " << fL1Station.Rmax[0];
@@ -286,14 +425,26 @@ public:
     LOG(INFO) << "        sin(phi):            " << fL1Station.yInfo.sin_phi[0];
     LOG(INFO) << "        sigma2:              " << fL1Station.yInfo.sigma2[0];
     LOG(INFO) << "";
+    LOG(INFO) << "  Additiona fields:";
+    LOG(INFO) << "    Xmax:                    " << fXmax;
+    LOG(INFO) << "    Ymax:                    " << fYmax;
+    LOG(INFO) << "";
     LOG(INFO) << "===================================================================================";
   }
+  void Reset() {
+    L1BaseStationInfo other;
+    std::swap(*this, other);
+  }
 
 private:
-  /// Flags set. A particular flag is up if the corresponding setter was called (experimental)
-  std::bitset<L1BaseStationInfo::kEND> fInitFlags;
-  std::string fTypeName {"BASE"};
-  L1Station fL1Station {};
+  
+  std::bitset<L1BaseStationInfo::kEND> fInitFlags;  ///< Class fileds initialization flags
+  std::string fTypeName {"BASE"};  ///< Station type name (TODO: probably should be replaced with function of type)
+  L1Station fL1Station {};  ///< L1Station structure, describes a station in L1Algo
+  int fStationID {-1}; ///< Station ID
+  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
   // TODO (!!!!) MUST THINK ABOUT THIS OBJECT LIFE TIME: will it be better to copy
   //             or to move it to the core? If the second, what should we do with
   //             getters? Do we need to lock them, when the fL1Station object will
diff --git a/reco/L1/L1Algo/L1InitManager.h b/reco/L1/L1Algo/L1InitManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..d46295478cbbb1b2300e14ee694853cfc51255cd
--- /dev/null
+++ b/reco/L1/L1Algo/L1InitManager.h
@@ -0,0 +1,73 @@
+/* Copyright (C) 2016-2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergey Gorbunov, Sergei Zharko [committer] */
+
+/************************************************************************************************************
+ * @file L1InitManager.h
+ * @bried Input data management class for L1Algo
+ * @since 24.12.2021
+ *
+ ***********************************************************************************************************/
+
+#include "L1BaseStationInfo.h"
+#include "L1Parameters.h"
+#include "L1Vector.h"
+
+//#include <string>
+#include <unordered_map>
+
+/// Initialization manager for L1Aglo
+///
+/// The L1InitManager class provides interface for L1Algo initialization
+
+class L1InitManager {
+public:
+  /// Default constructor
+  L1InitManager() = default;
+  /// Destructor
+  ~L1InitManager() = default;
+  /// Copy constructor is forbidden
+  L1InitManager(const L1InitManager& /*other*/) = delete;
+  /// Move constructor is forbidden
+  L1InitManager(L1InitManager&& /*other*/) = delete;
+  /// Copy assignment operator is forbidden
+  L1InitManager& operator=(const L1InitManager& /*other*/) = delete;
+  /// Move assignment operator is forbidden
+  L1InitManager& operator=(L1InitManager&& /*other*/) = delete;
+
+  /// Adds another station of a given type using reference to a L1BaseStationInfo object
+  void AddStation(const L1BaseStationInfo& inStation)
+  {
+    fvStationsInfo.push_back(inStation);
+    ++fmStationsNumber[inStation.GetStationType()];
+    // TODO: Think, how we would like to initialize station ID
+  }
+  /// Adds another station of a given type using pointer to a L1BaseStationInfo object
+  void AddStation(const L1BaseStationInfo* inStationPtr)
+  {
+    fvStationsInfo.push_back(*inStationPtr);  // Copy is occured
+    ++fmStationsNumber[inStationPtr->GetStationType()];
+  }
+
+  /// Prints out a list of stations
+  void PrintStations(int verbosityLevel = 0)
+  {
+    if (verbosityLevel < 1) {
+      for (auto& station : fvStationsInfo) {
+        LOG(INFO) << "----------- station: ";
+        LOG(INFO) << "\ttype = " << station.GetStationType();  // TMP
+        LOG(INFO) << "\tz = " << station.GetZdouble(); 
+      }
+    }
+    else {
+      for (auto& station : fvStationsInfo) {
+        station.Print();
+      }
+    }
+  }
+
+private:
+  L1Vector<L1BaseStationInfo> fvStationsInfo {"L1InitManager::fvStationsInfo"};  ///< Vector containing all the stations
+  // TODO: Max stations is probably not optimal for vector initialization. Must think, what to do here. 
+  std::unordered_map<int, int> fmStationsNumber;  ///< Number of each station type <station type, counter>
+};
diff --git a/reco/L1/L1Algo/L1Parameters.h b/reco/L1/L1Algo/L1Parameters.h
index 718d3bea164b134385f40cc9cd33f437b94bdf39..94de70cf100beb82e5accaaee22901779a438169 100644
--- a/reco/L1/L1Algo/L1Parameters.h
+++ b/reco/L1/L1Algo/L1Parameters.h
@@ -13,6 +13,44 @@
 #define L1Parameters_h 1
 
 #include <FairLogger.h>
+#include <string>
+#include <unordered_map>
+#include <iomanip>
+
+#include "L1Vector.h"
+
+//---------------------------------------------------------------------------------------------------------//
+//    Track finder iterations definition
+//---------------------------------------------------------------------------------------------------------//
+
+// TODO: May be it is reasonable to create TrackFinderIterations class 
+
+/// Different iterations for Track Finder running
+enum class TrackFinderIter {
+  kFastPrim,       ///< primary fast tracks
+  kAllPrim,        ///< primary all tracks
+  kAllPrimJump,    ///< primary all tracks with jumped triplets
+  kAllSec,         ///< secondary all tracks
+  kAllPrimE,       ///< primary all electron tracks
+  kAllSecE,        ///< secondary all electron tracks 
+  kFastPrimJump,   ///< primary fast tracks with jumped triplets
+  kAllSecJump      ///< secondary all tracks with jumped triplets
+};
+
+
+const std::unordered_map<TrackFinderIter, std::string> kTrackFinderIterNames {
+  { TrackFinderIter::kFastPrim,     "Primary tracks, fast" },
+  { TrackFinderIter::kAllPrim,      "Primary tracks, all" },
+  { TrackFinderIter::kAllPrimJump,  "Primary tracks with jumped triplets, all" },
+  { TrackFinderIter::kAllSec,       "Secondary tracks, all" },
+  { TrackFinderIter::kAllPrimE,     "Primary electron tracks, all" },
+  { TrackFinderIter::kAllSecE,      "Secondary electron tracks, all" },
+  { TrackFinderIter::kFastPrimJump, "Primary tracks with jumped triplets, fast" },
+  { TrackFinderIter::kAllSecJump,   "Secondary tracks with jumped triplets, all" }
+};
+
+template <typename T>
+using TrackFinderIterParameter_t = std::unordered_map<TrackFinderIter, T>;
 
 class L1Parameters {
 public:
@@ -22,19 +60,15 @@ public:
   /// Amount of coefficients in field approximations
   static constexpr int kMaxNFieldApproxCoefficients {21};  // TODO: May be it is better to use the polynomial
                                                            // order instead of this?
-  /// Amount of bits to code one station
-  static constexpr unsigned int kStationBits {6};
-  /// Amount of bits to code one thread
-  static constexpr unsigned int kThreadBits {6};
-  /// Amount of bits to code one triple
-  static constexpr unsigned int kTripletBits {32 - kStationBits - kThreadBits};
-
-  /// Max number of stations
-  static constexpr unsigned int kMaxNstations {1 << kStationBits};  // 2^6  = 64
-  /// Max number of threads
-  static constexpr unsigned int kMaxNthreads {1 << kThreadBits};  // 2^6  = 64
-  /// Max number of triplets
-  static constexpr unsigned int kMaxNtriplets {1 << kTripletBits};  // 2^20 = 1,048,576
+  static constexpr int kMaxFieldApproxPolynomialOrder {5}; ///> Order of polynomial to approximate field in the vicinity of station plane
+
+  static constexpr unsigned int kStationBits {6};  ///> Amount of bits to code one station
+  static constexpr unsigned int kThreadBits {6};  ///> Amount of bits to code one thread
+  static constexpr unsigned int kTripletBits {32 - kStationBits - kThreadBits};  ///> Amount of bits to code one triple
+
+  static constexpr unsigned int kMaxNstations {1 << kStationBits};  ///> Max number of stations, 2^6  = 64
+  static constexpr unsigned int kMaxNthreads {1 << kThreadBits};  ///> Max number of threads, 2^6  = 64
+  static constexpr unsigned int kMaxNtriplets {1 << kTripletBits};  ///> Max number of triplets, 2^20 = 1,048,576
 
 public:
   //-------------------------------------------------------------------------------------------------------//
@@ -71,26 +105,90 @@ public:
     LOG(INFO) << "===================================================================================";
   }
   // TODO: change constant names with actual (human) names
-  // TODO: create a map with parameters, their description and
+  // TODO: create a map with parameters, their description etc.
 
 public:
   //-------------------------------------------------------------------------------------------------------//
-  //    Runtime constants                                                                                 //
+  //    Runtime constants                                                                                  //
   //-------------------------------------------------------------------------------------------------------//
   /// Sets upper-bound cut on max number of doublets per one singlet
   void SetMaxDoubletsPerSinglet(unsigned int value) { fMaxDoubletsPerSinglet = value; }
   /// Sets upper-bound cut on max number of triplets per one doublet
   void SetMaxTripletPerDoublets(unsigned int value) { fMaxTripletPerDoublets = value; }
 
+  /// Sets track finder iteration sequence
+  void SetTrackFinderIterSequence(const L1Vector<TrackFinderIter>& iterations) {
+    fTrackFinderIterSequence = iterations;
+  }
+  
+
   unsigned int GetMaxDoubletsPerSinglet() const { return fMaxDoubletsPerSinglet; }
   unsigned int GetMaxTripletPerDoublets() const { return fMaxTripletPerDoublets; }
 
+  //-------------------------------------------------------------------------------------------------------//
+  //    Auxilary methods                                                                                   //
+  //-------------------------------------------------------------------------------------------------------//
+  
+  void PrintTrackFinderIterationsSequence() const
+  {  
+    LOG(INFO) << "== L1Algo track finder iterations =================================================";
+    LOG(INFO) << "";
+    int idx = 0;
+    for (auto& iteration: fTrackFinderIterSequence) {
+      LOG(INFO) << "  " << std::setw(2) << std::setfill(' ') << idx << ' ' << kTrackFinderIterNames.at(iteration);
+      ++idx;
+    }
+    LOG(INFO) << "";
+    LOG(INFO) << "===================================================================================";
+
+  }
 
 private:
-  ///
-  unsigned int fMaxDoubletsPerSinglet {150};
-  ///
-  unsigned int fMaxTripletPerDoublets {15};
+  unsigned int fMaxDoubletsPerSinglet {150};  ///<
+  unsigned int fMaxTripletPerDoublets {15};  ///<
+
+  L1Vector<TrackFinderIter> fTrackFinderIterSequence {}; ///< Sequence of iterations in the track finder algorithm 
+
+  // TODO: Develope naming system for these constants
+
+  std::unordered_map<TrackFinderIter, float> fTrackChi2Cut {
+    { TrackFinderIter::kFastPrim,     10.f },
+    { TrackFinderIter::kAllPrim,      10.f },
+    { TrackFinderIter::kAllPrimJump,  10.f },
+    { TrackFinderIter::kAllSec,       10.f },
+    { TrackFinderIter::kAllPrimE,     10.f },
+    { TrackFinderIter::kAllSecE,      10.f },
+    { TrackFinderIter::kFastPrimJump, 10.f },
+    { TrackFinderIter::kAllSecJump,   10.f }
+  };
+
+  std::unordered_map<TrackFinderIter, float> fTripletChi2Cut {
+    { TrackFinderIter::kFastPrim,     5.f },
+    { TrackFinderIter::kAllPrim,      5.f },
+    { TrackFinderIter::kAllPrimJump,  5.f },
+    { TrackFinderIter::kAllSec,       5.f },
+    { TrackFinderIter::kAllPrimE,     5.f },
+    { TrackFinderIter::kAllSecE,      5.f },
+    { TrackFinderIter::kFastPrimJump, 5.f },
+    { TrackFinderIter::kAllSecJump,   5.f }
+  };
+
+  std::unordered_map<TrackFinderIter, float> fDoubletChi2Cut {
+    { TrackFinderIter::kFastPrim,     5.f },
+    { TrackFinderIter::kAllPrim,      5.f },
+    { TrackFinderIter::kAllPrimJump,  5.f },
+    { TrackFinderIter::kAllSec,       5.f },
+    { TrackFinderIter::kAllPrimE,     5.f },
+    { TrackFinderIter::kAllSecE,      5.f },
+    { TrackFinderIter::kFastPrimJump, 5.f },
+    { TrackFinderIter::kAllSecJump,   5.f }
+  };
+
+  
+
+  //float fTripletChi2Cut {5.f};
+  //float fTripletChi2Cut {5.f};
+
 };
 
 #endif  // L1Parameters_h