From 0e94e4b810de3d982d0b0c06b3d4c2d3f543226e Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Wed, 5 Oct 2022 15:27:11 +0200
Subject: [PATCH] L1: old iteration enums are removed

---
 reco/L1/CbmL1.cxx                   | 14 ++++-
 reco/L1/L1Algo/L1Algo.h             | 29 ---------
 reco/L1/L1Algo/L1CAIteration.cxx    |  6 ++
 reco/L1/L1Algo/L1CAIteration.h      | 21 +++++++
 reco/L1/L1Algo/L1CATrackFinder.cxx  | 92 +++++++++++------------------
 reco/L1/L1Algo/L1ConfigExample.yaml | 20 +++++++
 reco/L1/L1Algo/L1ConfigRW.cxx       | 43 +++++++++-----
 reco/L1/L1Algo/L1InitManager.cxx    | 13 +++-
 reco/L1/L1Algo/L1Parameters.cxx     | 11 +++-
 reco/L1/L1Algo/L1TrackExtender.cxx  |  4 +-
 10 files changed, 143 insertions(+), 110 deletions(-)

diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index b7b7baa4be..438da30663 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -662,6 +662,7 @@ InitStatus CbmL1::Init()
     trackingIterFastPrim.SetTargetPosSigmaXY(1, 1);
     trackingIterFastPrim.SetMinLevelTripletStart(0);
     trackingIterFastPrim.SetPrimaryFlag(true);
+    trackingIterFastPrim.SetSuppressGhostFlag(false);
 
     auto trackingIterAllPrim = L1CAIteration("AllPrimIter");
     trackingIterAllPrim.SetTrackChi2Cut(10.f);
@@ -676,6 +677,7 @@ InitStatus CbmL1::Init()
     trackingIterAllPrim.SetTargetPosSigmaXY(1, 1);
     trackingIterAllPrim.SetMinLevelTripletStart(0);
     trackingIterAllPrim.SetPrimaryFlag(true);
+    trackingIterAllPrim.SetSuppressGhostFlag(false);
 
     auto trackingIterFastPrim2 = L1CAIteration("FastPrim2Iter");
     trackingIterFastPrim2.SetTrackChi2Cut(10.f);
@@ -690,6 +692,7 @@ InitStatus CbmL1::Init()
     trackingIterFastPrim2.SetTargetPosSigmaXY(5, 5);
     trackingIterFastPrim2.SetMinLevelTripletStart(0);
     trackingIterFastPrim2.SetPrimaryFlag(true);
+    trackingIterFastPrim2.SetSuppressGhostFlag(true);
 
     auto trackingIterAllSec = L1CAIteration("AllSecIter");
     trackingIterAllSec.SetTrackChi2Cut(10.f);
@@ -704,6 +707,7 @@ InitStatus CbmL1::Init()
     trackingIterAllSec.SetTargetPosSigmaXY(10, 10);
     trackingIterAllSec.SetMinLevelTripletStart(1);
     trackingIterAllSec.SetPrimaryFlag(false);
+    trackingIterAllSec.SetSuppressGhostFlag(true);
 
     auto trackingIterFastPrimJump = L1CAIteration("FastPrimJumpIter");
     trackingIterFastPrimJump.SetTrackChi2Cut(10.f);
@@ -718,6 +722,8 @@ InitStatus CbmL1::Init()
     trackingIterFastPrimJump.SetTargetPosSigmaXY(5, 5);
     trackingIterFastPrimJump.SetMinLevelTripletStart(0);
     trackingIterFastPrimJump.SetPrimaryFlag(true);
+    trackingIterFastPrimJump.SetSuppressGhostFlag(true);
+    trackingIterFastPrimJump.SetJumpedFlag(true);
 
     auto trackingIterAllPrimJump = L1CAIteration("AllPrimJumpIter");
     trackingIterAllPrimJump.SetTrackChi2Cut(10.f);
@@ -732,6 +738,8 @@ InitStatus CbmL1::Init()
     trackingIterAllPrimJump.SetTargetPosSigmaXY(5, 5);
     trackingIterAllPrimJump.SetMinLevelTripletStart(0);
     trackingIterAllPrimJump.SetPrimaryFlag(true);
+    trackingIterAllPrimJump.SetSuppressGhostFlag(true);
+    trackingIterAllPrimJump.SetJumpedFlag(true);
 
     auto trackingIterAllSecJump = L1CAIteration("AllSecJumpIter");
     trackingIterAllSecJump.SetTrackChi2Cut(10.f);
@@ -746,6 +754,8 @@ InitStatus CbmL1::Init()
     trackingIterAllSecJump.SetMinLevelTripletStart(1);
     trackingIterAllSecJump.SetTargetPosSigmaXY(10, 10);
     trackingIterAllSecJump.SetPrimaryFlag(false);
+    trackingIterAllSecJump.SetSuppressGhostFlag(true);
+    trackingIterAllSecJump.SetJumpedFlag(true);
 
     auto trackingIterAllPrimE = L1CAIteration("AllPrimEIter");
     trackingIterAllPrimE.SetTrackChi2Cut(10.f);
@@ -761,6 +771,7 @@ InitStatus CbmL1::Init()
     trackingIterAllPrimE.SetMinLevelTripletStart(0);
     trackingIterAllPrimE.SetPrimaryFlag(true);
     trackingIterAllPrimE.SetElectronFlag(true);
+    trackingIterAllPrimE.SetSuppressGhostFlag(false);
 
     auto trackingIterAllSecE = L1CAIteration("AllSecEIter");
     trackingIterAllSecE.SetTrackChi2Cut(10.f);
@@ -776,6 +787,7 @@ InitStatus CbmL1::Init()
     trackingIterAllSecE.SetTargetPosSigmaXY(10, 10);
     trackingIterAllSecE.SetPrimaryFlag(false);
     trackingIterAllSecE.SetElectronFlag(true);
+    trackingIterAllSecE.SetSuppressGhostFlag(false);
 
     // Select default track finder
     if (L1Algo::TrackingMode::kMcbm == fTrackingMode) {
@@ -883,7 +895,7 @@ InitStatus CbmL1::Init()
     fInitManager.SetMomentumCutOff(fMomentumCutOff);
 
     // Form parameters container
-    if (!fInitManager.FormParametersContainer()) { return kERROR; }
+    if (!fInitManager.FormParametersContainer()) { return kFATAL; }
 
     // Write to file if needed
     if (1 == fSTAPDataMode) { this->WriteSTAPParamObject(); }
diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h
index 2853070b7c..a9ee938f81 100644
--- a/reco/L1/L1Algo/L1Algo.h
+++ b/reco/L1/L1Algo/L1Algo.h
@@ -544,38 +544,9 @@ private:
 
   // fNFindIterations - set number of interation for trackfinding
   // itetation of finding:
-#ifdef FIND_GAPED_TRACKS
-  enum
-  {
-    kFastPrimIter,     // primary fast tracks
-    kAllPrimIter,      // primary all tracks
-    kAllPrimJumpIter,  // primary tracks with jumped triplets
-    kAllSecIter,       // secondary all tracks
-    kAllPrimEIter,     // primary all electron tracks
-    kAllSecEIter,      // secondary all electron tracks
-
-    kFastPrimJumpIter,  // primary fast tracks with jumped triplets
-    kFastPrimIter2,
-    kAllSecJumpIter  // secondary tracks with jumped triplets
-  };
 
   int fNFindIterations = -1;  // TODO investigate kAllPrimJumpIter & kAllSecJumpIter
 
-#else  // not FIND_GAPED_TRACKS
-  enum
-  {
-    kFastPrimIter = 0,  // primary fast tracks
-    kAllPrimIter,       // primary all tracks
-    kAllSecIter,        // secondary all tracks
-    kFastPrimJumpIter,  // disabled
-    kAllPrimJumpIter,   // disabled
-    kFastPrimIter2,
-    kAllSecJumpIter,
-    kAllPrimEIter,
-    kAllSecEIter
-  };
-#endif  // FIND_GAPED_TRACKS
-
   std::map<int, int> threadNumberToCpuMap {};
 
   float fTrackChi2Cut {10.f};
diff --git a/reco/L1/L1Algo/L1CAIteration.cxx b/reco/L1/L1Algo/L1CAIteration.cxx
index 72ae712f5c..f2e7e3cada 100644
--- a/reco/L1/L1Algo/L1CAIteration.cxx
+++ b/reco/L1/L1Algo/L1CAIteration.cxx
@@ -42,6 +42,8 @@ L1CAIteration::L1CAIteration(const L1CAIteration& other) noexcept
   , fIsElectron(other.fIsElectron)
   , fIsTrackFromTriplets(other.fIsTrackFromTriplets)
   , fIfExtendTracks(other.fIfExtendTracks)
+  , fIfJumped(other.fIfJumped)
+  , fIfSuppressGhost(other.fIfSuppressGhost)
 {
 }
 //
@@ -119,6 +121,8 @@ void L1CAIteration::Swap(L1CAIteration& other) noexcept
   std::swap(fIsElectron, other.fIsElectron);
   std::swap(fIsTrackFromTriplets, other.fIsTrackFromTriplets);
   std::swap(fIfExtendTracks, other.fIfExtendTracks);
+  std::swap(fIfJumped, other.fIfJumped);
+  std::swap(fIfSuppressGhost, other.fIfSuppressGhost);
 }
 //
 //----------------------------------------------------------------------------------------------------------------------
@@ -133,6 +137,8 @@ std::string L1CAIteration::ToString(int indentLevel) const
   aStream << indent << indCh << "Is electron:                            " << fIsElectron << '\n';
   aStream << indent << indCh << "Are tracks created from triplets:       " << fIsTrackFromTriplets << '\n';
   aStream << indent << indCh << "Are tracks extended with unused hits :  " << fIfExtendTracks << '\n';
+  aStream << indent << indCh << "Are hits skip in triplets building:     " << fIfJumped << '\n';
+  aStream << indent << indCh << "Ghost suppression in tracks cand. selection :" << fIfSuppressGhost << '\n';
   aStream << indent << indCh << "Track chi2 cut:                         " << fTrackChi2Cut << '\n';
   aStream << indent << indCh << "Triplet chi2 cut:                       " << fTripletChi2Cut << '\n';
   aStream << indent << indCh << "Doublet chi2 cut:                       " << fDoubletChi2Cut << '\n';
diff --git a/reco/L1/L1Algo/L1CAIteration.h b/reco/L1/L1Algo/L1CAIteration.h
index dc1d09e22e..63d82156dd 100644
--- a/reco/L1/L1Algo/L1CAIteration.h
+++ b/reco/L1/L1Algo/L1CAIteration.h
@@ -13,6 +13,7 @@
 #define L1CAIteration_h 1
 
 #include <boost/serialization/access.hpp>
+#include <boost/serialization/string.hpp>
 
 #include <bitset>
 #include <string>
@@ -59,6 +60,9 @@ public:
   /// Gets station index of the first station used in tracking
   int GetFirstStationIndex() const { return fFirstStationIndex; }
 
+  /// Gets ... TODO
+  bool GetJumpedFlag() const { return fIfJumped; }
+
   /// Gets correction for accounting overlaping and iff z
   float GetMaxDZ() const { return fMaxDZ; }
 
@@ -86,6 +90,9 @@ public:
   /// Checks flag: true - only primary tracks are searched, false - [all or only secondary?]
   bool GetPrimaryFlag() const { return fIsPrimary; }
 
+  /// Sets flag: true - skip track candidates with level = 0
+  bool GetSuppressGhostFlag() const { return fIfSuppressGhost; }
+
   /// Gets sigma target position in X direction [cm]
   float GetTargetPosSigmaX() const { return fTargetPosSigmaX; }
 
@@ -126,6 +133,9 @@ public:
   /// Sets index of first station used in tracking
   void SetFirstStationIndex(int index) { fFirstStationIndex = index; }
 
+  /// Sets flag: true - triplets are built from hits .... TODO
+  void SetJumpedFlag(bool flag) { fIfJumped = flag; }
+
   /// Sets correction for accounting overlaping and iff z
   void SetMaxDZ(float input) { fMaxDZ = input; }
 
@@ -154,6 +164,9 @@ public:
   /// Sets flag: primary tracks - true, secondary tracks - false
   void SetPrimaryFlag(bool flag) { fIsPrimary = flag; }
 
+  /// Sets flag: true - skip track candidates with level = 0
+  void SetSuppressGhostFlag(bool flag) { fIfSuppressGhost = flag; }
+
   /// Sets sigma of target positions in XY plane
   /// \param  sigmaX  Sigma value in X direction [cm]
   /// \param  sigmaX  Sigma value in Y direction [cm]
@@ -223,13 +236,19 @@ private:
   bool fIsTrackFromTriplets = false;
 
   bool fIfExtendTracks = false;  ///< Flag: true - extends track candidates with unused hits
+  bool fIfJumped       = false;  ///< Flag: true - find triplets with skip station
 
+  /// \brief Flag to suppress ghost tracks on the stage of track candidates selection
+  ///   If the flag is true, three-hit tracks with level = 0 will be skip. This helps to reduce ghost tracks
+  /// under conditions of high hits density
+  bool fIfSuppressGhost = false;
 
   /// 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& fName;
     ar& fTrackChi2Cut;
     ar& fTripletChi2Cut;
     ar& fDoubletChi2Cut;
@@ -247,6 +266,8 @@ private:
     ar& fIsElectron;
     ar& fIsTrackFromTriplets;
     ar& fIfExtendTracks;
+    ar& fIfJumped;
+    ar& fIfSuppressGhost;
   }
 
 
diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx
index b21a50b700..aaf20b56b1 100644
--- a/reco/L1/L1Algo/L1CATrackFinder.cxx
+++ b/reco/L1/L1Algo/L1CATrackFinder.cxx
@@ -1228,12 +1228,12 @@ inline void L1Algo::findTripletsStep3(  // input
       // TODO: But for some reason, the efficiency degrades without them.
       // TODO: It needs to be investigated. If the cuts are necessary, they need to be adjusted.
 
+      // TODO: SZh 04.10.2022: What does this number mean?
       fscal Cmax = 0.04 * fMaxInvMom[0];  // minimal momentum: 0.05 - 0.1
-                                          //if ( isec == kAllPrimJumpIter ) {
       if (Cqp > Cmax) {
-        //cout << "isec " << isec << " Cqp " << Cqp << " max " << Cmax << " add " << 0.05 * Cmax << endl;
         Cqp = Cmax;
       }
+      // TODO: SZh 04.10.2022: What does this number mean?
       Cqp += 0.05 * Cmax;  // TODO: without this line the ghost ratio increases, why?
     }
 
@@ -1289,11 +1289,12 @@ inline void L1Algo::f5(  // input
     for (int istal = fParameters.GetNstationsActive() - 4; istal >= fFirstCAstation; istal--) {
       for (int tripType = 0; tripType < 3; tripType++)  // tT = 0 - 123triplet, tT = 1 - 124triplet, tT = 2 - 134triplet
       {
-        if ((((isec != kFastPrimJumpIter) && (isec != kAllPrimJumpIter) && (isec != kAllSecJumpIter))
-             && (tripType != 0))
-            || (((isec == kFastPrimJumpIter) || (isec == kAllPrimJumpIter) || (isec == kAllSecJumpIter))
-                && (tripType != 0) && (istal == fParameters.GetNstationsActive() - 4)))
+        // All iters - jump
+        if ((!fpCurrentIteration->GetJumpedFlag() && tripType != 0)
+            || (fpCurrentIteration->GetJumpedFlag() && tripType != 0
+                && (fParameters.GetNstationsActive() - 4 == istal))) {
           continue;
+        }
 
         int istam = istal + 1;
         int istar = istal + 2;
@@ -1566,8 +1567,6 @@ inline void L1Algo::TripletsStaPort(  /// creates triplets:
     for (Tindex i = 0; i < static_cast<Tindex>(hitsr_3.size()); ++i)
       L1_assert(hitsr_3[i] < HitsUnusedStopIndex[istar] - HitsUnusedStartIndex[istar]);
 
-    //        if (n3 >= MaxPortionTriplets) cout << "isec: " << isec << " station: " << istal << " portion number: " << ip << " CATrackFinder: Warning: Too many Triplets created in portion" << endl;
-
     /// Add the right hits to parameters estimation.
     findTripletsStep1(  // input
       n3_V, star, u_front3, u_back3, z_pos3, du3, dv3, timeR, timeER,
@@ -1621,11 +1620,11 @@ inline void L1Algo::TripletsStaPort(  /// creates triplets:
 // }
 
 
-/***********************************************************************************************/ /**
- *                                                                                                *
- *                            ------ CATrackFinder procedure ------                               *
- *                                                                                                *
- **************************************************************************************************/
+// **************************************************************************************************
+// *                                                                                                *
+// *                            ------ CATrackFinder procedure ------                               *
+// *                                                                                                *
+// **************************************************************************************************
 
 void L1Algo::CATrackFinder()
 {
@@ -2051,7 +2050,7 @@ void L1Algo::CATrackFinder()
           // output
         );
 
-        if ((isec == kFastPrimJumpIter) || (isec == kAllPrimJumpIter) || (isec == kAllSecJumpIter) || (fMissingHits)) {
+        if (fpCurrentIteration->GetJumpedFlag() || (fMissingHits)) {
           // All iterations are "jump"!
           Tindex nG_2;
           hitsmG_2.clear();
@@ -2106,23 +2105,12 @@ void L1Algo::CATrackFinder()
 
     int min_level =
       caIteration.GetMinLevelTripletStart();  // min level to start triplet. So min track length = min_level+3.
-                                              //    if (isec == kFastPrimJumpIter) min_level = 1;
-    //if ((isec == kAllSecIter) || (isec == kAllSecEIter) || (isec == kAllSecJumpIter))
-    //  min_level = 1;  // only the long low momentum tracks
 
     // TODO: SZh 04.10.2022: Why this fatal error is called?
     // NOTE: This line was wrapped into TRACKS_FROM_TRIPLETS ifdef
     //LOG(FATAL) << "L1CATrackFinder: min_level undefined in " << __FILE__ << " : " << __LINE__;
     if (fpCurrentIteration->GetTrackFromTripletsFlag()) { min_level = 0; }
 
-    // TODO: Just remove it
-    // // min_level: lower then this triplets would never start
-    //     int min_level = 1; // min level for start triplet. So min track length = min_level+3.
-    //     if (isec == kAllPrimJumpIter) min_level = 1;
-    //     if ( (isec == kAllSecIter) || (isec == kAllSecJumpIter) ) min_level = 2; // only the long low momentum tracks
-    // //    if (isec == -1) min_level = fParameters.GetNstationsActive() - 3 - 3; //only the longest tracks
-
-
     L1Branch curr_tr;
     L1Branch new_tr[L1Constants::size::kMaxNstations];
     L1Branch best_tr;
@@ -2177,30 +2165,26 @@ void L1Algo::CATrackFinder()
                 || fvHitKeyFlags[(*vHitsUnused)[first_trip.GetLHit()].b]) {
               continue;
             }
-//               ghost suppression !!!
-#ifndef FIND_GAPED_TRACKS
-            if (/*(isec == kFastPrimIter) ||*/ (isec == kAllPrimIter) || (isec == kAllPrimEIter)
-                || (isec == kAllSecIter) || (isec == kAllSecEIter) || (isec == kAllSecJumpIter)) {
-#else
-            if ((isec == kFastPrimIter) || (isec == kFastPrimIter2) || (isec == kFastPrimJumpIter)
-                || (isec == kAllPrimIter) || (isec == kAllPrimEIter) || (isec == kAllPrimJumpIter)
-                || (isec == kAllSecIter) || (isec == kAllSecEIter) || (isec == kAllSecJumpIter)) {
-#endif
-              if (!fpCurrentIteration->GetTrackFromTripletsFlag()) {  // ghost suppression !!!
-                // TODO: Primary => 3 hits tracks are saved, otherwise 3 hit tracks are thrown away
-                if (isec != kFastPrimIter && isec != kAllPrimIter && isec != kAllPrimEIter && isec != kAllSecEIter)
-                  if (first_trip.GetLevel() == 0)
-                    continue;  //ghost suppression//find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet
-
-                if (kGlobal != fTrackingMode && kMcbm != fTrackingMode) {
-                  if ((firstTripletLevel == 0) && ((*vHitsUnused)[first_trip.GetLHit()].iSt != 0))
-                    continue;  // ghost supression // collect only MAPS tracks-triplets  CHECK!!!
-                }
+            //               ghost suppression !!!
+            //
+
+            if (!fpCurrentIteration->GetTrackFromTripletsFlag()) {  // ghost suppression !!!
+
+              if (fpCurrentIteration->GetSuppressGhostFlag()) {
+                if (first_trip.GetLevel() == 0)
+                  continue;  //ghost suppression//find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet
+              }
+
+              if (kGlobal != fTrackingMode && kMcbm != fTrackingMode) {
+                if ((firstTripletLevel == 0) && ((*vHitsUnused)[first_trip.GetLHit()].iSt != 0))
+                  continue;  // ghost supression // collect only MAPS tracks-triplets  CHECK!!!
               }
-              if (first_trip.GetLevel() < firstTripletLevel)
-                continue;  // try only triplets, which can start track with firstTripletLevel+3 length. w\o it have more ghosts, but efficiency either
             }
 
+            // Collect triplets, which can start a track with length equal to firstTipletLevel + 3. This cut suppresses
+            // ghost tracks, but does not affect the efficiency
+            if (first_trip.GetLevel() < firstTripletLevel) { continue; }
+
             //  curr_tr.Momentum = 0.f;
             curr_tr.chi2 = 0.f;
             //   curr_tr.Lengtha  = 0;
@@ -2231,11 +2215,8 @@ void L1Algo::CATrackFinder()
 
             if (fGhostSuppression) {
               if (3 == best_L) {
-                // if( isec == kAllSecIter ) continue; // too /*short*/ secondary track
-                if (((isec == kAllSecIter) || (isec == kAllSecEIter) || (isec == kAllSecJumpIter)) && (istaF != 0))
-                  continue;  // too /*short*/ non-MAPS track
-                if ((isec != kAllSecIter) && (isec != kAllSecEIter) && (isec != kAllSecJumpIter) && (best_chi2 > 5.0))
-                  continue;
+                if (!fpCurrentIteration->GetPrimaryFlag() && (istaF != 0)) continue;  // too /*short*/ non-MAPS track
+                if (fpCurrentIteration->GetPrimaryFlag() && (best_chi2 > 5.0)) continue;
               }
             }
             fTrackCandidates[thread_num].push_back(best_tr);
@@ -2698,10 +2679,11 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best
 
     if (curr_chi2 > fTrackChi2Cut * ndf) return;
 
+    // TODO: SZh 04.10.2022: Does one should delete this code?
     //       // try to find more hits
     // if (fpCurrentIteration->GetExtendTracksFlag()) {
     //     // if( curr_L < min_best_l )
-    //     if (isec != kFastPrimJumpIter && isec != kAllPrimJumpIter && isec != kAllSecJumpIter && curr_L >= 3){
+    //     if (!fpCurrentIteration->GetJumpedFlag() && curr_L >= 3){
     //       //curr_chi2 = BranchExtender(curr_tr);
     //       BranchExtender(curr_tr);
     //       curr_L = curr_tr.Hits.size();
@@ -2785,12 +2767,6 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best
         if (dtx > fPickNeighbour * sqrt(Ctx)) continue;
       }
 
-      //if (GetFUsed((*fStripFlag)[(*vHitsUnused)[new_trip.GetLHit()].f]
-      //             | (*fStripFlag)[(*vHitsUnused)[new_trip.GetLHit()].b])) {  //hits are used
-      //L1_SHOW(fInputData.GetNhitKeys());
-      //L1_SHOW(fvHitKeyFlags.size());
-      //L1_SHOW((*vHitsUnused)[new_trip.GetLHit()].f);
-      //L1_SHOW((*vHitsUnused)[new_trip.GetLHit()].b);
       if (fvHitKeyFlags[(*vHitsUnused)[new_trip.GetLHit()].f]
           || fvHitKeyFlags[(*vHitsUnused)[new_trip.GetLHit()].b]) {  //hits are used
         //  no used hits allowed -> compare and store track
diff --git a/reco/L1/L1Algo/L1ConfigExample.yaml b/reco/L1/L1Algo/L1ConfigExample.yaml
index cdc1b2c7c8..4ded80ef8f 100644
--- a/reco/L1/L1Algo/L1ConfigExample.yaml
+++ b/reco/L1/L1Algo/L1ConfigExample.yaml
@@ -22,10 +22,15 @@ l1:
         max_slope:             2.748
         max_dz:                0. # cm
         min_start_triplet_lvl: 0
+        first_station_index:   0
         target_pos_sigma_x:    1. # cm
         target_pos_sigma_y:    1. # cm
         is_primary:            true
         is_electron:           false
+        is_jumped:             false
+        if_extend_tracks:       true
+        if_suppress_ghost:      false
+        is_track_from_triplets: false
       - name: "AllPrimIter"
         track_chi2_cut:        10.
         triplet_chi2_cut:      23.4450
@@ -37,10 +42,15 @@ l1:
         max_slope:             2.748
         max_dz:                0.1 # cm
         min_start_triplet_lvl: 0
+        first_station_index:   0
         target_pos_sigma_x:    1. # cm
         target_pos_sigma_y:    1. # cm
         is_primary:            true
         is_electron:           false
+        is_jumped:             false
+        if_extend_tracks:       true
+        if_suppress_ghost:      false
+        is_track_from_triplets: false
       - name: "AllPrimJumpIter"
         track_chi2_cut:        10.
         triplet_chi2_cut:      18.7560
@@ -52,10 +62,15 @@ l1:
         max_slope:             2.748
         max_dz:                0.1 # cm
         min_start_triplet_lvl: 0
+        first_station_index:   0
         target_pos_sigma_x:    5. # cm
         target_pos_sigma_y:    5. # cm
         is_primary:            true
         is_electron:           false
+        is_jumped:             true
+        if_extend_tracks:       true
+        if_suppress_ghost:      true
+        is_track_from_triplets: false
       - name: "AllSecIter"
         track_chi2_cut:        10.
         triplet_chi2_cut:      18.7560
@@ -67,8 +82,13 @@ l1:
         max_slope:             2.748
         max_dz:                0.1 # cm
         min_start_triplet_lvl: 1
+        first_station_index:   0
         target_pos_sigma_x:    10. # cm
         target_pos_sigma_y:    10. # cm
         is_primary:            false
         is_electron:           false
+        is_jumped:             false
+        if_extend_tracks:       true    
+        if_suppress_ghost:      true
+        is_track_from_triplets: false
 ...
diff --git a/reco/L1/L1Algo/L1ConfigRW.cxx b/reco/L1/L1Algo/L1ConfigRW.cxx
index 6f3c55da21..1a8f30ef6e 100644
--- a/reco/L1/L1Algo/L1ConfigRW.cxx
+++ b/reco/L1/L1Algo/L1ConfigRW.cxx
@@ -53,6 +53,7 @@ void L1ConfigRW::ReadCAIterations(const YAML::Node& node)
       LOG(info) << "L1 config: Reading CA tracking iterations sequence. Default iterations will be ignored";
     }
     fpInitManager->ClearCAIterations();
+    L1_SHOW(node.size());
     fpInitManager->SetCAIterationsNumberCrosscheck(node.size());
     if (fVerbose > 2) { LOG(info) << "L1 config: " << fVerbose << " CA iterations were recorded"; }
     if (fVerbose > 3) { LOG(info) << "L1 config: Recorded iterations:"; }
@@ -61,19 +62,25 @@ void L1ConfigRW::ReadCAIterations(const YAML::Node& node)
     for (const auto& input : node) {
       try {
         auto caIter = L1CAIteration(input["name"].as<std::string>());
-        caIter.SetTrackChi2Cut(input["track_chi2_cut"].as<float>());
-        caIter.SetTripletChi2Cut(input["triplet_chi2_cut"].as<float>());
-        caIter.SetDoubletChi2Cut(input["doublet_chi2_cut"].as<float>());
-        caIter.SetPickGather(input["pick_gather"].as<float>());
-        caIter.SetPickNeighbour(input["pick_neighbour"].as<float>());
-        caIter.SetMaxInvMom(1. / input["min_momentum"].as<float>());
-        caIter.SetMaxSlopePV(input["max_slope_pv"].as<float>());
-        caIter.SetMaxSlope(input["max_slope"].as<float>());
-        caIter.SetMaxDZ(input["max_dz"].as<float>());
-        caIter.SetTargetPosSigmaXY(input["target_pos_sigma_x"].as<float>(), input["target_pos_sigma_y"].as<float>());
-        caIter.SetMinLevelTripletStart(input["min_start_triplet_lvl"].as<int>());
-        caIter.SetPrimaryFlag(input["is_primary"].as<bool>());
-        caIter.SetElectronFlag(input["is_electron"].as<bool>());
+        caIter.SetTrackChi2Cut(input["track_chi2_cut"].as<float>(caIter.GetTrackChi2Cut()));
+        caIter.SetTripletChi2Cut(input["triplet_chi2_cut"].as<float>(caIter.GetTripletChi2Cut()));
+        caIter.SetDoubletChi2Cut(input["doublet_chi2_cut"].as<float>(caIter.GetDoubletChi2Cut()));
+        caIter.SetPickGather(input["pick_gather"].as<float>(caIter.GetPickGather()));
+        caIter.SetPickNeighbour(input["pick_neighbour"].as<float>(caIter.GetPickNeighbour()));
+        caIter.SetMaxInvMom(1. / input["min_momentum"].as<float>(caIter.GetMaxInvMom()));
+        caIter.SetMaxSlopePV(input["max_slope_pv"].as<float>(caIter.GetMaxSlopePV()));
+        caIter.SetMaxSlope(input["max_slope"].as<float>(caIter.GetMaxSlope()));
+        caIter.SetMaxDZ(input["max_dz"].as<float>(caIter.GetMaxDZ()));
+        caIter.SetTargetPosSigmaXY(input["target_pos_sigma_x"].as<float>(caIter.GetTargetPosSigmaX()),
+                                   input["target_pos_sigma_y"].as<float>(caIter.GetTargetPosSigmaY()));
+        caIter.SetFirstStationIndex(input["first_station_index"].as<int>(caIter.GetFirstStationIndex()));
+        caIter.SetMinLevelTripletStart(input["min_start_triplet_lvl"].as<int>(caIter.GetMinLevelTripletStart()));
+        caIter.SetPrimaryFlag(input["is_primary"].as<bool>(caIter.GetPrimaryFlag()));
+        caIter.SetElectronFlag(input["is_electron"].as<bool>(caIter.GetElectronFlag()));
+        caIter.SetTrackFromTripletsFlag(input["is_track_from_triplets"].as<bool>(caIter.GetTrackFromTripletsFlag()));
+        caIter.SetExtendTracksFlag(input["if_extend_tracks"].as<bool>(caIter.GetExtendTracksFlag()));
+        caIter.SetJumpedFlag(input["is_jumped"].as<bool>(caIter.GetJumpedFlag()));
+        caIter.SetSuppressGhostFlag(input["if_suppress_ghost"].as<bool>(caIter.GetSuppressGhostFlag()));
         if (fVerbose > 3) { LOG(info) << "L1 config:\n" << caIter.ToString(1); }
         fpInitManager->PushBackCAIteration(caIter);
       }
@@ -103,8 +110,14 @@ void L1ConfigRW::ReadYaml(const std::string& filename)
     config = YAML::LoadFile(filename);
   }
   catch (const YAML::BadFile& exc) {
-    LOG(error) << "L1 config: tracking parameters file \"" << filename << "\" does not exist, default will be used";
-    return;
+    std::stringstream msg;
+    msg << "file does not exist";
+    throw std::runtime_error(msg.str());
+  }
+  catch (const YAML::ParserException& exc) {
+    std::stringstream msg;
+    msg << "file is formatted improperly";
+    throw std::runtime_error(msg.str());
   }
 
   // Tracking iterations
diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx
index 7249fe6df3..c237a76cee 100644
--- a/reco/L1/L1Algo/L1InitManager.cxx
+++ b/reco/L1/L1Algo/L1InitManager.cxx
@@ -157,14 +157,23 @@ bool L1InitManager::FormParametersContainer()
   // Read configuration file
   // NOTE: We consider parameters from the configuration file as ones with a higher priority, so all the defined
   //       variables there would be rewritten by the configuration
-  if (fConfigInputName != "") { fConfigRW.ReadYaml(fConfigInputName); }
+  try {
+    if (fConfigInputName != "") { fConfigRW.ReadYaml(fConfigInputName); }
+    LOG(info) << "L1InitManager: parameters configuration file \"" << fConfigInputName << "\" was loaded";
+  }
+  catch (const std::runtime_error& err) {
+    LOG(error) << "L1InitManager: parameters configuration file \"" << fConfigInputName << "\" was defined, "
+               << "but the loading failed. Reason: " << err.what();
+    return false;
+  }
 
   // Check initialization
   this->CheckInit();
 
   if (!fInitController.IsFinalized()) {
-    LOG(fatal) << "Attempt to form parameters container before all necessary fields were initialized"
+    LOG(error) << "L1InitManager: Attempt to form parameters container before all necessary fields were initialized"
                << fInitController.ToString();
+    return false;
   }
 
   // Form array of stations
diff --git a/reco/L1/L1Algo/L1Parameters.cxx b/reco/L1/L1Algo/L1Parameters.cxx
index 9f00df300f..0ee8740a0c 100644
--- a/reco/L1/L1Algo/L1Parameters.cxx
+++ b/reco/L1/L1Algo/L1Parameters.cxx
@@ -239,8 +239,15 @@ void L1Parameters::CheckConsistency() const
    *  2. If this iteration exists, it should be the last one in the sequence
    */
   {
-    int nIterations = std::count_if(fCAIterations.begin(), fCAIterations.end(),
-                                    [=](const L1CAIteration& it) { return it.GetTrackFromTripletsFlag(); });
+    int nIterations = fCAIterations.size();
+    if (!nIterations) {
+      std::stringstream msg;
+      msg << "L1Parameters: 0 track finder iterations were found. Please, define at least one iteration";
+      throw std::logic_error(msg.str());
+    }
+
+    nIterations = std::count_if(fCAIterations.begin(), fCAIterations.end(),
+                                [=](const L1CAIteration& it) { return it.GetTrackFromTripletsFlag(); });
     if (nIterations > 1) {
       std::stringstream msg;
       msg << "L1Parameters: found " << nIterations << " iterations with GetTrackFromTripletsFlag() == true:\n";
diff --git a/reco/L1/L1Algo/L1TrackExtender.cxx b/reco/L1/L1Algo/L1TrackExtender.cxx
index df3b68aa7a..37dffaf8c8 100644
--- a/reco/L1/L1Algo/L1TrackExtender.cxx
+++ b/reco/L1/L1Algo/L1TrackExtender.cxx
@@ -89,9 +89,7 @@ void L1Algo::BranchFitterFast(const L1Branch& t, L1TrackPar& T, const bool dir,
   T.C11  = sta0.XYInfo.C11;
 
   if constexpr (L1Constants::control::kIfSaveHitErrorsInTrackExtender) {
-    T.C00 = hit0.dx * hit0.dx;
-    T.C10 = hit0.dxy;
-    T.C11 = hit0.dy * hit0.dy;
+    std::tie(T.C00, T.C10, T.C11) = sta0.FormXYCovarianceMatrix(hit0.du, hit0.dv);
   }
 
   T.C20 = T.C21 = 0;
-- 
GitLab