From fcc0d31017d10d7f9c1314492e2ffd7ba9936199 Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Mon, 5 Sep 2022 17:20:29 +0200
Subject: [PATCH] L1: Added boost serializers for L1Parameters objects and
 their components; implemented an interface for parameters and input data RW

---
 macro/mcbm/mcbm_reco_event.C         |    2 +-
 macro/run/run_reco.C                 |    4 +-
 reco/L1/CMakeLists.txt               |    1 +
 reco/L1/CbmL1.cxx                    | 1077 +++++++++++++-------------
 reco/L1/CbmL1.h                      |   57 +-
 reco/L1/CbmL1ReadEvent.cxx           |    8 +-
 reco/L1/L1Algo/L1CAIteration.h       |   57 +-
 reco/L1/L1Algo/L1Field.h             |   39 +-
 reco/L1/L1Algo/L1InitManager.cxx     |   93 ++-
 reco/L1/L1Algo/L1InitManager.h       |   25 +-
 reco/L1/L1Algo/L1MaterialInfo.h      |   25 +
 reco/L1/L1Algo/L1Parameters.cxx      |    4 +-
 reco/L1/L1Algo/L1Parameters.h        |   38 +-
 reco/L1/L1Algo/L1SimdSerializer.h    |   31 +
 reco/L1/L1Algo/L1Station.h           |   25 +
 reco/L1/L1Algo/L1UMeasurementInfo.h  |   11 +
 reco/L1/L1Algo/L1XYMeasurementInfo.h |   12 +-
 17 files changed, 934 insertions(+), 575 deletions(-)
 create mode 100644 reco/L1/L1Algo/L1SimdSerializer.h

diff --git a/macro/mcbm/mcbm_reco_event.C b/macro/mcbm/mcbm_reco_event.C
index 3193307344..447f3f25c6 100644
--- a/macro/mcbm/mcbm_reco_event.C
+++ b/macro/mcbm/mcbm_reco_event.C
@@ -375,7 +375,7 @@ void mcbm_reco_event(Int_t nEvents = 10, TString dataset = "data/test",
   run->AddTask(kalman);
 
   // L1 tracking
-  auto l1 = (debugWithMC) ? new CbmL1("L1", 1, 3) : new CbmL1();
+  auto l1 = (debugWithMC) ? new CbmL1("L1", 1, 3, 0) : new CbmL1();
   l1->SetLegacyEventMode(1);
   l1->SetMcbmMode();
   l1->SetUseHitErrors(1);
diff --git a/macro/run/run_reco.C b/macro/run/run_reco.C
index 8b9add9650..e49474e04b 100644
--- a/macro/run/run_reco.C
+++ b/macro/run/run_reco.C
@@ -379,8 +379,8 @@ void run_reco(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice =
     run->AddTask(kalman);
 
     // L1 tracking
-    auto l1 = (debugWithMC) ? new CbmL1("L1", 2, 3) : new CbmL1("L1", 0);
-    l1->SetInputConfigName(TString(gSystem->Getenv("VMCWORKDIR")) + "/reco/L1/L1Algo/L1ConfigExample.yaml");
+    auto l1 = (debugWithMC) ? new CbmL1("L1", 2, 3, 0) : new CbmL1("L1", 0);
+    //l1->SetInputConfigName(TString(gSystem->Getenv("VMCWORKDIR")) + "/reco/L1/L1Algo/L1ConfigExample.yaml");
 
     // --- Material budget file names
     TString mvdGeoTag;
diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt
index 7e89dcffe2..3bd2577e6a 100644
--- a/reco/L1/CMakeLists.txt
+++ b/reco/L1/CMakeLists.txt
@@ -305,6 +305,7 @@ Install(FILES CbmL1Counters.h
   L1Algo/L1Constants.h
   L1Algo/L1Utils.h
   L1Algo/L1NaN.h
+  L1Algo/L1SimdSerializer.h 
   vectors/std_alloc.h
   DESTINATION include
 )
diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index 27655f2603..242108264e 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -77,8 +77,6 @@ ClassImp(CbmL1);
 
 static L1Algo gAlgo _fvecalignment;  // TODO: Change coupling logic between L1Algo and CbmL1
 
-//L1AlgoInputData* fData_static _fvecalignment;
-
 CbmL1* CbmL1::fpInstance = 0;
 
 
@@ -94,14 +92,21 @@ CbmL1::CbmL1(const char* name, Int_t verbose, Int_t performance, int dataMode, c
   , fIODataManager(L1IODataManager(gAlgo.GetParameters()))
   , fPerformance(performance)
   , fSTAPDataMode(dataMode)
-  , fSTAPDataDir(dataDir)
   , fFindParticlesMode(findParticleMode)
 {
   if (!fpInstance) fpInstance = this;
 
+  switch (fSTAPDataMode) {
+    case 1: LOG(info) << "CbmL1: input data will be written for a standalone usage"; break;
+    case 2: LOG(info) << "CbmL1: input data will be read from external files"; break;
+    default: LOG(info) << "CbmL1: tracking will be run without external data R/W"; break;
+  }
+
+  if (1 == fSTAPDataMode || 2 == fSTAPDataMode) { this->DefineSTAPNames(dataDir); }
+
   if (!CbmTrackingDetectorInterfaceInit::Instance()) {
     LOG(fatal) << "CbmL1: CbmTrackingDetectorInterfaceInit instance was not found. Please, add it as a task to your "
-                  "reco macro before the KF and L1 task:\n"
+                  "reco macro right before the KF and L1 tasks:\n"
                << "\033[1;30mrun->AddTask(new CbmTrackingDetectorInterfaceInit());\033[0m";
   }
 }
@@ -347,487 +352,507 @@ InitStatus CbmL1::Init()
     fpMvdHits = L1_DYNAMIC_CAST<TClonesArray*>(fairManager->GetObject("MvdHit"));
   }
 
-  fNMvdStationsGeom  = 0;
-  fNStsStationsGeom  = 0;
-  fNMuchStationsGeom = 0;
-  fNTrdStationsGeom  = 0;
-  fNTofStationsGeom  = 0;
-  fNStationsGeom     = 0;
-
-
-  /**************************
-   ** Field initialization **
-   **************************/
-
-  fInitManager.SetFieldFunction([](const double(&inPos)[3], double(&outB)[3]) {
-    CbmKF::Instance()->GetMagneticField()->GetFieldValue(inPos, outB);
-  });
-
-  /***************************
-   ** Target initialization **
-   ***************************/
-
-  auto& target = CbmKF::Instance()->vTargets[0];
-  fInitManager.SetTargetPosition(target.x, target.y, target.z);
-
-  /*********************************
-   ** Target field initialization **
-   *********************************/
-
-  fInitManager.InitTargetField(/*zStep = */ 2.5 /*cm*/);  // Replace zStep -> sizeZfieldRegion = 2 * zStep (TODO)
-
-  /**************************************
-   **                                  **
-   ** STATIONS GEOMETRY INITIALIZATION **
-   **                                  **
-   **************************************/
-
-
-  /***************************************************
-   ** Active tracking detector subsystems selection **
-   ***************************************************/
-
-  std::set<L1DetectorID> vActiveTrackingDetectorIDs {};  // Set of detectors active in tracking
-
-  if (fUseMVD) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kMvd); }
-  if (fUseSTS) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kSts); }
-  if (fUseMUCH) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kMuch); }
-  if (fUseTRD) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kTrd); }
-  if (fUseTOF) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kTof); }
-  fInitManager.SetActiveDetectorIDs(vActiveTrackingDetectorIDs);
-
-  /*********************************************************************
-   ** Counting numbers of stations for different detector subsystems  **
-   *********************************************************************/
-
-  /*** MVD and STS ***/
-  auto mvdInterface  = CbmMvdTrackingInterface::Instance();
-  auto stsInterface  = CbmStsTrackingInterface::Instance();
-  auto muchInterface = CbmMuchTrackingInterface::Instance();
-  auto trdInterface  = CbmTrdTrackingInterface::Instance();
-  auto tofInterface  = CbmTofTrackingInterface::Instance();
-
-  // NOTE: hack for "mcbm_beam_2021_07_surveyed" to account for a mismactch in the station
-  //       indeces of hits in TOF
-  if (fMissingHits) { tofInterface->FixHitsStationsMismatch(); }
-
-  fNMvdStationsGeom  = (fUseMVD) ? mvdInterface->GetNtrackingStations() : 0;
-  fNStsStationsGeom  = (fUseSTS) ? stsInterface->GetNtrackingStations() : 0;
-  fNMuchStationsGeom = (fUseMUCH) ? muchInterface->GetNtrackingStations() : 0;
-  fNTrdStationsGeom  = (fUseTRD) ? trdInterface->GetNtrackingStations() : 0;
-  fNTofStationsGeom  = (fUseTOF) ? tofInterface->GetNtrackingStations() : 0;
-  fNStationsGeom = fNMvdStationsGeom + fNStsStationsGeom + fNMuchStationsGeom + fNTrdStationsGeom + fNTofStationsGeom;
-
-  // Provide crosscheck number of stations for the fInitManagera
-  fInitManager.SetNstations(L1DetectorID::kMvd, fNMvdStationsGeom);
-  fInitManager.SetNstations(L1DetectorID::kSts, fNStsStationsGeom);
-  fInitManager.SetNstations(L1DetectorID::kMuch, fNMuchStationsGeom);
-  fInitManager.SetNstations(L1DetectorID::kTrd, fNTrdStationsGeom);
-  fInitManager.SetNstations(L1DetectorID::kTof, fNTofStationsGeom);
-
-  /****************************
-   ** Material budget input  **
-   ****************************/
-
-  // NOTE: std::vector of material tables. Vector sizes correspond to number of stations provided by geometry, i.e. both
-  //       active and inactive station are represented in the folloving vectors
-  auto materialTableMvd  = ReadMaterialBudget(L1DetectorID::kMvd);
-  auto materialTableSts  = ReadMaterialBudget(L1DetectorID::kSts);
-  auto materialTableMuch = ReadMaterialBudget(L1DetectorID::kMuch);
-  auto materialTableTrd  = ReadMaterialBudget(L1DetectorID::kTrd);
-  auto materialTableTof  = ReadMaterialBudget(L1DetectorID::kTof);
-
-  /* User corrections (optional) */
-  auto correctionMvd = [this](L1Material& material, const L1MaterialInfo& homogenious) {
-    this->ApplyCorrectionToMaterialMap<L1DetectorID::kMvd>(material, homogenious);
-  };
-  auto correctionSts = [this](L1Material& material, const L1MaterialInfo& homogenious) {
-    this->ApplyCorrectionToMaterialMap<L1DetectorID::kSts>(material, homogenious);
-  };
-  auto correctionMuch = [this](L1Material& material, const L1MaterialInfo& homogenious) {
-    this->ApplyCorrectionToMaterialMap<L1DetectorID::kMuch>(material, homogenious);
-  };
-  auto correctionTrd = [this](L1Material& material, const L1MaterialInfo& homogenious) {
-    this->ApplyCorrectionToMaterialMap<L1DetectorID::kTrd>(material, homogenious);
-  };
-  auto correctionTof = [this](L1Material& material, const L1MaterialInfo& homogenious) {
-    this->ApplyCorrectionToMaterialMap<L1DetectorID::kTof>(material, homogenious);
-  };
+  // *****************************
+  // ** Geometry initialization **
+  // *****************************
 
-  /***************************************
-   ** Stations geometry initialization  **
-   ***************************************/
-
-  /*** MVD stations info ***/
-  if (fUseMVD) {
-    for (int iSt = 0; iSt < fNMvdStationsGeom; ++iSt) {
-      auto stationInfo = L1BaseStationInfo(L1DetectorID::kMvd, iSt);
-      stationInfo.SetStationType(1);  // MVD
-      stationInfo.SetTimeInfo(mvdInterface->IsTimeInfoProvided(iSt));
-      stationInfo.SetTimeResolution(mvdInterface->GetTimeResolution(iSt));
-      stationInfo.SetFieldStatus(fTrackingMode == L1Algo::TrackingMode::kMcbm ? 0 : 1);
-      stationInfo.SetZ(mvdInterface->GetZ(iSt));
-      stationInfo.SetXmax(mvdInterface->GetXmax(iSt));
-      stationInfo.SetYmax(mvdInterface->GetYmax(iSt));
-      stationInfo.SetRmin(mvdInterface->GetRmin(iSt));
-      stationInfo.SetRmax(mvdInterface->GetRmax(iSt));
-      stationInfo.SetMaterialSimple(mvdInterface->GetThickness(iSt), mvdInterface->GetRadLength(iSt));
-      stationInfo.SetMaterialMap(std::move(materialTableMvd[iSt]), correctionMvd);
-      // TODO: The CA TF result is dependent from type of geometry settings. Should be understood (S.Zharko)
-      stationInfo.SetFrontBackStripsGeometry(
-        (fscal) mvdInterface->GetStripsStereoAngleFront(iSt), (fscal) mvdInterface->GetStripsSpatialRmsFront(iSt),
-        (fscal) mvdInterface->GetStripsStereoAngleBack(iSt), (fscal) mvdInterface->GetStripsSpatialRmsBack(iSt));
-      stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
-      fInitManager.AddStation(stationInfo);
-      LOG(info) << "- MVD station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
-    }
+  // Read parameters object from a binary file
+  if (2 == fSTAPDataMode) {
+    this->ReadSTAPParamObject();
+
+    fNMvdStationsGeom  = fInitManager.GetNstationsGeometry(L1DetectorID::kMvd);
+    fNStsStationsGeom  = fInitManager.GetNstationsGeometry(L1DetectorID::kSts);
+    fNTrdStationsGeom  = fInitManager.GetNstationsGeometry(L1DetectorID::kTrd);
+    fNMuchStationsGeom = fInitManager.GetNstationsGeometry(L1DetectorID::kMuch);
+    fNTofStationsGeom  = fInitManager.GetNstationsGeometry(L1DetectorID::kTof);
+    fNStationsGeom     = fInitManager.GetNstationsGeometry();
+
+    if (fMissingHits) { CbmTofTrackingInterface::Instance()->FixHitsStationsMismatch(); }
   }
+  // Parameters initialization, based on the FairRunAna chain
+  else {
+    auto mvdInterface  = CbmMvdTrackingInterface::Instance();
+    auto stsInterface  = CbmStsTrackingInterface::Instance();
+    auto muchInterface = CbmMuchTrackingInterface::Instance();
+    auto trdInterface  = CbmTrdTrackingInterface::Instance();
+    auto tofInterface  = CbmTofTrackingInterface::Instance();
+
+    // NOTE: hack for "mcbm_beam_2021_07_surveyed" to account for a mismactch in the station
+    //       indeces of hits in TOF
+    if (fMissingHits) { tofInterface->FixHitsStationsMismatch(); }
+
+    fNMvdStationsGeom  = (fUseMVD) ? mvdInterface->GetNtrackingStations() : 0;
+    fNStsStationsGeom  = (fUseSTS) ? stsInterface->GetNtrackingStations() : 0;
+    fNMuchStationsGeom = (fUseMUCH) ? muchInterface->GetNtrackingStations() : 0;
+    fNTrdStationsGeom  = (fUseTRD) ? trdInterface->GetNtrackingStations() : 0;
+    fNTofStationsGeom  = (fUseTOF) ? tofInterface->GetNtrackingStations() : 0;
+    fNStationsGeom = fNMvdStationsGeom + fNStsStationsGeom + fNMuchStationsGeom + fNTrdStationsGeom + fNTofStationsGeom;
+
+    // **************************
+    // ** Field initialization **
+    // **************************
+
+    fInitManager.SetFieldFunction([](const double(&inPos)[3], double(&outB)[3]) {
+      CbmKF::Instance()->GetMagneticField()->GetFieldValue(inPos, outB);
+    });
+
+    // ***************************
+    // ** Target initialization **
+    // ***************************
+
+    auto& target = CbmKF::Instance()->vTargets[0];
+    fInitManager.SetTargetPosition(target.x, target.y, target.z);
+
+    // *********************************
+    // ** Target field initialization **
+    // *********************************
+
+    fInitManager.InitTargetField(/*zStep = */ 2.5 /*cm*/);  // Replace zStep -> sizeZfieldRegion = 2 * zStep (TODO)
+
+    // **************************************
+    // **                                  **
+    // ** STATIONS GEOMETRY INITIALIZATION **
+    // **                                  **
+    // **************************************
+
+
+    // ***************************************************
+    // ** Active tracking detector subsystems selection **
+    // ***************************************************
+
+    std::set<L1DetectorID> vActiveTrackingDetectorIDs {};  // Set of detectors active in tracking
+
+    if (fUseMVD) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kMvd); }
+    if (fUseSTS) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kSts); }
+    if (fUseMUCH) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kMuch); }
+    if (fUseTRD) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kTrd); }
+    if (fUseTOF) { vActiveTrackingDetectorIDs.insert(L1DetectorID::kTof); }
+    fInitManager.SetActiveDetectorIDs(vActiveTrackingDetectorIDs);
+
+    // *********************************************************************
+    // ** Counting numbers of stations for different detector subsystems  **
+    // *********************************************************************
+
+
+    // Provide crosscheck number of stations for the fInitManagera
+    fInitManager.SetNstations(L1DetectorID::kMvd, fNMvdStationsGeom);
+    fInitManager.SetNstations(L1DetectorID::kSts, fNStsStationsGeom);
+    fInitManager.SetNstations(L1DetectorID::kMuch, fNMuchStationsGeom);
+    fInitManager.SetNstations(L1DetectorID::kTrd, fNTrdStationsGeom);
+    fInitManager.SetNstations(L1DetectorID::kTof, fNTofStationsGeom);
+
+    // ****************************
+    // ** Material budget input  **
+    // ****************************
+
+    // NOTE: std::vector of material tables. Vector sizes correspond to number of stations provided by geometry, i.e. both
+    //       active and inactive station are represented in the folloving vectors
+    auto materialTableMvd  = ReadMaterialBudget(L1DetectorID::kMvd);
+    auto materialTableSts  = ReadMaterialBudget(L1DetectorID::kSts);
+    auto materialTableMuch = ReadMaterialBudget(L1DetectorID::kMuch);
+    auto materialTableTrd  = ReadMaterialBudget(L1DetectorID::kTrd);
+    auto materialTableTof  = ReadMaterialBudget(L1DetectorID::kTof);
+
+    /* User corrections (optional) */
+    auto correctionMvd = [this](L1Material& material, const L1MaterialInfo& homogenious) {
+      this->ApplyCorrectionToMaterialMap<L1DetectorID::kMvd>(material, homogenious);
+    };
+    auto correctionSts = [this](L1Material& material, const L1MaterialInfo& homogenious) {
+      this->ApplyCorrectionToMaterialMap<L1DetectorID::kSts>(material, homogenious);
+    };
+    auto correctionMuch = [this](L1Material& material, const L1MaterialInfo& homogenious) {
+      this->ApplyCorrectionToMaterialMap<L1DetectorID::kMuch>(material, homogenious);
+    };
+    auto correctionTrd = [this](L1Material& material, const L1MaterialInfo& homogenious) {
+      this->ApplyCorrectionToMaterialMap<L1DetectorID::kTrd>(material, homogenious);
+    };
+    auto correctionTof = [this](L1Material& material, const L1MaterialInfo& homogenious) {
+      this->ApplyCorrectionToMaterialMap<L1DetectorID::kTof>(material, homogenious);
+    };
+
+    // ***************************************
+    // ** Stations geometry initialization  **
+    // ***************************************
+
+    // *** MVD stations info ***
+    if (fUseMVD) {
+      for (int iSt = 0; iSt < fNMvdStationsGeom; ++iSt) {
+        auto stationInfo = L1BaseStationInfo(L1DetectorID::kMvd, iSt);
+        stationInfo.SetStationType(1);  // MVD
+        stationInfo.SetTimeInfo(mvdInterface->IsTimeInfoProvided(iSt));
+        stationInfo.SetTimeResolution(mvdInterface->GetTimeResolution(iSt));
+        stationInfo.SetFieldStatus(fTrackingMode == L1Algo::TrackingMode::kMcbm ? 0 : 1);
+        stationInfo.SetZ(mvdInterface->GetZ(iSt));
+        stationInfo.SetXmax(mvdInterface->GetXmax(iSt));
+        stationInfo.SetYmax(mvdInterface->GetYmax(iSt));
+        stationInfo.SetRmin(mvdInterface->GetRmin(iSt));
+        stationInfo.SetRmax(mvdInterface->GetRmax(iSt));
+        stationInfo.SetMaterialSimple(mvdInterface->GetThickness(iSt), mvdInterface->GetRadLength(iSt));
+        stationInfo.SetMaterialMap(std::move(materialTableMvd[iSt]), correctionMvd);
+        // TODO: The CA TF result is dependent from type of geometry settings. Should be understood (S.Zharko)
+        stationInfo.SetFrontBackStripsGeometry(
+          (fscal) mvdInterface->GetStripsStereoAngleFront(iSt), (fscal) mvdInterface->GetStripsSpatialRmsFront(iSt),
+          (fscal) mvdInterface->GetStripsStereoAngleBack(iSt), (fscal) mvdInterface->GetStripsSpatialRmsBack(iSt));
+        stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
+        fInitManager.AddStation(stationInfo);
+        LOG(info) << "- MVD station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
+      }
+    }
 
-  /*** STS stations info ***/
-  if (fUseSTS) {
-    for (int iSt = 0; iSt < fNStsStationsGeom; ++iSt) {
-      auto stationInfo = L1BaseStationInfo(L1DetectorID::kSts, iSt);
-      stationInfo.SetStationType(0);  // STS
-      stationInfo.SetTimeInfo(stsInterface->IsTimeInfoProvided(iSt));
-      stationInfo.SetTimeResolution(stsInterface->GetTimeResolution(iSt));
-      stationInfo.SetFieldStatus(L1Algo::TrackingMode::kMcbm == fTrackingMode ? 0 : 1);
-      stationInfo.SetZ(stsInterface->GetZ(iSt));
-      stationInfo.SetXmax(stsInterface->GetXmax(iSt));
-      stationInfo.SetYmax(stsInterface->GetYmax(iSt));
-      stationInfo.SetRmin(stsInterface->GetRmin(iSt));
-      stationInfo.SetRmax(stsInterface->GetRmax(iSt));
-      stationInfo.SetMaterialSimple(stsInterface->GetThickness(iSt), stsInterface->GetRadLength(iSt));
-      stationInfo.SetMaterialMap(std::move(materialTableSts[iSt]), correctionSts);
-      // TODO: The CA TF result is dependent from type of geometry settings. Should be understood (S.Zharko)
-      stationInfo.SetFrontBackStripsGeometry(
-        (fscal) stsInterface->GetStripsStereoAngleFront(iSt), (fscal) stsInterface->GetStripsSpatialRmsFront(iSt),
-        (fscal) stsInterface->GetStripsStereoAngleBack(iSt), (fscal) stsInterface->GetStripsSpatialRmsBack(iSt));
-      stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
-      fInitManager.AddStation(stationInfo);
-      LOG(info) << "- STS station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
+    // *** STS stations info ***
+    if (fUseSTS) {
+      for (int iSt = 0; iSt < fNStsStationsGeom; ++iSt) {
+        auto stationInfo = L1BaseStationInfo(L1DetectorID::kSts, iSt);
+        stationInfo.SetStationType(0);  // STS
+        stationInfo.SetTimeInfo(stsInterface->IsTimeInfoProvided(iSt));
+        stationInfo.SetTimeResolution(stsInterface->GetTimeResolution(iSt));
+        stationInfo.SetFieldStatus(L1Algo::TrackingMode::kMcbm == fTrackingMode ? 0 : 1);
+        stationInfo.SetZ(stsInterface->GetZ(iSt));
+        stationInfo.SetXmax(stsInterface->GetXmax(iSt));
+        stationInfo.SetYmax(stsInterface->GetYmax(iSt));
+        stationInfo.SetRmin(stsInterface->GetRmin(iSt));
+        stationInfo.SetRmax(stsInterface->GetRmax(iSt));
+        stationInfo.SetMaterialSimple(stsInterface->GetThickness(iSt), stsInterface->GetRadLength(iSt));
+        stationInfo.SetMaterialMap(std::move(materialTableSts[iSt]), correctionSts);
+        // TODO: The CA TF result is dependent from type of geometry settings. Should be understood (S.Zharko)
+        stationInfo.SetFrontBackStripsGeometry(
+          (fscal) stsInterface->GetStripsStereoAngleFront(iSt), (fscal) stsInterface->GetStripsSpatialRmsFront(iSt),
+          (fscal) stsInterface->GetStripsStereoAngleBack(iSt), (fscal) stsInterface->GetStripsSpatialRmsBack(iSt));
+        stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
+        fInitManager.AddStation(stationInfo);
+        LOG(info) << "- STS station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
+      }
     }
-  }
 
-  /*** MuCh stations info ***/
-  if (fUseMUCH) {
-    for (int iSt = 0; iSt < fNMuchStationsGeom; ++iSt) {
-      auto stationInfo = L1BaseStationInfo(L1DetectorID::kMuch, iSt);
-      stationInfo.SetStationType(2);  // MuCh
-      stationInfo.SetTimeInfo(muchInterface->IsTimeInfoProvided(iSt));
-      stationInfo.SetTimeResolution(muchInterface->GetTimeResolution(iSt));
-      stationInfo.SetFieldStatus(0);
-      stationInfo.SetZ(muchInterface->GetZ(iSt));
-      stationInfo.SetXmax(muchInterface->GetXmax(iSt));
-      stationInfo.SetYmax(muchInterface->GetYmax(iSt));
-      stationInfo.SetRmin(muchInterface->GetRmin(iSt));
-      stationInfo.SetRmax(muchInterface->GetRmax(iSt));
-      stationInfo.SetMaterialSimple(muchInterface->GetThickness(iSt), muchInterface->GetRadLength(iSt));
-      stationInfo.SetMaterialMap(std::move(materialTableMuch[iSt]), correctionMuch);
-      // TODO: The CA TF result is dependent from type of geometry settings. Should be understood (S.Zharko)
-      stationInfo.SetFrontBackStripsGeometry(
-        (fscal) muchInterface->GetStripsStereoAngleFront(iSt), (fscal) muchInterface->GetStripsSpatialRmsFront(iSt),
-        (fscal) muchInterface->GetStripsStereoAngleBack(iSt), (fscal) muchInterface->GetStripsSpatialRmsBack(iSt));
-      stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
-      fInitManager.AddStation(stationInfo);
-      LOG(info) << "- MuCh station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
+    // *** MuCh stations info ***
+    if (fUseMUCH) {
+      for (int iSt = 0; iSt < fNMuchStationsGeom; ++iSt) {
+        auto stationInfo = L1BaseStationInfo(L1DetectorID::kMuch, iSt);
+        stationInfo.SetStationType(2);  // MuCh
+        stationInfo.SetTimeInfo(muchInterface->IsTimeInfoProvided(iSt));
+        stationInfo.SetTimeResolution(muchInterface->GetTimeResolution(iSt));
+        stationInfo.SetFieldStatus(0);
+        stationInfo.SetZ(muchInterface->GetZ(iSt));
+        stationInfo.SetXmax(muchInterface->GetXmax(iSt));
+        stationInfo.SetYmax(muchInterface->GetYmax(iSt));
+        stationInfo.SetRmin(muchInterface->GetRmin(iSt));
+        stationInfo.SetRmax(muchInterface->GetRmax(iSt));
+        stationInfo.SetMaterialSimple(muchInterface->GetThickness(iSt), muchInterface->GetRadLength(iSt));
+        stationInfo.SetMaterialMap(std::move(materialTableMuch[iSt]), correctionMuch);
+        // TODO: The CA TF result is dependent from type of geometry settings. Should be understood (S.Zharko)
+        stationInfo.SetFrontBackStripsGeometry(
+          (fscal) muchInterface->GetStripsStereoAngleFront(iSt), (fscal) muchInterface->GetStripsSpatialRmsFront(iSt),
+          (fscal) muchInterface->GetStripsStereoAngleBack(iSt), (fscal) muchInterface->GetStripsSpatialRmsBack(iSt));
+        stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
+        fInitManager.AddStation(stationInfo);
+        LOG(info) << "- MuCh station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
+      }
     }
-  }
 
-  /*** TRD stations info ***/
-  if (fUseTRD) {
-    for (int iSt = 0; iSt < fNTrdStationsGeom; ++iSt) {
-      auto stationInfo = L1BaseStationInfo(L1DetectorID::kTrd, iSt);
-      stationInfo.SetStationType((iSt == 1 || iSt == 3) ? 6 : 3);  // MuCh
-      stationInfo.SetTimeInfo(trdInterface->IsTimeInfoProvided(iSt));
-      stationInfo.SetTimeResolution(trdInterface->GetTimeResolution(iSt));
-      stationInfo.SetFieldStatus(0);
-      stationInfo.SetZ(trdInterface->GetZ(iSt));
-      stationInfo.SetXmax(trdInterface->GetXmax(iSt));
-      stationInfo.SetYmax(trdInterface->GetYmax(iSt));
-      stationInfo.SetRmin(trdInterface->GetRmin(iSt));
-      stationInfo.SetRmax(trdInterface->GetRmax(iSt));
-      stationInfo.SetMaterialSimple(trdInterface->GetThickness(iSt), trdInterface->GetRadLength(iSt));
-      stationInfo.SetMaterialMap(std::move(materialTableTrd[iSt]), correctionTrd);
-      fscal trdFrontPhi   = trdInterface->GetStripsStereoAngleFront(iSt);
-      fscal trdBackPhi    = trdInterface->GetStripsStereoAngleBack(iSt);
-      fscal trdFrontSigma = trdInterface->GetStripsSpatialRmsFront(iSt);
-      fscal trdBackSigma  = trdInterface->GetStripsSpatialRmsBack(iSt);
-      if (L1Algo::TrackingMode::kGlobal == fTrackingMode) {  //SGtrd2D!!
-        trdFrontSigma = .1;
-        trdBackSigma  = .1;
-        // stationInfo.SetTimeResolution(1.e10);
-        stationInfo.SetTimeInfo(false);
+    // *** TRD stations info ***
+    if (fUseTRD) {
+      for (int iSt = 0; iSt < fNTrdStationsGeom; ++iSt) {
+        auto stationInfo = L1BaseStationInfo(L1DetectorID::kTrd, iSt);
+        stationInfo.SetStationType((iSt == 1 || iSt == 3) ? 6 : 3);  // MuCh
+        stationInfo.SetTimeInfo(trdInterface->IsTimeInfoProvided(iSt));
+        stationInfo.SetTimeResolution(trdInterface->GetTimeResolution(iSt));
+        stationInfo.SetFieldStatus(0);
+        stationInfo.SetZ(trdInterface->GetZ(iSt));
+        stationInfo.SetXmax(trdInterface->GetXmax(iSt));
+        stationInfo.SetYmax(trdInterface->GetYmax(iSt));
+        stationInfo.SetRmin(trdInterface->GetRmin(iSt));
+        stationInfo.SetRmax(trdInterface->GetRmax(iSt));
+        stationInfo.SetMaterialSimple(trdInterface->GetThickness(iSt), trdInterface->GetRadLength(iSt));
+        stationInfo.SetMaterialMap(std::move(materialTableTrd[iSt]), correctionTrd);
+        fscal trdFrontPhi   = trdInterface->GetStripsStereoAngleFront(iSt);
+        fscal trdBackPhi    = trdInterface->GetStripsStereoAngleBack(iSt);
+        fscal trdFrontSigma = trdInterface->GetStripsSpatialRmsFront(iSt);
+        fscal trdBackSigma  = trdInterface->GetStripsSpatialRmsBack(iSt);
+        if (L1Algo::TrackingMode::kGlobal == fTrackingMode) {  //SGtrd2D!!
+          trdFrontSigma = .1;
+          trdBackSigma  = .1;
+          // stationInfo.SetTimeResolution(1.e10);
+          stationInfo.SetTimeInfo(false);
+        }
+        stationInfo.SetFrontBackStripsGeometry(trdFrontPhi, trdFrontSigma, trdBackPhi, trdBackSigma);
+        stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
+        if (iSt == 1 && L1Algo::TrackingMode::kMcbm == fTrackingMode && fMissingHits) {
+          stationInfo.SetTrackingStatus(false);
+        }
+        fInitManager.AddStation(stationInfo);
+        LOG(info) << "- TRD station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
       }
-      stationInfo.SetFrontBackStripsGeometry(trdFrontPhi, trdFrontSigma, trdBackPhi, trdBackSigma);
-      stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
-      if (iSt == 1 && L1Algo::TrackingMode::kMcbm == fTrackingMode && fMissingHits) {
-        stationInfo.SetTrackingStatus(false);
+    }
+
+    // *** TOF stations info ***
+    if (fUseTOF) {
+      for (int iSt = 0; iSt < fNTofStationsGeom; ++iSt) {
+        auto stationInfo = L1BaseStationInfo(L1DetectorID::kTof, iSt);
+        stationInfo.SetStationType(4);
+        stationInfo.SetTimeInfo(tofInterface->IsTimeInfoProvided(iSt));
+        stationInfo.SetTimeResolution(tofInterface->GetTimeResolution(iSt));
+        stationInfo.SetFieldStatus(0);
+        stationInfo.SetZ(tofInterface->GetZ(iSt));
+        auto thickness = tofInterface->GetThickness(iSt);
+        auto radLength = tofInterface->GetRadLength(iSt);
+        stationInfo.SetMaterialSimple(thickness, radLength);
+        stationInfo.SetMaterialMap(std::move(materialTableTof[iSt]), correctionTof);
+        stationInfo.SetXmax(tofInterface->GetXmax(iSt));
+        stationInfo.SetYmax(tofInterface->GetYmax(iSt));
+        stationInfo.SetRmin(tofInterface->GetRmin(iSt));
+        stationInfo.SetRmax(tofInterface->GetRmax(iSt));
+        fscal tofFrontPhi   = tofInterface->GetStripsStereoAngleFront(iSt);
+        fscal tofBackPhi    = tofInterface->GetStripsStereoAngleBack(iSt);
+        fscal tofFrontSigma = tofInterface->GetStripsSpatialRmsFront(iSt);
+        fscal tofBackSigma  = tofInterface->GetStripsSpatialRmsBack(iSt);
+        stationInfo.SetFrontBackStripsGeometry(tofFrontPhi, tofFrontSigma, tofBackPhi, tofBackSigma);
+        stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
+        fInitManager.AddStation(stationInfo);
+        LOG(info) << "- TOF station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
       }
-      fInitManager.AddStation(stationInfo);
-      LOG(info) << "- TRD station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
     }
-  }
 
-  /*** TOF stations info ***/
-  if (fUseTOF) {
-    for (int iSt = 0; iSt < fNTofStationsGeom; ++iSt) {
-      auto stationInfo = L1BaseStationInfo(L1DetectorID::kTof, iSt);
-      stationInfo.SetStationType(4);
-      stationInfo.SetTimeInfo(tofInterface->IsTimeInfoProvided(iSt));
-      stationInfo.SetTimeResolution(tofInterface->GetTimeResolution(iSt));
-      stationInfo.SetFieldStatus(0);
-      stationInfo.SetZ(tofInterface->GetZ(iSt));
-      auto thickness = tofInterface->GetThickness(iSt);
-      auto radLength = tofInterface->GetRadLength(iSt);
-      stationInfo.SetMaterialSimple(thickness, radLength);
-      stationInfo.SetMaterialMap(std::move(materialTableTof[iSt]), correctionTof);
-      stationInfo.SetXmax(tofInterface->GetXmax(iSt));
-      stationInfo.SetYmax(tofInterface->GetYmax(iSt));
-      stationInfo.SetRmin(tofInterface->GetRmin(iSt));
-      stationInfo.SetRmax(tofInterface->GetRmax(iSt));
-      fscal tofFrontPhi   = tofInterface->GetStripsStereoAngleFront(iSt);
-      fscal tofBackPhi    = tofInterface->GetStripsStereoAngleBack(iSt);
-      fscal tofFrontSigma = tofInterface->GetStripsSpatialRmsFront(iSt);
-      fscal tofBackSigma  = tofInterface->GetStripsSpatialRmsBack(iSt);
-      stationInfo.SetFrontBackStripsGeometry(tofFrontPhi, tofFrontSigma, tofBackPhi, tofBackSigma);
-      stationInfo.SetTrackingStatus(target.z < stationInfo.GetZdouble() ? true : false);
-      fInitManager.AddStation(stationInfo);
-      LOG(info) << "- TOF station " << iSt << " at z = " << stationInfo.GetZdouble() << " cm";
+    // ****************************************
+    // **                                    **
+    // ** TRACKING ITERATIONS INITIALIZATION **
+    // **                                    **
+    // ****************************************
+
+    // TODO: Need to provide a selection: default iterations input (these hard-coded ones), input from file or input
+    //       from running macro (S.Zharko)
+    auto trackingIterFastPrim = L1CAIteration("FastPrimIter");
+    trackingIterFastPrim.SetTrackChi2Cut(10.f);
+    trackingIterFastPrim.SetTripletChi2Cut(23.4450f);  // = 7.815 * 3;  // prob = 0.05
+    trackingIterFastPrim.SetDoubletChi2Cut(7.56327f);  // = 1.3449 * 2.f / 3.f;  // prob = 0.1
+    trackingIterFastPrim.SetPickGather(3.0f);
+    trackingIterFastPrim.SetPickNeighbour(5.0f);
+    trackingIterFastPrim.SetMaxInvMom(1.0 / 0.5);
+    trackingIterFastPrim.SetMaxSlopePV(1.1f);
+    trackingIterFastPrim.SetMaxSlope(2.748f);
+    trackingIterFastPrim.SetMaxDZ(0);
+    trackingIterFastPrim.SetTargetPosSigmaXY(1, 1);
+    trackingIterFastPrim.SetMinLevelTripletStart(0);
+    trackingIterFastPrim.SetPrimaryFlag(true);
+
+    auto trackingIterAllPrim = L1CAIteration("AllPrimIter");
+    trackingIterAllPrim.SetTrackChi2Cut(10.f);
+    trackingIterAllPrim.SetTripletChi2Cut(23.4450f);
+    trackingIterAllPrim.SetDoubletChi2Cut(7.56327f);
+    trackingIterAllPrim.SetPickGather(4.0f);
+    trackingIterAllPrim.SetPickNeighbour(5.0f);
+    trackingIterAllPrim.SetMaxInvMom(1.0 / 0.05);
+    trackingIterAllPrim.SetMaxSlopePV(1.1f);
+    trackingIterAllPrim.SetMaxSlope(2.748f);
+    trackingIterAllPrim.SetMaxDZ(0.1);
+    trackingIterAllPrim.SetTargetPosSigmaXY(1, 1);
+    trackingIterAllPrim.SetMinLevelTripletStart(0);
+    trackingIterAllPrim.SetPrimaryFlag(true);
+
+    auto trackingIterFastPrim2 = L1CAIteration("FastPrim2Iter");
+    trackingIterFastPrim2.SetTrackChi2Cut(10.f);
+    trackingIterFastPrim2.SetTripletChi2Cut(21.1075f);
+    trackingIterFastPrim2.SetDoubletChi2Cut(7.56327f);
+    trackingIterFastPrim2.SetPickGather(3.0f);
+    trackingIterFastPrim2.SetPickNeighbour(5.0f);
+    trackingIterFastPrim2.SetMaxInvMom(1.0 / 0.5);
+    trackingIterFastPrim2.SetMaxSlopePV(1.1f);
+    trackingIterFastPrim2.SetMaxSlope(2.748f);
+    trackingIterFastPrim2.SetMaxDZ(0);
+    trackingIterFastPrim2.SetTargetPosSigmaXY(5, 5);
+    trackingIterFastPrim2.SetMinLevelTripletStart(0);
+    trackingIterFastPrim2.SetPrimaryFlag(true);
+
+    auto trackingIterAllSec = L1CAIteration("AllSecIter");
+    trackingIterAllSec.SetTrackChi2Cut(10.f);
+    trackingIterAllSec.SetTripletChi2Cut(18.7560f);  // = 6.252 * 3;  // prob = 0.1
+    trackingIterAllSec.SetDoubletChi2Cut(7.56327f);
+    trackingIterAllSec.SetPickGather(4.0f);
+    trackingIterAllSec.SetPickNeighbour(5.0f);
+    trackingIterAllSec.SetMaxInvMom(1.0 / 0.1);
+    trackingIterAllSec.SetMaxSlopePV(1.5f);
+    trackingIterAllSec.SetMaxSlope(2.748f);
+    trackingIterAllSec.SetMaxDZ(0.1);
+    trackingIterAllSec.SetTargetPosSigmaXY(10, 10);
+    trackingIterAllSec.SetMinLevelTripletStart(1);
+    trackingIterAllSec.SetPrimaryFlag(false);
+
+    auto trackingIterFastPrimJump = L1CAIteration("FastPrimJumpIter");
+    trackingIterFastPrimJump.SetTrackChi2Cut(10.f);
+    trackingIterFastPrimJump.SetTripletChi2Cut(21.1075f);  // prob = 0.01
+    trackingIterFastPrimJump.SetDoubletChi2Cut(7.56327f);
+    trackingIterFastPrimJump.SetPickGather(3.0f);
+    trackingIterFastPrimJump.SetPickNeighbour(5.0f);
+    trackingIterFastPrimJump.SetMaxInvMom(1.0 / 0.5);
+    trackingIterFastPrimJump.SetMaxSlopePV(1.1f);
+    trackingIterFastPrimJump.SetMaxSlope(2.748f);
+    trackingIterFastPrimJump.SetMaxDZ(0);
+    trackingIterFastPrimJump.SetTargetPosSigmaXY(5, 5);
+    trackingIterFastPrimJump.SetMinLevelTripletStart(0);
+    trackingIterFastPrimJump.SetPrimaryFlag(true);
+
+    auto trackingIterAllPrimJump = L1CAIteration("AllPrimJumpIter");
+    trackingIterAllPrimJump.SetTrackChi2Cut(10.f);
+    trackingIterAllPrimJump.SetTripletChi2Cut(18.7560f);
+    trackingIterAllPrimJump.SetDoubletChi2Cut(7.56327f);
+    trackingIterAllPrimJump.SetPickGather(4.0f);
+    trackingIterAllPrimJump.SetPickNeighbour(5.0f);
+    trackingIterAllPrimJump.SetMaxInvMom(1.0 / 0.1);
+    trackingIterAllPrimJump.SetMaxSlopePV(1.1f);
+    trackingIterAllPrimJump.SetMaxSlope(2.748f);
+    trackingIterAllPrimJump.SetMaxDZ(0.1);
+    trackingIterAllPrimJump.SetTargetPosSigmaXY(5, 5);
+    trackingIterAllPrimJump.SetMinLevelTripletStart(0);
+    trackingIterAllPrimJump.SetPrimaryFlag(true);
+
+    auto trackingIterAllSecJump = L1CAIteration("AllSecJumpIter");
+    trackingIterAllSecJump.SetTrackChi2Cut(10.f);
+    trackingIterAllSecJump.SetTripletChi2Cut(21.1075f);
+    trackingIterAllSecJump.SetDoubletChi2Cut(7.56327f);
+    trackingIterAllSecJump.SetPickGather(4.0f);
+    trackingIterAllSecJump.SetPickNeighbour(5.0f);
+    trackingIterAllSecJump.SetMaxInvMom(1.0 / 0.1);
+    trackingIterAllSecJump.SetMaxSlopePV(1.5f);
+    trackingIterAllSecJump.SetMaxSlope(2.748f);
+    trackingIterAllSecJump.SetMaxDZ(0.1);
+    trackingIterAllSecJump.SetMinLevelTripletStart(1);
+    trackingIterAllSecJump.SetTargetPosSigmaXY(10, 10);
+
+    auto trackingIterAllPrimE = L1CAIteration("AllPrimEIter");
+    trackingIterAllPrimE.SetTrackChi2Cut(10.f);
+    trackingIterAllPrimE.SetTripletChi2Cut(23.4450f);
+    trackingIterAllPrimE.SetDoubletChi2Cut(7.56327f);
+    trackingIterAllPrimE.SetPickGather(4.0f);
+    trackingIterAllPrimE.SetPickNeighbour(5.0f);
+    trackingIterAllPrimE.SetMaxInvMom(1.0 / 0.05);
+    trackingIterAllPrimE.SetMaxSlopePV(1.1f);
+    trackingIterAllPrimE.SetMaxSlope(2.748f);
+    trackingIterAllPrimE.SetMaxDZ(0.1);
+    trackingIterAllPrimE.SetTargetPosSigmaXY(1, 1);
+    trackingIterAllPrimE.SetMinLevelTripletStart(0);
+    trackingIterAllPrimE.SetPrimaryFlag(true);
+    trackingIterAllPrimE.SetElectronFlag(true);
+
+    auto trackingIterAllSecE = L1CAIteration("AllSecEIter");
+    trackingIterAllSecE.SetTrackChi2Cut(10.f);
+    trackingIterAllSecE.SetTripletChi2Cut(18.7560f);
+    trackingIterAllSecE.SetDoubletChi2Cut(7.56327f);
+    trackingIterAllSecE.SetPickGather(4.0f);
+    trackingIterAllSecE.SetPickNeighbour(5.0f);
+    trackingIterAllSecE.SetMaxInvMom(1.0 / 0.05);
+    trackingIterAllSecE.SetMaxSlopePV(1.5f);
+    trackingIterAllSecE.SetMaxSlope(2.748f);
+    trackingIterAllSecE.SetMaxDZ(0.1);
+    trackingIterAllSecE.SetMinLevelTripletStart(1);
+    trackingIterAllSecE.SetTargetPosSigmaXY(10, 10);
+    trackingIterAllSecE.SetElectronFlag(true);
+
+    // Select default track finder
+    if (L1Algo::TrackingMode::kMcbm == fTrackingMode) {
+      trackingIterAllPrim.SetMaxInvMom(1. / 0.1);
+      trackingIterAllPrimE.SetMaxInvMom(1. / 0.1);
+      trackingIterAllSecE.SetMaxInvMom(1. / 0.1);
+
+      trackingIterFastPrim.SetMaxInvMom(1.0 / 0.3);
+      trackingIterAllSec.SetMaxInvMom(1.0 / 0.3);
+      trackingIterFastPrimJump.SetMaxInvMom(1.0 / 0.3);
+      trackingIterAllPrimJump.SetMaxInvMom(1.0 / 0.3);
+      trackingIterAllSecJump.SetMaxInvMom(1.0 / 0.3);
+
+      fInitManager.SetCAIterationsNumberCrosscheck(4);
+      // Initialize CA track finder iterations sequence
+      fInitManager.PushBackCAIteration(trackingIterFastPrim);
+      fInitManager.PushBackCAIteration(trackingIterAllPrim);
+      fInitManager.PushBackCAIteration(trackingIterAllPrimJump);
+      fInitManager.PushBackCAIteration(trackingIterAllSec);
+    }
+    else if (L1Algo::TrackingMode::kGlobal == fTrackingMode) {
+      // SGtrd2d!!
+
+      // Initialize CA track finder iterations sequence
+
+      auto trd2dIter1 = L1CAIteration("Trd2dIter1");
+      trd2dIter1.SetTrackChi2Cut(7.f);              //10.f
+      trd2dIter1.SetTripletChi2Cut(2 * 23.4450f);   // = 7.815 * 3;  // prob = 0.05
+      trd2dIter1.SetDoubletChi2Cut(4. * 7.56327f);  // = 1.3449 * 2.f / 3.f;  // prob = 0.1
+      trd2dIter1.SetPickGather(3.0f);
+      trd2dIter1.SetPickNeighbour(4.0f);
+      trd2dIter1.SetMaxInvMom(1.0 / 0.05);  //(1.0 / 0.5);
+      trd2dIter1.SetMaxSlopePV(.5f);
+      trd2dIter1.SetMaxSlope(.5f);
+      trd2dIter1.SetMaxDZ(0.05);
+      trd2dIter1.SetTargetPosSigmaXY(1., 1.);  //(1, 1);
+      trd2dIter1.SetMinLevelTripletStart(1);
+      trd2dIter1.SetPrimaryFlag(false);
+
+      auto trd2dIter2 = L1CAIteration("Trd2dIter2");
+      trd2dIter2.SetTrackChi2Cut(7.f);              //10.f
+      trd2dIter2.SetTripletChi2Cut(2 * 23.4450f);   // = 7.815 * 3;  // prob = 0.05
+      trd2dIter2.SetDoubletChi2Cut(4. * 7.56327f);  // = 1.3449 * 2.f / 3.f;  // prob = 0.1
+      trd2dIter2.SetPickGather(3.0f);
+      trd2dIter2.SetPickNeighbour(4.0f);
+      trd2dIter2.SetMaxInvMom(1.0 / 0.05);  //(1.0 / 0.5);
+      trd2dIter2.SetMaxSlopePV(.5f);
+      trd2dIter2.SetMaxSlope(.5f);
+      trd2dIter2.SetMaxDZ(0.05);
+      trd2dIter2.SetTargetPosSigmaXY(8 * 10, 6 * 10);  //(1, 1);
+      trd2dIter2.SetMinLevelTripletStart(0);
+      trd2dIter2.SetPrimaryFlag(false);
+
+      // Initialize CA track finder iterations sequence
+
+      fInitManager.SetCAIterationsNumberCrosscheck(1);
+      /*
+      fInitManager.SetCAIterationsNumberCrosscheck(5);
+      fInitManager.PushBackCAIteration(trackingIterFastPrim);
+      fInitManager.PushBackCAIteration(trackingIterAllPrim);
+      fInitManager.PushBackCAIteration(trackingIterAllPrimJump);
+      fInitManager.PushBackCAIteration(trackingIterAllSec);
+       */
+      fInitManager.PushBackCAIteration(trd2dIter2);
+    }
+    else {
+      fInitManager.SetCAIterationsNumberCrosscheck(4);
+      // Initialize CA track finder iterations sequence
+      fInitManager.PushBackCAIteration(trackingIterFastPrim);
+      fInitManager.PushBackCAIteration(trackingIterAllPrim);
+      fInitManager.PushBackCAIteration(trackingIterAllPrimJump);
+      fInitManager.PushBackCAIteration(trackingIterAllSec);
+      //fInitManager.PushBackCAIteration(trackingIterAllPrimE);
+      //fInitManager.PushBackCAIteration(trackingIterAllSecE);
+      //fInitManager.PushBackCAIteration(trackingIterFastPrimJump);
+      //fInitManager.PushBackCAIteration(trackingIterFastPrim2);
+      //fInitManager.PushBackCAIteration(trackingIterAllSecJump);
     }
-  }
 
-  /****************************************
-   **                                    **
-   ** TRACKING ITERATIONS INITIALIZATION **
-   **                                    **
-   ****************************************/
-
-  // TODO: Need to provide a selection: default iterations input (these hard-coded ones), input from file or input
-  //       from running macro (S.Zharko)
-  auto trackingIterFastPrim = L1CAIteration("FastPrimIter");
-  trackingIterFastPrim.SetTrackChi2Cut(10.f);
-  trackingIterFastPrim.SetTripletChi2Cut(23.4450f);  // = 7.815 * 3;  // prob = 0.05
-  trackingIterFastPrim.SetDoubletChi2Cut(7.56327f);  // = 1.3449 * 2.f / 3.f;  // prob = 0.1
-  trackingIterFastPrim.SetPickGather(3.0f);
-  trackingIterFastPrim.SetPickNeighbour(5.0f);
-  trackingIterFastPrim.SetMaxInvMom(1.0 / 0.5);
-  trackingIterFastPrim.SetMaxSlopePV(1.1f);
-  trackingIterFastPrim.SetMaxSlope(2.748f);
-  trackingIterFastPrim.SetMaxDZ(0);
-  trackingIterFastPrim.SetTargetPosSigmaXY(1, 1);
-  trackingIterFastPrim.SetMinLevelTripletStart(0);
-  trackingIterFastPrim.SetPrimaryFlag(true);
-
-  auto trackingIterAllPrim = L1CAIteration("AllPrimIter");
-  trackingIterAllPrim.SetTrackChi2Cut(10.f);
-  trackingIterAllPrim.SetTripletChi2Cut(23.4450f);
-  trackingIterAllPrim.SetDoubletChi2Cut(7.56327f);
-  trackingIterAllPrim.SetPickGather(4.0f);
-  trackingIterAllPrim.SetPickNeighbour(5.0f);
-  trackingIterAllPrim.SetMaxInvMom(1.0 / 0.05);
-  trackingIterAllPrim.SetMaxSlopePV(1.1f);
-  trackingIterAllPrim.SetMaxSlope(2.748f);
-  trackingIterAllPrim.SetMaxDZ(0.1);
-  trackingIterAllPrim.SetTargetPosSigmaXY(1, 1);
-  trackingIterAllPrim.SetMinLevelTripletStart(0);
-  trackingIterAllPrim.SetPrimaryFlag(true);
-
-  auto trackingIterFastPrim2 = L1CAIteration("FastPrim2Iter");
-  trackingIterFastPrim2.SetTrackChi2Cut(10.f);
-  trackingIterFastPrim2.SetTripletChi2Cut(21.1075f);
-  trackingIterFastPrim2.SetDoubletChi2Cut(7.56327f);
-  trackingIterFastPrim2.SetPickGather(3.0f);
-  trackingIterFastPrim2.SetPickNeighbour(5.0f);
-  trackingIterFastPrim2.SetMaxInvMom(1.0 / 0.5);
-  trackingIterFastPrim2.SetMaxSlopePV(1.1f);
-  trackingIterFastPrim2.SetMaxSlope(2.748f);
-  trackingIterFastPrim2.SetMaxDZ(0);
-  trackingIterFastPrim2.SetTargetPosSigmaXY(5, 5);
-  trackingIterFastPrim2.SetMinLevelTripletStart(0);
-  trackingIterFastPrim2.SetPrimaryFlag(true);
-
-  auto trackingIterAllSec = L1CAIteration("AllSecIter");
-  trackingIterAllSec.SetTrackChi2Cut(10.f);
-  trackingIterAllSec.SetTripletChi2Cut(18.7560f);  // = 6.252 * 3;  // prob = 0.1
-  trackingIterAllSec.SetDoubletChi2Cut(7.56327f);
-  trackingIterAllSec.SetPickGather(4.0f);
-  trackingIterAllSec.SetPickNeighbour(5.0f);
-  trackingIterAllSec.SetMaxInvMom(1.0 / 0.1);
-  trackingIterAllSec.SetMaxSlopePV(1.5f);
-  trackingIterAllSec.SetMaxSlope(2.748f);
-  trackingIterAllSec.SetMaxDZ(0.1);
-  trackingIterAllSec.SetTargetPosSigmaXY(10, 10);
-  trackingIterAllSec.SetMinLevelTripletStart(1);
-  trackingIterAllSec.SetPrimaryFlag(false);
-
-  auto trackingIterFastPrimJump = L1CAIteration("FastPrimJumpIter");
-  trackingIterFastPrimJump.SetTrackChi2Cut(10.f);
-  trackingIterFastPrimJump.SetTripletChi2Cut(21.1075f);  // prob = 0.01
-  trackingIterFastPrimJump.SetDoubletChi2Cut(7.56327f);
-  trackingIterFastPrimJump.SetPickGather(3.0f);
-  trackingIterFastPrimJump.SetPickNeighbour(5.0f);
-  trackingIterFastPrimJump.SetMaxInvMom(1.0 / 0.5);
-  trackingIterFastPrimJump.SetMaxSlopePV(1.1f);
-  trackingIterFastPrimJump.SetMaxSlope(2.748f);
-  trackingIterFastPrimJump.SetMaxDZ(0);
-  trackingIterFastPrimJump.SetTargetPosSigmaXY(5, 5);
-  trackingIterFastPrimJump.SetMinLevelTripletStart(0);
-  trackingIterFastPrimJump.SetPrimaryFlag(true);
-
-  auto trackingIterAllPrimJump = L1CAIteration("AllPrimJumpIter");
-  trackingIterAllPrimJump.SetTrackChi2Cut(10.f);
-  trackingIterAllPrimJump.SetTripletChi2Cut(18.7560f);
-  trackingIterAllPrimJump.SetDoubletChi2Cut(7.56327f);
-  trackingIterAllPrimJump.SetPickGather(4.0f);
-  trackingIterAllPrimJump.SetPickNeighbour(5.0f);
-  trackingIterAllPrimJump.SetMaxInvMom(1.0 / 0.1);
-  trackingIterAllPrimJump.SetMaxSlopePV(1.1f);
-  trackingIterAllPrimJump.SetMaxSlope(2.748f);
-  trackingIterAllPrimJump.SetMaxDZ(0.1);
-  trackingIterAllPrimJump.SetTargetPosSigmaXY(5, 5);
-  trackingIterAllPrimJump.SetMinLevelTripletStart(0);
-  trackingIterAllPrimJump.SetPrimaryFlag(true);
-
-  auto trackingIterAllSecJump = L1CAIteration("AllSecJumpIter");
-  trackingIterAllSecJump.SetTrackChi2Cut(10.f);
-  trackingIterAllSecJump.SetTripletChi2Cut(21.1075f);
-  trackingIterAllSecJump.SetDoubletChi2Cut(7.56327f);
-  trackingIterAllSecJump.SetPickGather(4.0f);
-  trackingIterAllSecJump.SetPickNeighbour(5.0f);
-  trackingIterAllSecJump.SetMaxInvMom(1.0 / 0.1);
-  trackingIterAllSecJump.SetMaxSlopePV(1.5f);
-  trackingIterAllSecJump.SetMaxSlope(2.748f);
-  trackingIterAllSecJump.SetMaxDZ(0.1);
-  trackingIterAllSecJump.SetMinLevelTripletStart(1);
-  trackingIterAllSecJump.SetTargetPosSigmaXY(10, 10);
-
-  auto trackingIterAllPrimE = L1CAIteration("AllPrimEIter");
-  trackingIterAllPrimE.SetTrackChi2Cut(10.f);
-  trackingIterAllPrimE.SetTripletChi2Cut(23.4450f);
-  trackingIterAllPrimE.SetDoubletChi2Cut(7.56327f);
-  trackingIterAllPrimE.SetPickGather(4.0f);
-  trackingIterAllPrimE.SetPickNeighbour(5.0f);
-  trackingIterAllPrimE.SetMaxInvMom(1.0 / 0.05);
-  trackingIterAllPrimE.SetMaxSlopePV(1.1f);
-  trackingIterAllPrimE.SetMaxSlope(2.748f);
-  trackingIterAllPrimE.SetMaxDZ(0.1);
-  trackingIterAllPrimE.SetTargetPosSigmaXY(1, 1);
-  trackingIterAllPrimE.SetMinLevelTripletStart(0);
-  trackingIterAllPrimE.SetPrimaryFlag(true);
-  trackingIterAllPrimE.SetElectronFlag(true);
-
-  auto trackingIterAllSecE = L1CAIteration("AllSecEIter");
-  trackingIterAllSecE.SetTrackChi2Cut(10.f);
-  trackingIterAllSecE.SetTripletChi2Cut(18.7560f);
-  trackingIterAllSecE.SetDoubletChi2Cut(7.56327f);
-  trackingIterAllSecE.SetPickGather(4.0f);
-  trackingIterAllSecE.SetPickNeighbour(5.0f);
-  trackingIterAllSecE.SetMaxInvMom(1.0 / 0.05);
-  trackingIterAllSecE.SetMaxSlopePV(1.5f);
-  trackingIterAllSecE.SetMaxSlope(2.748f);
-  trackingIterAllSecE.SetMaxDZ(0.1);
-  trackingIterAllSecE.SetMinLevelTripletStart(1);
-  trackingIterAllSecE.SetTargetPosSigmaXY(10, 10);
-  trackingIterAllSecE.SetElectronFlag(true);
-
-  // Select default track finder
-  if (L1Algo::TrackingMode::kMcbm == fTrackingMode) {
-    trackingIterAllPrim.SetMaxInvMom(1. / 0.1);
-    trackingIterAllPrimE.SetMaxInvMom(1. / 0.1);
-    trackingIterAllSecE.SetMaxInvMom(1. / 0.1);
-
-    trackingIterFastPrim.SetMaxInvMom(1.0 / 0.3);
-    trackingIterAllSec.SetMaxInvMom(1.0 / 0.3);
-    trackingIterFastPrimJump.SetMaxInvMom(1.0 / 0.3);
-    trackingIterAllPrimJump.SetMaxInvMom(1.0 / 0.3);
-    trackingIterAllSecJump.SetMaxInvMom(1.0 / 0.3);
-
-    fInitManager.SetCAIterationsNumberCrosscheck(4);
-    // Initialize CA track finder iterations sequence
-    fInitManager.PushBackCAIteration(trackingIterFastPrim);
-    fInitManager.PushBackCAIteration(trackingIterAllPrim);
-    fInitManager.PushBackCAIteration(trackingIterAllPrimJump);
-    fInitManager.PushBackCAIteration(trackingIterAllSec);
-  }
-  else if (L1Algo::TrackingMode::kGlobal == fTrackingMode) {
-    // SGtrd2d!!
-
-    // Initialize CA track finder iterations sequence
-
-    auto trd2dIter1 = L1CAIteration("Trd2dIter1");
-    trd2dIter1.SetTrackChi2Cut(7.f);              //10.f
-    trd2dIter1.SetTripletChi2Cut(2 * 23.4450f);   // = 7.815 * 3;  // prob = 0.05
-    trd2dIter1.SetDoubletChi2Cut(4. * 7.56327f);  // = 1.3449 * 2.f / 3.f;  // prob = 0.1
-    trd2dIter1.SetPickGather(3.0f);
-    trd2dIter1.SetPickNeighbour(4.0f);
-    trd2dIter1.SetMaxInvMom(1.0 / 0.05);  //(1.0 / 0.5);
-    trd2dIter1.SetMaxSlopePV(.5f);
-    trd2dIter1.SetMaxSlope(.5f);
-    trd2dIter1.SetMaxDZ(0.05);
-    trd2dIter1.SetTargetPosSigmaXY(1., 1.);  //(1, 1);
-    trd2dIter1.SetMinLevelTripletStart(1);
-    trd2dIter1.SetPrimaryFlag(false);
-
-    auto trd2dIter2 = L1CAIteration("Trd2dIter2");
-    trd2dIter2.SetTrackChi2Cut(7.f);              //10.f
-    trd2dIter2.SetTripletChi2Cut(2 * 23.4450f);   // = 7.815 * 3;  // prob = 0.05
-    trd2dIter2.SetDoubletChi2Cut(4. * 7.56327f);  // = 1.3449 * 2.f / 3.f;  // prob = 0.1
-    trd2dIter2.SetPickGather(3.0f);
-    trd2dIter2.SetPickNeighbour(4.0f);
-    trd2dIter2.SetMaxInvMom(1.0 / 0.05);  //(1.0 / 0.5);
-    trd2dIter2.SetMaxSlopePV(.5f);
-    trd2dIter2.SetMaxSlope(.5f);
-    trd2dIter2.SetMaxDZ(0.05);
-    trd2dIter2.SetTargetPosSigmaXY(8 * 10, 6 * 10);  //(1, 1);
-    trd2dIter2.SetMinLevelTripletStart(0);
-    trd2dIter2.SetPrimaryFlag(false);
-
-    // Initialize CA track finder iterations sequence
-
-    fInitManager.SetCAIterationsNumberCrosscheck(1);
-    /*
-    fInitManager.SetCAIterationsNumberCrosscheck(5);
-    fInitManager.PushBackCAIteration(trackingIterFastPrim);
-    fInitManager.PushBackCAIteration(trackingIterAllPrim);
-    fInitManager.PushBackCAIteration(trackingIterAllPrimJump);
-    fInitManager.PushBackCAIteration(trackingIterAllSec);
-     */
-    fInitManager.PushBackCAIteration(trd2dIter2);
-  }
-  else {
-    fInitManager.SetCAIterationsNumberCrosscheck(4);
-    // Initialize CA track finder iterations sequence
-    fInitManager.PushBackCAIteration(trackingIterFastPrim);
-    fInitManager.PushBackCAIteration(trackingIterAllPrim);
-    fInitManager.PushBackCAIteration(trackingIterAllPrimJump);
-    fInitManager.PushBackCAIteration(trackingIterAllSec);
-    //fInitManager.PushBackCAIteration(trackingIterAllPrimE);
-    //fInitManager.PushBackCAIteration(trackingIterAllSecE);
-    //fInitManager.PushBackCAIteration(trackingIterFastPrimJump);
-    //fInitManager.PushBackCAIteration(trackingIterFastPrim2);
-    //fInitManager.PushBackCAIteration(trackingIterAllSecJump);
-  }
+    // **********************
+    // ** Set special cuts **
+    // **********************
 
-  /**********************
-   ** Set special cuts **
-   **********************/
+    fInitManager.SetGhostSuppression(fGhostSuppression);
+    fInitManager.SetTrackingLevel(fTrackingLevel);
+    fInitManager.SetMomentumCutOff(fMomentumCutOff);
 
-  fInitManager.SetGhostSuppression(fGhostSuppression);
-  fInitManager.SetTrackingLevel(fTrackingLevel);
-  fInitManager.SetMomentumCutOff(fMomentumCutOff);
+    // Form parameters container
+    fInitManager.FormParametersContainer();
 
-  /*** Get numbers of active stations ***/
+    // Write to file if needed
+    if (1 == fSTAPDataMode) { this->WriteSTAPParamObject(); }
+  }
 
-  fNMvdStations  = fInitManager.GetNstationsActive(L1DetectorID::kMvd);
-  fNStsStations  = fInitManager.GetNstationsActive(L1DetectorID::kSts);
-  fNTrdStations  = fInitManager.GetNstationsActive(L1DetectorID::kTrd);
-  fNMuchStations = fInitManager.GetNstationsActive(L1DetectorID::kMuch);
-  fNTofStations  = fInitManager.GetNstationsActive(L1DetectorID::kTof);
-  fNStations     = fInitManager.GetNstationsActive();
+  //
+  // ** Send formed parameters object to L1Algo instance **
+  //
+  fInitManager.SendParameters(fpAlgo);
 
+  /*** Get numbers of active stations ***/
+
+  fNMvdStations  = fpAlgo->GetParameters()->GetNstationsActive(L1DetectorID::kMvd);
+  fNStsStations  = fpAlgo->GetParameters()->GetNstationsActive(L1DetectorID::kSts);
+  fNTrdStations  = fpAlgo->GetParameters()->GetNstationsActive(L1DetectorID::kTrd);
+  fNMuchStations = fpAlgo->GetParameters()->GetNstationsActive(L1DetectorID::kMuch);
+  fNTofStations  = fpAlgo->GetParameters()->GetNstationsActive(L1DetectorID::kTof);
+  fNStations     = fpAlgo->GetParameters()->GetNstationsActive();
 
-  // Send formed parameters object to L1Algo instance
-  fInitManager.SendParameters(fpAlgo);
 
   LOG(info) << "----- Numbers of stations active in tracking -----";
   LOG(info) << "  MVD:    " << fNMvdStations;
@@ -1276,101 +1301,99 @@ void CbmL1::IdealTrackFinder()
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void CbmL1::WriteSTAPGeoData(const L1Vector<float>& /*geo_*/)
+void CbmL1::DefineSTAPNames(TString dirName)
 {
-  LOG(fatal) << "CbmL1: Running in standalone mode is not available at the moment. It will be updated soon...";
-}
+  namespace bfs = boost::filesystem;
 
-// ---------------------------------------------------------------------------------------------------------------------
-//
-void CbmL1::WriteAlgoInputData()  // must be called after ReadEvent
-{
-  // Check if output directory exists
-  if (!boost::filesystem::exists(fSTAPDataDir.Data())) {
-    LOG(warn) << "CbmL1: directory " << fSTAPDataDir.Data()
-              << " (full path: " << boost::filesystem::system_complete(fSTAPDataDir.Data()).string()
+  // Check, if dirName path exists
+  if (!bfs::exists(dirName.Data())) {
+    LOG(warn) << "CbmL1: directory " << dirName.Data()
+              << " (full path: " << bfs::system_complete(dirName.Data()).string()
               << ") for writing L1AlgoData object does not exist";
     fSTAPDataDir = ".";
   }
 
-  if (!boost::filesystem::is_directory(fSTAPDataDir.Data())) {
+  // Check, if dirName path is a directory
+  if (!bfs::is_directory(fSTAPDataDir.Data())) {
     LOG(warn) << "CbmL1: path " << fSTAPDataDir.Data()
-              << " (full path: " << boost::filesystem::system_complete(fSTAPDataDir.Data()).string()
-              << ") is not a directory";
+              << " (full path: " << bfs::system_complete(fSTAPDataDir.Data()).string() << ") is not a directory";
     fSTAPDataDir = ".";
   }
 
-  // Define output directory
-  std::string hitsDir = (fSTAPDataDir + "/tracking_input_hits").Data();
-  if (!boost::filesystem::exists(hitsDir)) { boost::filesystem::create_directories(hitsDir); }
+  // TODO: Prepare directory, if it is not defined?
+  //
+  LOG(info) << "CbmL1: STAP data root directory is \033[1;32m" << bfs::system_complete(fSTAPDataDir.Data())
+            << "\033[0m";
 
-  // Get filename
-  static int iEvent         = 0;
-  boost::filesystem::path p = (FairRunAna::Instance()->GetUserOutputFileName()).Data();
-  std::string prefix        = p.filename().string();
-  std::string suffix        = "reco.root";
-  prefix.erase(prefix.find("reco.root"));
-  std::string filename = hitsDir + "/" + prefix + "event" + std::to_string(iEvent) + ".L1InputData.dat";
-  ++iEvent;
+  // Output prefix definition
+  bfs::path pathToOutput = FairRunAna::Instance()->GetUserOutputFileName().Data();
+  fSTAPDataPrefix        = pathToOutput.filename().string();
+  TString sOutputSuffix  = ".reco.root";
+  {
+    int suffixIdx = fSTAPDataPrefix.Index(sOutputSuffix);
+    if (suffixIdx != -1) { fSTAPDataPrefix.Remove(suffixIdx, sOutputSuffix.Length()); }
+  }
+  // Leave prefix without points on the edges, if there are any
+  fSTAPDataPrefix = fSTAPDataPrefix.Strip(TString::EStripType::kBoth, '.');
+
+  // Directory for handling L1InputData objects
+  TString sInputDataDir = fSTAPDataDir + "/" + TString(kSTAPAlgoIDataDir.data());
+  if (!bfs::exists(sInputDataDir.Data())) {
+    LOG(warn) << "CbmL1: directory for tracking input data does not exist. It will be created";
+    bfs::create_directories(sInputDataDir.Data());
+  }
+  LOG(info) << "CbmL1: STAP tracking input jobs directory is \033[1;32m" << bfs::system_complete(sInputDataDir.Data())
+            << "\033[0m";
+}
 
-  // Write file
-  L1_SHOW(filename);
-  fIODataManager.WriteInputData(filename);
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void CbmL1::WriteSTAPParamObject()
+{
+  TString filename = fSTAPDataDir + "/" + fSTAPDataPrefix + "." + TString(kSTAPParamSuffix.data());
+  fInitManager.WriteParametersObject(filename.Data());
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void CbmL1::WriteSTAPPerfData()  // must be called after ReadEvent
+void CbmL1::WriteSTAPAlgoInputData(int iJob)  // must be called after ReadEvent
 {
-  LOG(fatal) << "CbmL1: Running in standalone mode is not available at the moment. It will be updated soon...";
+  TString filename = fSTAPDataDir + "/" + TString(kSTAPAlgoIDataDir.data()) + "/" + fSTAPDataPrefix + "."
+                     + TString::Format(kSTAPAlgoIDataSuffix.data(), iJob);
+
+  // Write file
+  fIODataManager.WriteInputData(filename.Data());
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void CbmL1::ReadSTAPGeoData()
+void CbmL1::WriteSTAPPerfInputData()  // must be called after ReadEvent
 {
   LOG(fatal) << "CbmL1: Running in standalone mode is not available at the moment. It will be updated soon...";
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void CbmL1::ReadAlgoInputData()
+void CbmL1::ReadSTAPParamObject()
 {
-  // Check if output directory exists
-  if (!boost::filesystem::exists(fSTAPDataDir.Data())) {
-    LOG(warn) << "CbmL1: directory " << fSTAPDataDir.Data()
-              << " (full path: " << boost::filesystem::system_complete(fSTAPDataDir.Data()).string()
-              << ") for reading L1AlgoData object does not exist";
-    fSTAPDataDir = ".";
-  }
-
-  if (!boost::filesystem::is_directory(fSTAPDataDir.Data())) {
-    LOG(warn) << "CbmL1: path " << fSTAPDataDir.Data()
-              << " (full path: " << boost::filesystem::system_complete(fSTAPDataDir.Data()).string()
-              << ") is not a directory";
-    fSTAPDataDir = ".";
-  }
-
-  // Define output directory
-  std::string hitsDir = fSTAPDataDir.Data();
+  TString filename = fSTAPDataDir + "/" + fSTAPDataPrefix + "." + TString(kSTAPParamSuffix.data());
+  fInitManager.ReadParametersObject(filename.Data());
+}
 
-  // Get filename
-  static int iEvent         = 0;
-  boost::filesystem::path p = (FairRunAna::Instance()->GetUserOutputFileName()).Data();
-  std::string prefix        = p.filename().string();
-  std::string suffix        = "reco.root";
-  prefix.erase(prefix.find("reco.root"));
-  std::string filename = hitsDir + "/" + prefix + "event" + std::to_string(iEvent) + ".L1InputData.dat";
-  ++iEvent;
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void CbmL1::ReadSTAPAlgoInputData(int iJob)
+{
+  TString filename = fSTAPDataDir + "/" + TString(kSTAPAlgoIDataDir) + "/" + fSTAPDataPrefix + "."
+                     + TString::Format(kSTAPAlgoIDataSuffix.data(), iJob);
 
-  // Write file
-  L1_SHOW(filename);
-  fIODataManager.ReadInputData(filename);
+  // Read file
+  fIODataManager.ReadInputData(filename.Data());
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void CbmL1::ReadSTAPPerfData()
+void CbmL1::ReadSTAPPerfInputData()
 {
   LOG(fatal) << "CbmL1: Running in standalone mode is not available at the moment. It will be updated soon...";
 }
diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h
index db153bfec3..77d56c58e8 100644
--- a/reco/L1/CbmL1.h
+++ b/reco/L1/CbmL1.h
@@ -46,6 +46,7 @@
 #include <iostream>
 #include <map>
 #include <set>
+#include <string_view>
 #include <utility>
 
 #include "L1Algo/L1Algo.h"
@@ -358,14 +359,36 @@ private:
   void TrackFitPerformance();      // pulls & residuals. Can be called only after Performance()
   void HistoPerformance();         // fill some histograms and calculate efficiencies
 
-  /// STandAlone Package service-functions
-  void WriteSTAPGeoData(const L1Vector<float>& geo);  // create geo_algo.dat
-  void WriteAlgoInputData();                          // create data_algo.dat
-  void WriteSTAPPerfData();                           // create data_perfo.dat
-  //void ReadSTAPGeoData(L1Vector<float> geo, int &size);
-  void ReadSTAPGeoData();
-  void ReadAlgoInputData();
-  void ReadSTAPPerfData();
+  // ** STandAlone Package service-functions **
+
+  /// Defines the name of input/output directory [dir] and prefix of the files [pref], which is used to define
+  /// input and output data trees in the reconstruction macro. If the output TTree file has name
+  /// /path/to/[pref].reco.root, the data files will be:
+  ///   [dir]/input_hits/[pref].job[No].L1InputData.dat - hits input files, containing serialized L1InputData objects,
+  ///     stored for each job (each call of CbmL1::ReadEvent function)
+  ///   [dir]/[pref].L1Parameters.dat - parameters input files, containing serialized L1Parameters object
+  ///
+  void DefineSTAPNames(TString dirName);
+
+  /// Writes initialized L1Parameters object to file ""
+  void WriteSTAPParamObject();
+
+  /// Writes a sample of an L1InputData object to defined directory fSTAPDataDir
+  /// \param iJob  Number of job, usually is defined by the nCalls of executing function
+  /// \note  Creates a file fSTAPDataDir + "/" + fSTAPDataPrefix + "." + TString::Format(kSTAPAlgoIDataSuffix, iJob)
+  void WriteSTAPAlgoInputData(int iJob = 0);
+
+  void WriteSTAPPerfInputData();
+
+  /// Reads a sample of an L1InputData object from defined directory fSTAPDataDir
+  /// \param iJob  Number of job, usually is defined by the nCalls of executing function
+  /// \note  Reads from a file fSTAPDataDir + "/" + fSTAPDataPrefix + "." + TString::Format(kSTAPAlgoIDataSuffix, iJob)
+  void ReadSTAPParamObject();
+
+  void ReadSTAPAlgoInputData(int iJob = 0);
+
+  void ReadSTAPPerfInputData();
+
   /// SIMD KF Banchmark service-functions
   void WriteSIMDKFData();
 
@@ -442,7 +465,23 @@ private:
   /// 0 (off) , 1 (write), 2 (read data and work only with it), 3 (debug - write and read)
   int fSTAPDataMode = 0;
 
-  TString fSTAPDataDir {};
+  TString fSTAPDataDir    = ".";     ///< Name of input/output directory for running in a STAP mode
+  TString fSTAPDataPrefix = "test";  ///< Name of input/output file prefix. The prefix is defined by output TTree file
+
+  /// Extension for IO of the L1Parameters object
+  static constexpr std::string_view kSTAPParamSuffix = "L1Parameters.dat";
+
+  /// Extension for IO of the L1InputData object
+  /// \note IO of the L1InputData object is called inside every launch of CbmL1::ReadEvent function. Inside the function
+  ///       there is a static counter, which calculates the job (function call) number. One have to define the name of
+  ///       the kSTAPAlgoIDataSuffix containing '%d' control symbol, which is replaced with the current job number.
+  ///       \example The file name with [pref] = auau.mbias.eb.100ev and [suff] = "job%d.L1InputData.dat" for the job
+  ///       number 10 is auau.mbias.eb.100ev.job10.L1InputData.dat
+  static constexpr std::string_view kSTAPAlgoIDataSuffix = "job%d.L1InputData.dat";
+
+  /// Name of subdirectory for handling L1InputData objects
+  static constexpr std::string_view kSTAPAlgoIDataDir = "input_hits";
+
 
   Int_t fTrackingLevel     = 2;     // currently not used
   Double_t fMomentumCutOff = 0.1;   // currently not used
diff --git a/reco/L1/CbmL1ReadEvent.cxx b/reco/L1/CbmL1ReadEvent.cxx
index ede3970530..62a2efb5ab 100644
--- a/reco/L1/CbmL1ReadEvent.cxx
+++ b/reco/L1/CbmL1ReadEvent.cxx
@@ -177,6 +177,8 @@ struct TmpHit {
 void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int& FstHitinTs, bool& areDataLeft,
                       CbmEvent* event)
 {
+  static int nCalls = 0;
+
   if (fVerbose >= 10) cout << "ReadEvent: start." << endl;
 
   areDataLeft = false;  // no data left after reading the sub-timeslice
@@ -1185,8 +1187,8 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int
   if (fVerbose >= 1) cout << "ReadEvent: mvd and sts are saved." << endl;
 
   // ----- Send data from IODataManager to L1Algo --------------------------------------------------------------------
-  if (1 == fSTAPDataMode) { WriteAlgoInputData(); }
-  if (2 == fSTAPDataMode) { ReadAlgoInputData(); }
+  if (1 == fSTAPDataMode) { WriteSTAPAlgoInputData(nCalls); }
+  if (2 == fSTAPDataMode) { ReadSTAPAlgoInputData(nCalls); }
   // TODO: SZh: If we read data from file, we don't need to collect them above. This should be addressed
   fIODataManager.SendInputData(fpAlgo);
 
@@ -1195,6 +1197,8 @@ void CbmL1::ReadEvent(float& TsStart, float& TsLength, float& /*TsOverlap*/, int
     if (fVerbose >= 10) cout << "MCPoints and MCTracks are saved." << endl;
   }
   if (fVerbose >= 10) cout << "ReadEvent is done." << endl;
+
+  ++nCalls;
 }  // void CbmL1::ReadEvent()
 //
 //--------------------------------------------------------------------------------------------------
diff --git a/reco/L1/L1Algo/L1CAIteration.h b/reco/L1/L1Algo/L1CAIteration.h
index c4dcc3e825..e84361b981 100644
--- a/reco/L1/L1Algo/L1CAIteration.h
+++ b/reco/L1/L1Algo/L1CAIteration.h
@@ -12,6 +12,8 @@
 #ifndef L1CAIteration_h
 #define L1CAIteration_h 1
 
+#include <boost/serialization/access.hpp>
+
 #include <bitset>
 #include <string>
 
@@ -160,22 +162,45 @@ private:
   // NOTE: For each new cut one should not forget to create a setter and a getter, insert the value
   //       initialization in the copy constructor and the Swap operator as well as a string repre-
   //       sentation to the ToString method (S.Zharko)
-  float fTrackChi2Cut {10.f};                   ///< Track chi2 upper cut
-  float fTripletChi2Cut {21.1075f};             ///< Triplet chi2 upper cut
-  float fDoubletChi2Cut {11.3449 * 2.f / 3.f};  ///< Doublet chi2 upper cut
-  float fPickGather {3.0};        ///< Size of region to attach new hits to the created track [TODO: units??]
-  float fPickNeighbour {5.0};     ///< Min value of dp/dp_error, for which two tiplets are neighbours
-  float fMaxInvMom {1.0 / 0.5};   ///< Max considered q/p for tracks
-  float fMaxSlopePV {1.1};        ///< Max slope (tx\ty) in primary vertex
-  float fMaxSlope {2.748};        ///< Max slope (tx\ty) in 3D hit position of a triplet
-  float fMaxDZ {0.f};             ///< Correction for accounting overlaping and iff z [TODO: units??]
-  float fTargetPosSigmaX {0};     ///< Constraint on target position in X direction [cm]
-  float fTargetPosSigmaY {0};     ///< Constraint on target position in Y direction [cm]
-  int fMinLevelTripletStart {0};  ///< Min level for starting a triplet. Track length = fMinLevelTripletStart + 3
-  int fFirstStationIndex {0};     ///< First station, used for tracking
-
-  bool fIsPrimary {false};   ///< Flag: true - only primary tracks are searched for
-  bool fIsElectron {false};  ///< Flag: true - only electrons are searched for
+  float fTrackChi2Cut       = 10.f;                 ///< Track chi2 upper cut
+  float fTripletChi2Cut     = 21.1075f;             ///< Triplet chi2 upper cut
+  float fDoubletChi2Cut     = 11.3449 * 2.f / 3.f;  ///< Doublet chi2 upper cut
+  float fPickGather         = 3.0;                  ///< Size of region to attach new hits to the created track
+  float fPickNeighbour      = 5.0;                  ///< Min value of dp/dp_error, for which two tiplets are neighbours
+  float fMaxInvMom          = 1.0 / 0.5;            ///< Max considered q/p for tracks
+  float fMaxSlopePV         = 1.1;                  ///< Max slope (tx\ty) in primary vertex
+  float fMaxSlope           = 2.748;                ///< Max slope (tx\ty) in 3D hit position of a triplet
+  float fMaxDZ              = 0.f;                  ///< Correction for accounting overlaping and iff z [cm]
+  float fTargetPosSigmaX    = 0;                    ///< Constraint on target position in X direction [cm]
+  float fTargetPosSigmaY    = 0;                    ///< Constraint on target position in Y direction [cm]
+  int fMinLevelTripletStart = 0;                    ///< Min level for starting a triplet.
+                                                    ///< Track length = fMinLevelTripletStart + 3
+  int fFirstStationIndex = 0;                       ///< First station, used for tracking
+
+  bool fIsPrimary  = false;  ///< Flag: true - only primary tracks are searched for
+  bool fIsElectron = false;  ///< Flag: true - only electrons are searched for
+
+  /// Serialization method, used to save L1Hit objects into binary or text file in a defined order
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int /*version*/)
+  {
+    ar& fTrackChi2Cut;
+    ar& fTripletChi2Cut;
+    ar& fDoubletChi2Cut;
+    ar& fPickGather;
+    ar& fPickNeighbour;
+    ar& fMaxInvMom;
+    ar& fMaxSlopePV;
+    ar& fMaxSlope;
+    ar& fMaxDZ;
+    ar& fTargetPosSigmaX;
+    ar& fTargetPosSigmaY;
+    ar& fMinLevelTripletStart;
+    ar& fFirstStationIndex;
+    ar& fIsPrimary;
+    ar& fIsElectron;
+  }
 
 
   // ^ TODO: invent more proper name
diff --git a/reco/L1/L1Algo/L1Field.h b/reco/L1/L1Algo/L1Field.h
index a74328f436..2b39ae1bb3 100644
--- a/reco/L1/L1Algo/L1Field.h
+++ b/reco/L1/L1Algo/L1Field.h
@@ -9,6 +9,7 @@
 
 #include "L1Constants.h"
 #include "L1Def.h"
+#include "L1SimdSerializer.h"
 
 class L1FieldValue {
 public:
@@ -30,9 +31,19 @@ public:
   /// String representation of class contents
   /// \param indentLevel      number of indent characters in the output
   std::string ToString(int indentLevel) const;
+
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& x;
+    ar& y;
+    ar& z;
+  }
 } _fvecalignment;
 
-inline __attribute__((always_inline)) void L1FieldValue::Combine(L1FieldValue& B, fvec w)
+[[gnu::always_inline]] inline void L1FieldValue::Combine(L1FieldValue& B, fvec w)
 {
   x += w * (B.x - x);
   y += w * (B.y - y);
@@ -70,6 +81,16 @@ public:
     [L1Constants::size::kMaxNFieldApproxCoefficients];  ///< Polynomial coefficients for y-component of the field value
   fvec cz
     [L1Constants::size::kMaxNFieldApproxCoefficients];  ///< Polynomial coefficients for z-component of the field value
+
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& cx;
+    ar& cy;
+    ar& cz;
+  }
 } _fvecalignment;
 
 
@@ -159,6 +180,22 @@ public:
   fvec cz1 {0.f};
   fvec cz2 {0.f};
   fvec z0 {0.f};  ///< z-coordinate of the field region central point
+
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& cx0;
+    ar& cx1;
+    ar& cx2;
+    ar& cy0;
+    ar& cy1;
+    ar& cy2;
+    ar& cz0;
+    ar& cz1;
+    ar& cz2;
+  }
 } _fvecalignment;
 
 #endif
diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx
index 4c15cc8733..f5b2c82f47 100644
--- a/reco/L1/L1Algo/L1InitManager.cxx
+++ b/reco/L1/L1Algo/L1InitManager.cxx
@@ -2,13 +2,17 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Sergey Gorbunov, Sergei Zharko [committer] */
 
-/// \file L1InitManager.cxx
+/// \file  L1InitManager.cxx
 /// \brief Input parameters management class for L1Algo
 /// \since 19.01.2022
 
 #include "L1InitManager.h"
 
+#include <boost/archive/binary_iarchive.hpp>
+#include <boost/archive/binary_oarchive.hpp>
+
 #include <algorithm>
+#include <fstream>
 #include <sstream>
 
 #include "L1Algo.h"
@@ -87,6 +91,55 @@ void L1InitManager::CheckInit()
   this->CheckStationsInfoInit();
 }
 
+// ----------------------------------------------------------------------------------------------------------------------
+//
+void L1InitManager::ClearSetupInfo()
+{
+  // Clear stations set and a thickness map
+  fStationsInfo.clear();
+  std::fill(fParameters.fThickMap.begin(), fParameters.fThickMap.end(), L1Material());
+  fInitController.SetFlag(EInitKey::kStationsInfo, false);
+
+  // Set number of stations do default values
+  std::fill(fParameters.fNstationsGeometry.begin(), fParameters.fNstationsGeometry.end(), 0);
+  std::fill(fParameters.fNstationsActive.begin(), fParameters.fNstationsActive.end(), 0);
+  std::fill(fParameters.fActiveStationGlobalIDs.begin(), fParameters.fActiveStationGlobalIDs.end(), 0);
+  fParameters.fNstationsGeometryTotal = -1;
+  fParameters.fNstationsActiveTotal   = -1;
+  fInitController.SetFlag(EInitKey::kStationsNumberCrosscheck, false);
+
+  // Clear active detectors
+  fActiveDetectorIDs.clear();
+  fInitController.SetFlag(EInitKey::kActiveDetectorIDs, false);
+
+  // Clear field info
+  fParameters.fVertexFieldRegion = L1FieldRegion();
+  fParameters.fVertexFieldValue  = L1FieldValue();
+  fInitController.SetFlag(EInitKey::kPrimaryVertexField, false);
+
+  // Clear target position
+  std::fill(fParameters.fTargetPos.begin(), fParameters.fTargetPos.end(), L1Utils::kNaN);
+  fTargetZ = 0.;
+  fInitController.SetFlag(EInitKey::kTargetPos, false);
+
+  // Clear field function
+  fFieldFunction = L1FieldFunction_t([](const double(&)[3], double(&)[3]) {});
+  fInitController.SetFlag(EInitKey::kFieldFunction, false);
+
+  // Clear other flags
+  fParameters.fTrackingLevel    = 0;
+  fParameters.fGhostSuppression = 0;
+  fParameters.fMomentumCutOff   = 0;
+  fInitController.SetFlag(EInitKey::kTrackingLevel, false);
+  fInitController.SetFlag(EInitKey::kGhostSuppression, false);
+  fInitController.SetFlag(EInitKey::kMomentumCutOff, false);
+
+  fParameters.fDevIsIgnoreHitSearchAreas  = false;
+  fParameters.fDevIsFitSingletsFromTarget = false;
+  fParameters.fDevIsMatchDoubletsViaMc    = false;
+  fParameters.fDevIsMatchTripletsViaMc    = false;
+}
+
 // ----------------------------------------------------------------------------------------------------------------------
 //
 void L1InitManager::ClearCAIterations()
@@ -94,6 +147,7 @@ void L1InitManager::ClearCAIterations()
   fParameters.fCAIterations.clear();
   fCAIterationsNumberCrosscheck = -1;
   fInitController.SetFlag(EInitKey::kCAIterations, false);
+  fInitController.SetFlag(EInitKey::kStationsNumberCrosscheck, false);
 }
 
 // ----------------------------------------------------------------------------------------------------------------------
@@ -189,11 +243,26 @@ void L1InitManager::PushBackCAIteration(const L1CAIteration& iteration)
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-bool L1InitManager::SendParameters(L1Algo* pAlgo)
+void L1InitManager::ReadParametersObject(const std::string& fileName)
 {
-  // Form parameters cotainer
-  this->FormParametersContainer();
+  // Open input binary file
+  std::ifstream ifs(fileName, std::ios::binary);
+  if (!ifs) { LOG(fatal) << "L1InitManager: parameters data file \"" << fileName << "\" was not found"; }
+
+  // Get L1InputData object
+  try {
+    boost::archive::binary_iarchive ia(ifs);
+    ia >> fParameters;
+  }
+  catch (const std::exception&) {
+    LOG(fatal) << "L1InitManager: parameters file \"" << fileName << "\" has incorrect data format or was corrupted";
+  }
+}
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+bool L1InitManager::SendParameters(L1Algo* pAlgo)
+{
   assert(pAlgo);
   pAlgo->ReceiveParameters(std::move(fParameters));
   return true;
@@ -328,6 +397,22 @@ void L1InitManager::SetTrackingLevel(int trackingLevel)
   fInitController.SetFlag(EInitKey::kTrackingLevel);
 }
 
+// ----------------------------------------------------------------------------------------------------------------------
+//
+void L1InitManager::WriteParametersObject(const std::string& fileName) const
+{
+  // Open output binary file
+  std::ofstream ofs(fileName, std::ios::binary);
+  if (!ofs) {
+    LOG(error) << "L1InitManager: failed opening file \"" << fileName << " for writing parameters object\"";
+    return;
+  }
+
+  // Serialize L1Parameters object and write
+  boost::archive::binary_oarchive oa(ofs);
+  oa << fParameters;
+}
+
 //
 // INIT CHECKERS
 //
diff --git a/reco/L1/L1Algo/L1InitManager.h b/reco/L1/L1Algo/L1InitManager.h
index 0f66af6dc8..7a159a86c8 100644
--- a/reco/L1/L1Algo/L1InitManager.h
+++ b/reco/L1/L1Algo/L1InitManager.h
@@ -2,11 +2,9 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Sergey Gorbunov, Sergei Zharko [committer] */
 
-/************************************************************************************************************
- * @file L1InitManager.h
- * @brief Input data management class for L1Algo
- * @since 24.12.2021
- ***********************************************************************************************************/
+/// \file  L1InitManager.h
+/// \brief Input data management class for L1Algo
+/// \since 24.12.2021
 #ifndef L1InitManager_h
 #define L1InitManager_h 1
 
@@ -134,6 +132,12 @@ public:
   /// Clears vector of CA track finder iterations
   void ClearCAIterations();
 
+  /// Clears vector of base setup
+  void ClearSetupInfo();
+
+  /// Forms parameters container
+  void FormParametersContainer();
+
   /// Gets ghost suppression flag
   int GetGhostSuppression() const { return fParameters.fGhostSuppression; }
 
@@ -184,6 +188,10 @@ public:
   /// 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); }
 
+  /// Reads parameters object from boost-serialized binary file
+  /// \param  fileName  Name of input file
+  void ReadParametersObject(const std::string& fileName);
+
   /// Sets a set of active tracking detector IDs
   void SetActiveDetectorIDs(const L1DetectorIDSet_t& detectorIDs);
 
@@ -231,6 +239,11 @@ public:
   /// \return Success flag
   bool SendParameters(L1Algo* pAlgo);
 
+  /// Writes parameters object from boost-serialized binary file
+  /// \param  fileName  Name of input file
+  void WriteParametersObject(const std::string& fileName) const;
+
+
   // ***************************
   // ** Flags for development **
   // ***************************
@@ -260,8 +273,6 @@ private:
   /// \return true If all L1BaseStationInfo objects were initialized properly. Similar effect can be achieved by
   void CheckStationsInfoInit();
 
-  /// Forms parameters container
-  void FormParametersContainer();
 
 
   // *****************
diff --git a/reco/L1/L1Algo/L1MaterialInfo.h b/reco/L1/L1Algo/L1MaterialInfo.h
index ef4ea8a9f8..c495a61d6f 100644
--- a/reco/L1/L1Algo/L1MaterialInfo.h
+++ b/reco/L1/L1Algo/L1MaterialInfo.h
@@ -5,6 +5,8 @@
 #ifndef L1MaterialInfo_h
 #define L1MaterialInfo_h
 
+#include <boost/serialization/vector.hpp>
+
 #include <iomanip>
 #include <sstream>
 #include <string>
@@ -12,6 +14,7 @@
 
 #include "L1Def.h"
 #include "L1NaN.h"
+#include "L1SimdSerializer.h"
 
 /// Class L1MaterialInfo contains SIMDized vector fields of the
 /// The fields of the structure should ONLY be initialized within L1BaseStationInfo::SetMaterial(double, double) method, when the
@@ -35,6 +38,17 @@ struct L1MaterialInfo {
   /// String representation of class contents
   /// \param indentLevel    number of indent characters in the output
   std::string ToString(int indentLevel = 0) const;
+
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& thick;
+    ar& RL;
+    ar& RadThick;
+    ar& logRadThick;
+  }
 } _fvecalignment;
 
 /// Class L1Material describes a map of station thickness in units of radiation length (X0) to the specific point in XY plane
@@ -107,6 +121,17 @@ private:
   float fFactor {
     L1NaN::SetNaN<decltype(fFactor)>()};  ///< Factor used in the recalculation of point coordinates to row/column id
   std::vector<float> fTable {};  ///< Material budget table
+
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& fNbins;
+    ar& fRmax;
+    ar& fFactor;
+    ar& fTable;
+  }
 } _fvecalignment;
 
 #endif
diff --git a/reco/L1/L1Algo/L1Parameters.cxx b/reco/L1/L1Algo/L1Parameters.cxx
index 8422a5cb46..851324bb17 100644
--- a/reco/L1/L1Algo/L1Parameters.cxx
+++ b/reco/L1/L1Algo/L1Parameters.cxx
@@ -246,6 +246,7 @@ void L1Parameters::Print(int /*verbosityLevel*/) const
 //
 std::string L1Parameters::ToString(int verbosity, int indentLevel) const
 {
+  // FIXME: SZh: Fill it with other parameters
   std::stringstream aStream {};
   constexpr char indentChar = '\t';
   std::string indent(indentLevel, indentChar);
@@ -275,7 +276,6 @@ std::string L1Parameters::ToString(int verbosity, int indentLevel) const
     aStream << indent << indentChar << indentChar << indentChar << char(120 + dim) << " = " << fTargetPos[dim][0]
             << " cm\n";
   }
-
   aStream << indent << indentChar << "NUMBER OF STATIONS:\n";
   aStream << indent << indentChar << indentChar << "Number of stations (Geometry): ";
   for (int idx = 0; idx < int(fNstationsGeometry.size()); ++idx) {
@@ -299,6 +299,8 @@ std::string L1Parameters::ToString(int verbosity, int indentLevel) const
   for (int idx = 0; idx < *(fNstationsActive.end() - 1); ++idx) {
     aStream << indent << indentChar << indentChar << fStations[idx].ToString(verbosity) << '\n';
   }
+
+  aStream << indent << "FLAGS:\n";
   aStream << indent << "--------------------------------------------------------------------------------\n";
   return aStream.str();
 }
diff --git a/reco/L1/L1Algo/L1Parameters.h b/reco/L1/L1Algo/L1Parameters.h
index ddf9daf02a..b1bd49a988 100644
--- a/reco/L1/L1Algo/L1Parameters.h
+++ b/reco/L1/L1Algo/L1Parameters.h
@@ -10,9 +10,10 @@
 #ifndef L1Parameters_h
 #define L1Parameters_h 1
 
-#include <type_traits>
+#include <boost/serialization/array.hpp>
 
 #include <numeric>
+#include <type_traits>
 
 #include "L1CAIteration.h"
 #include "L1Constants.h"
@@ -249,13 +250,42 @@ private:
   // ***************************
 
   bool fDevIsIgnoreHitSearchAreas {false};  ///< Process all hits on the station ignoring hit search area
-
   bool fDevIsFitSingletsFromTarget {false};  ///< Fit singlet starting from the target with the KF
-
   bool fDevIsMatchDoubletsViaMc {false};  ///< Flag to match doublets using MC information
-
   bool fDevIsMatchTripletsViaMc {false};  ///< Flag to match triplets using Mc information
 
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& fMaxDoubletsPerSinglet;
+    ar& fMaxTripletPerDoublets;
+
+    ar& fCAIterations;
+    ar& fTargetPos;
+
+    ar& fVertexFieldValue;
+    ar& fVertexFieldRegion;
+
+    ar& fStations;
+    ar& fThickMap;
+
+    ar& fNstationsGeometryTotal;
+    ar& fNstationsActiveTotal;
+    ar& fNstationsGeometry;
+    ar& fNstationsActive;
+    ar& fActiveStationGlobalIDs;
+
+    ar& fTrackingLevel;
+    ar& fGhostSuppression;
+    ar& fMomentumCutOff;
+
+    ar& fDevIsIgnoreHitSearchAreas;
+    ar& fDevIsFitSingletsFromTarget;
+    ar& fDevIsMatchDoubletsViaMc;
+    ar& fDevIsMatchTripletsViaMc;
+  }
 };
 
 #endif  // L1Parameters_h
diff --git a/reco/L1/L1Algo/L1SimdSerializer.h b/reco/L1/L1Algo/L1SimdSerializer.h
new file mode 100644
index 0000000000..893bd331ee
--- /dev/null
+++ b/reco/L1/L1Algo/L1SimdSerializer.h
@@ -0,0 +1,31 @@
+/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergey Gorbunov, Sergei Zharko [committer] */
+
+/// \file   L1SimdSerializer.h
+/// \brief  External serialization for SIMD vector
+/// \since  02.09.2022
+/// \author S.Zharko <s.zharko@gsi.de>
+
+#ifndef L1SimdSerializer_h
+#define L1SimdSerializer_h 1
+
+#include <boost/serialization/access.hpp>
+
+#include "vectors/L1vec.h"
+
+namespace boost
+{
+  namespace serialization
+  {
+    template<class Archive>
+    void serialize(Archive& ar, fvec& vect, const unsigned int)
+    {
+      for (int i = 0; i < fvecLen; ++i) {
+        ar&(reinterpret_cast<fscal*>(&vect))[i];
+      }
+    }
+  }  // namespace serialization
+}  // namespace boost
+
+#endif  // L1SimdSerializer_h
diff --git a/reco/L1/L1Algo/L1Station.h b/reco/L1/L1Algo/L1Station.h
index 02e879fcae..7e176b6ef0 100644
--- a/reco/L1/L1Algo/L1Station.h
+++ b/reco/L1/L1Algo/L1Station.h
@@ -11,6 +11,7 @@
 #include "L1Field.h"
 #include "L1MaterialInfo.h"
 #include "L1NaN.h"
+#include "L1SimdSerializer.h"
 #include "L1UMeasurementInfo.h"
 #include "L1Utils.h"
 #include "L1XYMeasurementInfo.h"
@@ -37,6 +38,30 @@ public:
   L1UMeasurementInfo yInfo {};  ///< y axis in front,back coordinates
   L1XYMeasurementInfo XYInfo {};
 
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& type;
+    ar& timeInfo;
+    ar& fieldStatus;
+
+    ar& z;
+    ar& Rmin;
+    ar& Rmax;
+    ar& dt;
+
+    ar& materialInfo;
+    ar& fieldSlice;
+    ar& frontInfo;
+    ar& backInfo;
+    ar& xInfo;
+    ar& yInfo;
+    ar& XYInfo;
+  }
+
+
   /// Prints object fields
   /// \param verbosity  Verbosity level of the output
   void Print(int verbosity = 0) const;
diff --git a/reco/L1/L1Algo/L1UMeasurementInfo.h b/reco/L1/L1Algo/L1UMeasurementInfo.h
index 8f87f798cd..63a82ac90f 100644
--- a/reco/L1/L1Algo/L1UMeasurementInfo.h
+++ b/reco/L1/L1Algo/L1UMeasurementInfo.h
@@ -9,6 +9,7 @@
 
 #include "L1Def.h"
 #include "L1NaN.h"
+#include "L1SimdSerializer.h"
 #include "L1Utils.h"
 
 class L1UMeasurementInfo {
@@ -27,6 +28,16 @@ public:
 
   /// Checks, if the fields are NaN
   bool IsNaN() const { return L1NaN::IsNaN(cos_phi) || L1NaN::IsNaN(sin_phi) || L1NaN::IsNaN(sigma2); }
+
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& cos_phi;
+    ar& sin_phi;
+    ar& sigma2;
+  }
 } _fvecalignment;
 
 
diff --git a/reco/L1/L1Algo/L1XYMeasurementInfo.h b/reco/L1/L1Algo/L1XYMeasurementInfo.h
index 6af76f89ec..35cfca20f8 100644
--- a/reco/L1/L1Algo/L1XYMeasurementInfo.h
+++ b/reco/L1/L1Algo/L1XYMeasurementInfo.h
@@ -9,9 +9,9 @@
 
 #include "L1Def.h"
 #include "L1NaN.h"
+#include "L1SimdSerializer.h"
 
 class L1XYMeasurementInfo {
-
 public:
   fvec C00 {L1NaN::SetNaN<decltype(C00)>()};
   fvec C10 {L1NaN::SetNaN<decltype(C10)>()};
@@ -26,6 +26,16 @@ public:
 
   /// Checks, if the fields are NaN
   bool IsNaN() const { return L1NaN::IsNaN(C00) || L1NaN::IsNaN(C10) || L1NaN::IsNaN(C11); }
+
+  /// Serialization function
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive& ar, const unsigned int)
+  {
+    ar& C00;
+    ar& C10;
+    ar& C11;
+  }
 } _fvecalignment;
 
 
-- 
GitLab