Skip to content
Snippets Groups Projects
  • Sergei Zharko's avatar
    9d898740
    CA: Reorganisation of tracking iterations initialization · 9d898740
    Sergei Zharko authored
    A CA iteration (L1CAIteration class) represents a set of parameters, dependent from the particular track finder
    running step. Previously, default iterations were initialized in the CbmL1::Init function with hard-coded values.
    Now, the default iteration list is provided in the in the configuration file. At the moment there are three
    main configuration files:
       ${VMCWORKDIR}/macro/L1/configs/ca_params_sts.yaml    -- L1Algo::TrackingMode::kSts
       ${VMCWORKDIR}/macro/L1/configs/ca_params_mcbm.yaml   -- L1Algo::TrackingMode::kMcbm
       ${VMCWORKDIR}/macro/L1/configs/ca_params_global.yaml -- L1Algo::TrackingMode::kGlobal
    9d898740
    History
    CA: Reorganisation of tracking iterations initialization
    Sergei Zharko authored
    A CA iteration (L1CAIteration class) represents a set of parameters, dependent from the particular track finder
    running step. Previously, default iterations were initialized in the CbmL1::Init function with hard-coded values.
    Now, the default iteration list is provided in the in the configuration file. At the moment there are three
    main configuration files:
       ${VMCWORKDIR}/macro/L1/configs/ca_params_sts.yaml    -- L1Algo::TrackingMode::kSts
       ${VMCWORKDIR}/macro/L1/configs/ca_params_mcbm.yaml   -- L1Algo::TrackingMode::kMcbm
       ${VMCWORKDIR}/macro/L1/configs/ca_params_global.yaml -- L1Algo::TrackingMode::kGlobal
L1CAIteration.h 15.68 KiB
/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
   SPDX-License-Identifier: GPL-3.0-only
   Authors: Sergey Gorbunov, Sergei Zharko [committer] */

/***************************************************************************************************
 * @file   L1CAIteration.h
 * @brief  Declaration of the L1CAIteration class 
 * @since  05.02.2022
 * @author S.Zharko <s.zharko@gsi.de>
 ***************************************************************************************************/

#ifndef L1CAIteration_h
#define L1CAIteration_h 1

#include <Logger.h>

#include <boost/serialization/access.hpp>
#include <boost/serialization/string.hpp>

#include <bitset>
#include <iomanip>
#include <string>

// TODO: discuss the border conditions for the parameters. Implement them (S.Zharko)
//       Implementation: use tuples for boundary conditions of the parameters
/// Class L1CAIteration describes L1 Track finder iteration.
/// Each iteration utilizes special physics cuts and run condition to find tracks of a particular
/// class (e.g., fast primary tracks or secondary electron tracks). Hits associated with tracks
/// reconstructed during current iteration are removed from the further iterations.
///
class L1CAIteration {
public:
  /// Default constructor
  L1CAIteration() = default;

  /// Copy constructor
  L1CAIteration(const L1CAIteration& other) = default;

  /// Copy constructor
  L1CAIteration(const L1CAIteration& other, const std::string& name) : L1CAIteration(other) { SetName(name); }

  /// Move constructor
  L1CAIteration(L1CAIteration&& other) noexcept = default;

  /// Constructor from L1CAIteration type
  L1CAIteration(const std::string& name);

  /// Destructor
  ~L1CAIteration() noexcept = default;

  /// Copy assignment operator
  L1CAIteration& operator=(const L1CAIteration& other) = default;

  /// Move assignment operator
  L1CAIteration& operator=(L1CAIteration&& other) = default;

  /// Checks parameters consistency
  bool Check() const;

  /// @brief Gets doublet chi2 upper cut
  float GetDoubletChi2Cut() const { return fDoubletChi2Cut; }

  /// @brief flag check: electrons/positrons - true, heavy charged - false
  bool GetElectronFlag() const { return fIsElectron; }

  /// @brief Sets flag: true - extends track candidates with unused hits
  bool GetExtendTracksFlag() const { return fIsExtendTracks; }

  /// @brief Gets station index of the first station used in tracking
  int GetFirstStationIndex() const { return fFirstStationIndex; }

  /// @brief Gets flag: true - triplets are built skipping one station
  bool GetJumpedFlag() const { return fIsJumped; }

  /// @brief Gets correction for accounting overlaping and iff z
  float GetMaxDZ() const { return fMaxDZ; }

  /// @brief Gets max considered q/p for tracks
  float GetMaxQp() const { return fMaxQp; }

  /// @brief Gets max slope (tx\ty) in 3D hit position of a triplet
  float GetMaxSlope() const { return fMaxSlope; }

  /// @brief Gets max slope (tx\ty) in primary vertex
  float GetMaxSlopePV() const { return fMaxSlopePV; }

  /// @brief Gets min n hits
  int GetMinNhits() const { return fMinNhits; }

  /// @brief Gets min n hits for tracks that start on station 0
  int GetMinNhitsStation0() const { return fMinNhitsStation0; }

  /// @brief Gets the name of the iteration
  const std::string& GetName() const { return fName; }

  /// @brief Gets size of region [TODO: units??] to attach new hits to the created track
  float GetPickGather() const { return fPickGather; }

  /// @brief Checks flag: true - only primary tracks are searched, false - [all or only secondary?]
  bool GetPrimaryFlag() const { return fIsPrimary; }

  /// @brief Gets sigma target position in X direction [cm]
  float GetTargetPosSigmaX() const { return fTargetPosSigmaX; }

  /// @brief Gets sigma target position in Y direction [cm]
  float GetTargetPosSigmaY() const { return fTargetPosSigmaY; }

  /// @brief Gets track chi2 upper cut
  float GetTrackChi2Cut() const { return fTrackChi2Cut; }

  /// (DEBUG!) Sets flag:
  ///   true:
  ///     all the triplets found on this iteration will be converted to tracks,
  ///     all the iterations following after this one will be rejected from the
  ///     iterations sequence;
  ///   false (default):
  ///     tracks are built from triplets, and the minimal amount of hits used in
  ///     each track equals four. In case of primary tracks the first measurement
  ///     is taken from the target, and the other three measurements are taken from
  ///     the triplet.
  bool GetTrackFromTripletsFlag() const { return fIsTrackFromTriplets; }

  /// @brief Gets triplet chi2 upper cut
  float GetTripletChi2Cut() const { return fTripletChi2Cut; }

  /// @brief Gets triplet chi2 upper cut
  float GetTripletFinalChi2Cut() const { return fTripletFinalChi2Cut; }

  /// @brief Gets min value of dp/dp_error, for which two tiplets are neighbours
  float GetTripletLinkChi2() const { return fTripletLinkChi2; }

  /// @brief Prints iteration options
  void Print(int verbosityLevel = 0) const;

  /// @brief Sets doublet chi2 upper cut
  void SetDoubletChi2Cut(float input) { fDoubletChi2Cut = input; }

  /// @brief Sets flag: electron tracks - true, heavy ion tracks - false
  void SetElectronFlag(bool flag) { fIsElectron = flag; }
  /// @brief Sets flag: true - extends track candidates with unused hits
  void SetExtendTracksFlag(bool flag) { fIsExtendTracks = flag; }

  /// @brief Sets index of first station used in tracking
  void SetFirstStationIndex(int index) { fFirstStationIndex = index; }

  /// @brief Sets flag: true - triplets are built from hits .... TODO
  void SetJumpedFlag(bool flag) { fIsJumped = flag; }

  /// @brief Sets correction for accounting overlaping and iff z
  void SetMaxDZ(float input) { fMaxDZ = input; }

  /// @brief Sets max considered q/p for tracks
  void SetMaxQp(float input) { fMaxQp = input; }

  /// @brief Sets max slope (tx\ty) in 3D hit position of a triplet
  void SetMaxSlope(float input) { fMaxSlope = input; }

  /// @brief Sets max slope (tx\ty) in primary vertex
  void SetMaxSlopePV(float input) { fMaxSlopePV = input; }

  /// @brief Sets flag: true - skip track candidates with level = 0
  void SetMinNhits(int val) { fMinNhits = val; }

  /// @brief Sets min n hits for tracks that start on station 0
  void SetMinNhitsStation0(int val) { fMinNhitsStation0 = val; }

  /// @brief Sets name of the iteration
  void SetName(const std::string& name) { fName = name; }

  /// @brief Sets size of region [TODO: units??] to attach new hits to the created track
  void SetPickGather(float input) { fPickGather = input; }

  /// @brief Sets flag: primary tracks - true, secondary tracks - false
  void SetPrimaryFlag(bool flag) { fIsPrimary = flag; }

  /// @brief  Sets sigma of target positions in XY plane
  /// @param  sigmaX  Sigma value in X direction [cm]
  /// @param  sigmaX  Sigma value in Y direction [cm]
  void SetTargetPosSigmaXY(float sigmaX, float sigmaY);

  /// Sets track chi2 upper cut
  void SetTrackChi2Cut(float input) { fTrackChi2Cut = input; }

  /// (DEBUG!) Sets flag:
  ///   true:
  ///     all the triplets found on this iteration will be converted to tracks,
  ///     all the iterations following after this one will be rejected from the
  ///     iterations sequence;
  ///   false (default):
  ///     tracks are built from triplets, and the minimal amount of hits used in
  ///     each track equals four. In case of primary tracks the first measurement
  ///     is taken from the target, and the other three measurements are taken from
  ///     the triplet.
  void SetTrackFromTripletsFlag(bool flag) { fIsTrackFromTriplets = flag; }

  /// Sets triplet chi2 upper cut
  void SetTripletChi2Cut(float input) { fTripletChi2Cut = input; }

  /// Sets triplet chi2 upper cut
  void SetTripletFinalChi2Cut(float input) { fTripletFinalChi2Cut = input; }

  /// @brief Sets min value of dp/dp_error, for which two tiplets are neighbours
  void SetTripletLinkChi2(float input) { fTripletLinkChi2 = input; }

  /// @brief String representation of the class contents
  /// @param indentLevel  Level of indentation for the text (in terms of \t symbols)
  std::string ToString(int indentLevel = 0) const;

  /// @brief  Formes a strings, representing a table of iterations from the vector of iterations
  /// @param  vIterations  Vector of iterations
  /// @return Iterations table represented with a string
  template<typename T>
  static std::string ToTableFromVector(const T& vIterations);

private:
  /** Basic fields **/
  std::string fName {""};  ///< Iteration name

  /** Track finder dependent cuts **/
  // TODO: Iteratively change the literals to floats (S.Zharko)
  // 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 fTripletFinalChi2Cut = 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 fTripletLinkChi2     = 25.0;       ///< Min value of dp^2/dp_error^2, for which two tiplets are neighbours
  float fMaxQp               = 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 fFirstStationIndex     = 0;          ///< First station, used for tracking
  int fMinNhits              = 3;          ///< min n hits on the tracks
  int fMinNhitsStation0      = 3;          ///< min n hits for tracks that start on station 0
  bool fIsPrimary            = false;      ///< Flag: true - only primary tracks are searched for
  bool fIsElectron           = false;      ///< Flag: true - only electrons are searched for
  bool fIsExtendTracks       = false;      ///< Flag: true - extends track candidates with unused hits
  bool fIsJumped             = false;      ///< Flag: true - find triplets with skip station


  /// @brief Flag to select triplets on the iteration as tracks
  ///   In ordinary cases, the shortest track consists from four hits. For primary track the target is accounted as
  /// the first hit, and the other three hits are taken from the stations. For secondary track all the hits are selected
  /// from the stations only.
  ///   If the fIsTrackFromTriplets flag is turned on, all of the triplets found on this iterations will be considered
  /// as tracks.
  ///
  /// @note The only one iteration with the fIsTrackFromTriplets flag turned on can exist in the tracking iterations
  ///       sequence and this iteration should be the last in the tracking sequence.
  bool fIsTrackFromTriplets = 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& fTripletFinalChi2Cut;
    ar& fDoubletChi2Cut;
    ar& fPickGather;
    ar& fTripletLinkChi2;
    ar& fMaxQp;
    ar& fMaxSlopePV;
    ar& fMaxSlope;
    ar& fMaxDZ;
    ar& fTargetPosSigmaX;
    ar& fTargetPosSigmaY;
    ar& fFirstStationIndex;
    ar& fMinNhits;
    ar& fMinNhitsStation0;
    ar& fIsPrimary;
    ar& fIsElectron;
    ar& fIsExtendTracks;
    ar& fIsJumped;
    ar& fIsTrackFromTriplets;
  }

  /// @brief  Checks, if a particular value lies within selected limits. In case of fail throws std::logic_error
  /// @param  name   Name of parameters
  /// @param  value  Value of parameter
  /// @param  lLimit Lower limit of parameter
  /// @param  uLimit Upper limit of parameter
  template<typename T>
  static bool CheckValueLimits(const std::string& name, T value, T lLimit, T uLimit);
};

// ---------------------------------------------------------------------------------------------------------------------
//
template<typename T>
std::string L1CAIteration::ToTableFromVector(const T& vIterations)
{
  std::stringstream msg;
  msg << std::boolalpha;

  auto PutRow = [&](const std::string& name, std::function<void(const L1CAIteration&)> fn) {
    msg << std::setw(40) << std::setfill(' ') << name << ' ';
    for (const auto& iter : vIterations) {
      msg << std::setw(12) << std::setfill(' ');
      fn(iter);
      msg << ' ';
    }
    msg << '\n';
  };

  PutRow("                                   ", [&](const L1CAIteration& i) { msg << i.GetName(); });
  PutRow("Is primary                         ", [&](const L1CAIteration& i) { msg << i.GetPrimaryFlag(); });
  PutRow("Is electron                        ", [&](const L1CAIteration& i) { msg << i.GetElectronFlag(); });
  PutRow("If tracks created from triplets    ", [&](const L1CAIteration& i) { msg << i.GetTrackFromTripletsFlag(); });
  PutRow("If tracks extended with unused hits", [&](const L1CAIteration& i) { msg << i.GetExtendTracksFlag(); });
  PutRow("If triplets jump over one station  ", [&](const L1CAIteration& i) { msg << i.GetJumpedFlag(); });
  PutRow("Min number of hits                 ", [&](const L1CAIteration& i) { msg << i.GetMinNhits(); });
  PutRow("Min number of hits on station 0    ", [&](const L1CAIteration& i) { msg << i.GetMinNhitsStation0(); });
  PutRow("Track chi2 cut                     ", [&](const L1CAIteration& i) { msg << i.GetTrackChi2Cut(); });
  PutRow("Triplet chi2 cut                   ", [&](const L1CAIteration& i) { msg << i.GetTripletChi2Cut(); });
  PutRow("Triplet final chi2 cut             ", [&](const L1CAIteration& i) { msg << i.GetTripletFinalChi2Cut(); });
  PutRow("Doublet chi2 cut                   ", [&](const L1CAIteration& i) { msg << i.GetDoubletChi2Cut(); });
  PutRow("Pick gather                        ", [&](const L1CAIteration& i) { msg << i.GetPickGather(); });
  PutRow("Triplet link chi2                  ", [&](const L1CAIteration& i) { msg << i.GetTripletLinkChi2(); });
  PutRow("Max q/p                            ", [&](const L1CAIteration& i) { msg << i.GetMaxQp(); });
  PutRow("Max slope                          ", [&](const L1CAIteration& i) { msg << i.GetMaxSlope(); });
  PutRow("Max slope at primary vertex        ", [&](const L1CAIteration& i) { msg << i.GetMaxSlopePV(); });
  PutRow("Max DZ                             ", [&](const L1CAIteration& i) { msg << i.GetMaxDZ(); });
  PutRow("Target position sigma X [cm]       ", [&](const L1CAIteration& i) { msg << i.GetTargetPosSigmaX(); });
  PutRow("Target position sigma Y [cm]       ", [&](const L1CAIteration& i) { msg << i.GetTargetPosSigmaY(); });
  PutRow("First tracking station index       ", [&](const L1CAIteration& i) { msg << i.GetFirstStationIndex(); });

  return msg.str();
}

// ---------------------------------------------------------------------------------------------------------------------
// TODO: SZh. 06.10.2022: Probably, this method should be replaced to L1Utils
template<typename T>
bool L1CAIteration::CheckValueLimits(const std::string& name, T value, T lLimit, T uLimit)
{
  if (value < lLimit || value > uLimit) {
    LOG(error) << "parameter\033[1;32m" << name << "\033[0m (" << value << ") runs out of range: [" << lLimit << ','
               << uLimit << ']';
    return false;
  }
  return true;
}

#endif  // L1CAIteration_h