diff --git a/core/qa/CbmQaIO.h.orig b/core/qa/CbmQaIO.h.orig deleted file mode 100644 index 6bd4475159ade4a9293de3dbb1cd81ebb8559a66..0000000000000000000000000000000000000000 --- a/core/qa/CbmQaIO.h.orig +++ /dev/null @@ -1,380 +0,0 @@ -/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt - SPDX-License-Identifier: GPL-3.0-only - Authors: Sergei Zharko [committer] */ - -/// @file CbmQaIO.h -/// @brief Module for ROOT objects IO interface (header) -/// @author S.Zharko <s.zharko@gsi.de> -/// @since 29.03.2023 - -#ifndef CbmQaIO_h -#define CbmQaIO_h 1 - -#include "CbmQaCanvas.h" -#include "CbmQaEff.h" -#include "CbmQaTable.h" - -#include "Logger.h" - -#include "TCanvas.h" -#include "TEfficiency.h" -#include "TH1.h" -#include "TH2.h" -#include "TH3.h" -#include "TObject.h" -#include "TParameter.h" -#include "TProfile.h" -#include "TProfile2D.h" -#include "TProfile3D.h" -#include "TROOT.h" -#include "TString.h" - -#include <limits> -#include <type_traits> -#include <vector> - -<<<<<<< HEAD -======= -#include <yaml-cpp/yaml.h> ->>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd - -class TFile; - -/// @brief ROOT object IO interface for QA -/// -/// The class provides interface to write ROOT object into resulted files -class CbmQaIO { -public: - using ObjList_t = std::vector<std::pair<TObject*, TString>>; - - enum class EStoringMode - { - kSAMEDIR, ///< Objects of different type will be stored to root directory - kSUBDIR ///< Objects of different type will be stored in different subdirectories like histograms/ canvases/ - }; - - /// @brief Constructor - /// @param prefixName Name of the unique prefix - /// @param pObjList List of already created objects - CbmQaIO(TString prefixName, std::shared_ptr<ObjList_t> pObjList = nullptr); - - /// @brief Destructor - virtual ~CbmQaIO(); - - /// @brief Copy constructor - CbmQaIO(const CbmQaIO&) = delete; - - /// @brief Move constructor - CbmQaIO(CbmQaIO&&) = delete; - - /// @brief Copy assignment operator - CbmQaIO& operator=(const CbmQaIO&) = delete; - - /// @brief Move assignment operator - CbmQaIO& operator=(CbmQaIO&&) = delete; - -<<<<<<< HEAD - /// Set storing mode - void SetStoringMode(EStoringMode val) { fStoringMode = val; } - - /// @brief Sets a common root path to the objects in the output file - /// @param path A path to the object - void SetRootFolderName(TString path) { fsRootFolderName = path; } - - /// @brief Creates a ROOT object - /// @param name Name of the object including the path - /// @param args... Arguments passed to the object constructor - template<typename T, typename... Args> - T* MakeQaObject(TString name, Args... args); -======= - /// @brief Gets config name - const char* GetConfigName() const { return fsConfigName.Data(); } ->>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd - - /// @brief Creates, initializes and registers a canvas - /// @tparam T Type of the canvas: TCanvas or CbmQaCanvas (\note T should not be a pointer) - /// @param name Name of canvas - /// @param args The rest of the arguments, which will be passed to the canvas constructor - template<typename T, typename... Args> - T* MakeCanvas(TString name, Args... args); - - /// @brief Creates, initializes and registers an efficiency - /// @tparam T Type of the canvas: either TProfile, TProfile1D or TEfficiency (\note T should not be a pointer) - /// @param name Name of canvas - /// @param args The rest of the arguments, which will be passed to the efficiency constructor - template<typename T, typename... Args> - T* MakeEfficiency(TString name, Args... args); - - /// @brief Creates, initializes and registers a histogram - /// @tparam T Type of the histogram (\note T should not be a pointer) - /// @param name Name of histogram - /// @param args The rest of the arguments, which will be passed to the histogram constructor - template<typename T, typename... Args> - T* MakeHisto(TString name, Args... args); - - /// @brief Creates histogram, using properties defined with a tag in config - /// @param nameBase Name of the histogram - /// @param args The rest of the arguments, which will be passed to the histogram constructor - /// @note Tag is defined after the last ';' symbol in the nameBase string - /// @example - /// nambeBase = "/foo/bar/hit_xy_occupancy_station0;xy_station0" will be decayed into: - /// 1) subdirectory /foo/bar - /// 2) name of histogram "catrd_hit_xy_occupancy_station0" - /// 3) tag for configuration file "xy_station0" - /// If configuration file or tag are not defined, default parameters will be used - template<typename T, typename... Args> - T* MakeHistoConfig(const char* nameBase, const char* title, Args... args); - - /// @brief Creates, initializes and registers a table - /// @param name Name of the table - /// @param args The rest of the arguments, which will be passed to the table constructor - template<typename... Args> - CbmQaTable* MakeTable(TString name, Args... args); - -<<<<<<< HEAD -======= - /// @brief Creates a ROOT object - /// @param name Name of the object - /// @param args... Arguments passed to the object constructor - template<typename T, typename... Args> - T* MakeObject(const char* name, Args... args); - - /// @brief Sets config name - /// @param name A path to the config - void SetConfigName(const char* path); - - /// @brief Sets a common root path to the objects in the output file - /// @param path A path to the object - void SetRootFolderName(const char* path) { fsRootFolderName = path; } ->>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd - -protected: - /// @brief Function to check, if a property is defined - /// @param property A property to be tested - /// @param name A name of property (used for logging) - /// @note Throws an exception, if property is undefined - template<typename T> - void CheckProperty(T&& property, const char* name) const; - - /// @brief Applies properties on the histogram created with MakeHisto funciton - /// @param pHist Pointer to histogram - virtual void SetHistoProperties(TH1* /*pHits*/); - - /// @brief Writes objects into file - /// @param pOutFile Pointer to output ROOT file - void WriteToFile(TFile* pOutFile) const; - - - TString fsRootFolderName = ""; ///< Name of root folder - TString fsConfigName = ""; ///< Name of configuration file - TString fsPrefix = ""; ///< Unique prefix for all writeable root - - EStoringMode fStoringMode = EStoringMode::kSUBDIR; ///< Objects storing mode - std::shared_ptr<ObjList_t> fpvObjList = nullptr; ///< List of registered ROOT objects - - YAML::Node fConfigNode {}; ///< Configuration node -}; - - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename T> -void CbmQaIO::CheckProperty(T&& property, const char* name) const -{ - bool bPropertyUndefined = false; - if constexpr (std::is_signed_v<T>) { bPropertyUndefined = property < 0; } - else if constexpr (std::is_floating_point_v<T>) { - bPropertyUndefined = std::isnan(property); - } - - if (bPropertyUndefined) { - std::stringstream msg; - msg << "Property " << name << " is undefined in the configuration file"; - throw std::runtime_error(msg.str()); - } -} - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename T, typename... Args> -T* CbmQaIO::MakeQaObject(TString sObjName, Args... args) -{ - // Resolve directory name and object name - auto iLastSlashPos = static_cast<int>(sObjName.Last('/')); - TString sDirName = sObjName(0, iLastSlashPos); - sObjName = sObjName(iLastSlashPos + 1, sObjName.Length() - iLastSlashPos); - - // Add unique prefix to the object name - sObjName = fsPrefix + sObjName; - - // Check, if an object with the same name already exists - // TODO: check if this makes sense and doesn't crash the memory - //if (gROOT->FindObject(sObjName)) { - // LOG(warn) << fsRootFolderName << ": A previously created object \"" << sObjName << "\" will be deleted"; - // auto* pObj = static_cast<T*>(gROOT->FindObject(sObjName)); - // delete pObj; - //} - - // Create a new object - T* pObj = new T(sObjName, args...); - - // specific stuff for different kind of objects - - TH1* pH1 = dynamic_cast<TH1*>(pObj); - - if (pH1) { // any kind of histogram - pH1->SetDirectory(0); // don't let ROOT own the histogram. The user should take care on deleting it. - SetHistoProperties(pH1); - } - - TString sPrefix = ""; - if (EStoringMode::kSUBDIR == fStoringMode) { - if (dynamic_cast<CbmQaTable*>(pObj) || dynamic_cast<CbmQaCanvas*>(pObj)) { sPrefix = "summary/"; } - } - - // Add parent directory to the folder - if (fsRootFolderName.Length() != 0) { sDirName = fsRootFolderName + "/" + sPrefix + sDirName; } - - // Register the object into an object list - fpvObjList->push_back(std::make_pair(static_cast<TObject*>(pObj), sDirName)); - return pObj; -} - - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename T, typename... Args> -T* CbmQaIO::MakeCanvas(TString nameBase, Args... args) -{ - return MakeQaObject<T>(nameBase, args...); -} - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename T, typename... Args> -T* CbmQaIO::MakeEfficiency(TString nameBase, Args... args) -{ - return MakeQaObject<T>(nameBase, args...); -} - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename T, typename... Args> -<<<<<<< HEAD -T* CbmQaIO::MakeHisto(TString nameBase, Args... args) -======= -T* CbmQaIO::MakeHistoConfig(const char* nameBase, const char* title, Args... args) -{ - TString sObjName = nameBase; - auto iLastSepPos = static_cast<int>(sObjName.Last(';')); - TString sTagName = sObjName(iLastSepPos + 1, sObjName.Length() - iLastSepPos); - sObjName = sObjName(0, iLastSepPos); - - bool bUseConfig = false; - // Check, if parameters are provided for this tag - if (fConfigNode) { - if (fConfigNode["histograms"]) { - if (fConfigNode["histograms"][sTagName.Data()]) { bUseConfig = true; } - } - } - - if (bUseConfig) { - const auto& tagNode = fConfigNode["histograms"][sTagName.Data()]; - - int nBinsX = -1; - double minX = std::numeric_limits<double>::signaling_NaN(); - double maxX = std::numeric_limits<double>::signaling_NaN(); - [[maybe_unused]] int nBinsY = -1; - [[maybe_unused]] double minY = std::numeric_limits<double>::signaling_NaN(); - [[maybe_unused]] double maxY = std::numeric_limits<double>::signaling_NaN(); - [[maybe_unused]] int nBinsZ = -1; - [[maybe_unused]] double minZ = std::numeric_limits<double>::signaling_NaN(); - [[maybe_unused]] double maxZ = std::numeric_limits<double>::signaling_NaN(); - - if (tagNode["x"]) { - nBinsX = tagNode["x"]["nbins"].as<int>(); - minX = tagNode["x"]["min"].as<double>(); - maxX = tagNode["x"]["max"].as<double>(); - } - if (tagNode["y"]) { - nBinsY = tagNode["y"]["nbins"].as<int>(); - minY = tagNode["y"]["min"].as<double>(); - maxY = tagNode["y"]["max"].as<double>(); - } - if (tagNode["z"]) { - nBinsZ = tagNode["z"]["nbins"].as<int>(); - minZ = tagNode["z"]["min"].as<double>(); - maxZ = tagNode["z"]["max"].as<double>(); - } - - if constexpr (std::is_base_of_v<TProfile2D, T>) { - CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data())); - CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data())); - CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data())); - CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data())); - CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data())); - CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data())); - CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data())); - CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data())); - return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ); - } - else if constexpr (std::is_base_of_v<TProfile, T>) { - CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data())); - CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data())); - CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data())); - CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data())); - CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data())); - return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, minY, maxY); - } - else if constexpr (std::is_base_of_v<TH3, T>) { - CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data())); - CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data())); - CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data())); - CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data())); - CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data())); - CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data())); - CheckProperty(nBinsZ, Form("qa/histograms/%s/z/nbins", sTagName.Data())); - CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data())); - CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data())); - return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY, nBinsZ, minZ, maxZ); - } - else if constexpr (std::is_base_of_v<TH2, T>) { - CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data())); - CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data())); - CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data())); - CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data())); - CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data())); - CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data())); - return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY); - } - else if constexpr (std::is_base_of_v<TH1, T>) { - CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data())); - CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data())); - CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data())); - return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX); - } - } - else { - return MakeHisto<T>(sObjName.Data(), title, args...); - } -} - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename T, typename... Args> -T* CbmQaIO::MakeObject(const char* name, Args... args) ->>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd -{ - return MakeQaObject<T>(nameBase, args...); -} - -// --------------------------------------------------------------------------------------------------------------------- -// -template<typename... Args> -CbmQaTable* CbmQaIO::MakeTable(TString nameBase, Args... args) -{ - return MakeQaObject<CbmQaTable>(nameBase, args...); -} - - -#endif // CbmQaIO_h diff --git a/macro/L1/configs/CMakeLists.txt b/macro/L1/configs/CMakeLists.txt index c7026042c3ac6929f88d581aa4fe20d26ea2396d..3d65acd46ce0382a26c25780e868b8bb6a6eb852 100644 --- a/macro/L1/configs/CMakeLists.txt +++ b/macro/L1/configs/CMakeLists.txt @@ -1,5 +1,7 @@ Install(FILES config_ideal_hits_mcbm.yaml ca_params_mcbm.yaml ca_params_sts.yaml + ca_params_global.yaml + ca_params_user_example.yaml DESTINATION share/cbmroot/macro/L1/configs ) diff --git a/macro/L1/configs/ca_params_global.yaml b/macro/L1/configs/ca_params_global.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d633f7ce83a8b3c7b490f7d325c2f2509b165a90 --- /dev/null +++ b/macro/L1/configs/ca_params_global.yaml @@ -0,0 +1,235 @@ +# Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +# SPDX-License-Identifier: GPL-3.0-only +# Authors: Sergei Zharko [committer] +# +# @file ca_params_global.yaml +# @brief Main parameter list for CA tracking +# @since 26.05.2023 +# @author S.Zharko <s.zharko@gsi.de> +# +# The parameter list contains default parameters to run tracking in a given setup +# ... +ca: + # Parameters defining the CA tracking algorithm execution logic + core: + # Common parameters for the entire core + common: + # Sequence of station names to be IGNORED by tracking + # A station name contains the official detector subsystem abbreviation (MVD, STS, MUCH, TRD, TOF), + # which is followed by the local geometry index of station (the index, which is used in the detector + # interface classes). If there is no index provided, the whole detector subsystem is skept. + # Examples: + # 1) Turn the first and the second STS in the geometry and the full TRD detector off + # inactive_stations: [STS0', 'STS1', 'TRD'] + # 2) Turn first TOF station in the geometry off + # inactive_stations: [TOF0] + # 3) Turn the full TOF off + # inactive_stations: [TOF] + inactive_stations: [] + + # Random seed + random_seed: 1 + + # Track finder parameters + track_finder: + # Iteration sequence + # The iterations themselves are defined in the ca/possible_iterations branch. + iteration_sequence: ['FastPrim', 'AllPrim', 'AllPrimJump', 'AllSec'] + + # Flag to suppress ghost tracks (true/false) + is_ghost_suppression: true + + # Max number of doublets per singlet + max_doublets_per_singlet: 150 + + # Max number of triplets per doublet + max_triplets_per_doublet: 15 + + # Developement flags + dev: + ignore_hit_search_areas: true + use_of_original_field: false + match_doublets_via_mc: false + match_triplets_via_mc: false + extend_tracks_via_mc: false + suppress_overlap_hits_via_mc: false + par_search_w_used: false + + # Full set of default iterations. Each iteration is assigned to a target track group and has recommended set of + # parameters. Later, the iterations from this list can be accessed from user configuration file + possible_iterations: + # + # A default iteration of CA tracking, is used to initialize all the parameter fields + # of other iterations, if the corresponding field is missing + # + - name: "Default" + track_chi2_cut: 10. + triplet_chi2_cut: 23.4450 + triplet_final_chi2_cut: 23.4450 + doublet_chi2_cut: 7.56327 + pick_gather: 4.0 + triplet_link_chi2: 25. + max_qp: 2. # 1 / 0.5 [GeV/c]^-1 + max_slope_pv: 1.1 + max_slope: 2.748 + max_dz: 0.1 + target_pos_sigma_x: 0. + target_pos_sigma_y: 0. + min_n_hits: 4 + min_n_hits_station_0: 4 + first_station_index: 0 + is_extend_tracks: true + is_primary: false + is_electron: false + is_jumped: false + is_track_from_triplets: false + + - name: "FastPrim" + base_iteration: "Default" + min_n_hits_station_0: 3 + pick_gather: 3.0 + max_qp: 2. # 1 / 0.5 + max_dz: 0. + target_pos_sigma_x: 1. + target_pos_sigma_y: 1. + is_primary: true + + - name: "AllPrim" + base_iteration: "Default" + min_n_hits_station_0: 3 + max_qp: 20. # 1 / 0.05 + target_pos_sigma_x: 1. + target_pos_sigma_y: 1. + is_primary: true + + - name: "FastPrim2" + base_iteration: "Default" + triplet_chi2_cut: 21.1075 + triplet_final_chi2_cut: 21.1075 + pick_gather: 3.0 + max_qp: 2. # 1 / 0.5 + max_dz: 0. + target_pos_sigma_x: 5. + target_pos_sigma_y: 5. + is_primary: true + + - name: "AllSec" + base_iteration: "Default" + triplet_chi2_cut: 18.7560 + triplet_final_chi2_cut: 18.7560 + max_qp: 10. # 1 / 0.1 + target_pos_sigma_x: 10. + target_pos_sigma_y: 10. + max_slope_pv: 9.5 + is_primary: false + + - name: "FastPrimJump" + base_iteration: "Default" + triplet_chi2_cut: 21.1075 + triplet_final_chi2_cut: 21.1075 + pick_gather: 3.0 + max_qp: 2. # 1 / 0.5 + max_dz: 0. + target_pos_sigma_x: 5. + target_pos_sigma_y: 5. + is_primary: true + is_jumped: true + + - name: "AllPrimJump" + base_iteration: "Default" + triplet_chi2_cut: 18.7560 + triplet_final_chi2_cut: 18.7560 + max_qp: 10. # 1 / 0.1 + target_pos_sigma_x: 5. + target_pos_sigma_y: 5. + is_primary: true + is_jumped: true + + - name: "AllSecJump" + base_iteration: "Default" + triplet_chi2_cut: 21.1075 + triplet_final_chi2_cut: 21.1075 + max_qp: 10. # 1 / 0.1 + max_slope_pv: 1.5 + target_pos_sigma_x: 10. + target_pos_sigma_y: 10. + is_primary: false + + - name: "AllPrimElectron" + base_iteration: "Default" + min_n_hits_station_0: 3 + max_qp: 20. # 1 / 0.05 + target_pos_sigma_x: 1. + target_pos_sigma_y: 1. + is_primary: true + is_electron: true + + - name: "AllSecElectron" + base_iteration: "Default" + triplet_chi2_cut: 18.7560 + triplet_final_chi2_cut: 18.7560 + max_qp: 20. # 1 / 0.05 + max_slope_pv: 1.5 + target_pos_sigma_x: 10. + target_pos_sigma_y: 10. + is_primary: false + is_electron: true + # + # Custom test iterations for global tracking + # + - name: "globalIterPrimFast" + min_n_hits: 3 + min_n_hits_station0: 3 + track_chi2_cut: 7.5 + triplet_chi2_cut: 23.4450 + doublet_chi2_cut: 7.56327 + pick_gather: 3.0 + triplet_link_chi2: 16.0 + max_qp: 10. # 1 / 0.1 + max_slope_pv: 9.5 + max_slope: 0.5 + max_dz: 0.05 + target_pos_sigma_x: 1. + target_pos_sigma_y: 1. + is_primary: false + is_extend_track: true + #first_station_index: 11 + + - name: "Trd2dIter2" + min_n_hits: 3 + min_n_hits_station0: 3 + track_chi2_cut: 7. + triplet_chi2_cut: 46.89 + doublet_chi2_cut: 30.25308 + pick_gather: 3.0 + triplet_link_chi2: 16.0 + max_qp: 20. # 1 / 0.05 + max_slope_pv: 9.5 + max_slope: 0.5 + max_dz: 0.05 + target_pos_sigma_x: 80. + target_pos_sigma_y: 60. + is_primary: false + is_extend_track: true + #first_station_index: 12 + + - name: "Trd2dIter3" + min_n_hits: 4 + min_n_hits_station0: 4 + track_chi2_cut: 30. + triplet_chi2_cut: 30.0 + doublet_chi2_cut: 15.0 + pick_gather: 3.0 + triplet_link_chi2: 200.0 + max_qp: 10. # 1 / 0.1 + max_slope_pv: 9.5 + max_slope: 0.4 + max_dz: 0.05 + target_pos_sigma_x: 70. + target_pos_sigma_y: 60. + is_primary: false + is_extend_track: true + + +... + diff --git a/macro/L1/configs/ca_params_mcbm.yaml b/macro/L1/configs/ca_params_mcbm.yaml index 380b1a6af114726bfacfc6a005fa820e3455df92..d1a1f9dc4f181591cb899cc990960060f464f665 100644 --- a/macro/L1/configs/ca_params_mcbm.yaml +++ b/macro/L1/configs/ca_params_mcbm.yaml @@ -1,147 +1,106 @@ -# @brief Main parameter list for CA tracking -# @since 26.05.2023 -# @author S.Zharko <s.zharko@gsi.de> +# Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +# SPDX-License-Identifier: GPL-3.0-only +# Authors: Sergei Zharko [committer] +# +# @file ca_params_mcbm.yaml +# @brief Main parameter list for CA tracking in the mCBM running mode +# @since 26.05.2023 +# @author S.Zharko <s.zharko@gsi.de> # # The parameter list contains default parameters to run tracking in a given setup # ... - -# TODO: What to do with filenames (mat budget maps etc.)? -> Probably to user interface - ca: # Parameters defining the CA tracking algorithm execution logic core: # Common parameters for the entire core common: - # Flag to suppress usage of time info from input data even if it's provided - suppress_timeinfo: true + # Sequence of station names to be IGNORED by tracking + # A station name contains the official detector subsystem abbreviation (MVD, STS, MUCH, TRD, TOF), + # which is followed by the local geometry index of station (the index, which is used in the detector + # interface classes). If there is no index provided, the whole detector subsystem is skept. + # Examples: + # 1) Turn the first and the second STS in the geometry and the full TRD detector off + # inactive_stations: [STS0', 'STS1', 'TRD'] + # 2) Turn first TOF station in the geometry off + # inactive_stations: [TOF0] + # 3) Turn the full TOF off + # inactive_stations: [TOF] + #inactive_stations: ['MUCH'] + inactive_stations: [] + + # Random seed + random_seed: 1 # Track finder parameters track_finder: - # Number of threads - n_threads: 0 # ! L1Algo::fNThreads - # Iteration sequence - iteration_sequence: ["FastPrim", "AllPrim", "AllPrimJump", "AllSec"] + # The iterations themselves are defined in the ca/possible_iterations branch. + iteration_sequence: ['FastPrim', 'AllPrim', 'AllPrimJump', 'AllSec'] - # Flag to suppress ghost tracks or not - if_suppress_ghost: true - - # Track fitter parameters - track_fitter: - # Default particle mass - # possible variants: "el", "mu", "pi", "K", "p" - default_particle_mass: "mu" # TODO: provide converter + # Flag to suppress ghost tracks or not (true/false) + is_ghost_suppression: true - # Miscillaneous parameters,of the tracking core which are to be kept in the parameter config - misc: - target_field_approx: - # Step along the beam axis between nodal points in field approximation - step_dz : 2.5 # [cm] + # Max number of doublets per singlet + max_doublets_per_singlet: 150 - # Parameters, specific for CBM (data and MC-info definition) - cbm: - # Tracking mode - # - 0: kSts - # - 1: kMcbm - # - 2: kGlobal - tracking_mode: 1 # ! CbmL1::fTrackingMode + # Max number of triplets per doublet + max_triplets_per_doublet: 15 - # Standalone running mode - # - 0: standalone mode is not used - # - 1: data for standalone mode is written to configuration file (currently does not work) - # - 2: tracking runs in standalone mode using configuration file (currently does not work) - # - 3: data is written and read (currently does not work) - # - 4: parameters file is saved, but the data does not - standalone_mode: 0 # ! CbmL1::fSTAPDataMode - - # Sequence of station names to be IGNORED by tracking - # A station name contains the official detector subsystem abbreviation (MVD, STS, MUCH, TRD, TOF), - # which is followed by the local geometry index of station (the index, which is used in the detector - # interface classes). If there is no index provided, the whole detector subsystem is skept. - # Examples: - # 1) Turn the first and the second STS in the geometry and the full TRD detector off - # skeep_stations: ['STS0', 'STS1', 'TRD'] - # 2) Turn first TOF station in the geometry off - # skeep_stations: ['TOF0'] - # 3) Turn the full TOF off - # skeep_stations: ['TOF'] - skeep_stations: [] - + # Developement flags + dev: + ignore_hit_search_areas: true + use_of_original_field: false + match_doublets_via_mc: false + match_triplets_via_mc: false + extend_tracks_via_mc: false + suppress_overlap_hits_via_mc: false + par_search_w_used: false - - # Specific parameters for CA tracking QA - qa: - # (?: Do we need it) - performance_mode: 4 - - # Track cuts - tracks: - # Minimal reconstructable momentum - min_rec_mom: 0.1 # [GeV/c] ! CbmL1Constants::MinRecoMom - # Lower momentum boundary of the fast tracks [GeV/c] - min_purity: 0.7 # Minimum purity of track (purity: 0.-1.) ! CbmL1Constants::MinPurity - # Minimal number of stations to be reconstructed - # (!: Can overlap with core iteration parameters) - min_n_stations: 4 # Minimal number of stations ! CbmL1Constants::MinNStations - # Full set of default iterations. Each iteration is assigned to a target track group and has recommended set of # parameters. Later, the iterations from this list can be accessed from user configuration file possible_iterations: # # A default iteration of CA tracking, is used to initialize all the parameter fields # of other iterations, if the corresponding field is missing - # - name Unique name of the iteration ("Default" is reserved for the default iteration) - # - track_chi2_cut Cut on track chi2 - # - triplet_chi2_cut Cut on triplet chi2 - # - triplet_final_chi2_cut - # - doublet_chi2_cut # + - name: "Default" track_chi2_cut: 10. triplet_chi2_cut: 23.4450 triplet_final_chi2_cut: 23.4450 doublet_chi2_cut: 7.56327 pick_gather: 4.0 - triplet_link_chi2_cut: 25. + triplet_link_chi2: 25. max_qp: 2. # 1 / 0.5 [GeV/c]^-1 - max_slope_pv: 1.1 + max_slope_pv: 9.5 max_slope: 2.748 + max_dz: 0.1 target_pos_sigma_x: 0. target_pos_sigma_y: 0. min_n_hits: 4 min_n_hits_station_0: 4 - max_dz: 0.1 first_station_index: 0 - if_extend_track: true - if_primary: false - if_electron: false - if_jump_one_station: false - if_track_from_triplets: false - # - # Predefined CA tracking iterations: user can modify in the user-config, or create the new iterations - # + is_extend_tracks: false + is_primary: false + is_electron: false + is_jumped: false + is_track_from_triplets: false + - name: "FastPrim" base_iteration: "Default" - min_n_hits: 4 - min_n_hits_station_0: 4 - pick_gather: 3.0 - max_qp: 3.33333 # 1 / 0.3 + max_qp: 3.3333333 # 1 / 0.3 max_dz: 0. target_pos_sigma_x: 1. target_pos_sigma_y: 1. - max_slope_pv: 9.5 - if_primary: true - if_extend_track: false + is_primary: true - name: "AllPrim" base_iteration: "Default" min_n_hits_station_0: 3 - max_qp: 10. # 1 / 0.1 + max_qp: 10. target_pos_sigma_x: 1. target_pos_sigma_y: 1. - max_slope_pv: 9.5 - if_primary: true - if_extend_track: false + is_primary: true - name: "FastPrim2" base_iteration: "Default" @@ -152,73 +111,69 @@ ca: max_dz: 0. target_pos_sigma_x: 5. target_pos_sigma_y: 5. - if_primary: true + is_primary: true - name: "AllSec" base_iteration: "Default" triplet_chi2_cut: 18.7560 triplet_final_chi2_cut: 18.7560 - max_qp: 3.33333 # 1 / 0.1 + max_qp: 3.333333 # 1 / 0.3 target_pos_sigma_x: 10. target_pos_sigma_y: 10. max_slope_pv: 9.5 - if_primary: false - if_extend_track: false + is_primary: false - name: "FastPrimJump" base_iteration: "Default" triplet_chi2_cut: 21.1075 triplet_final_chi2_cut: 21.1075 pick_gather: 3.0 - max_qp: 3.33333 # 1 / 0.3 + max_qp: 3.3333333 # 1 / 0.3 max_dz: 0. target_pos_sigma_x: 5. target_pos_sigma_y: 5. - if_primary: true - if_jump_one_station: true + is_primary: true + is_jumped: true - name: "AllPrimJump" base_iteration: "Default" triplet_chi2_cut: 18.7560 triplet_final_chi2_cut: 18.7560 - max_qp: 3.33333 # 1 / 0.3 + max_qp: 3.3333333 # 1 / 0.3 target_pos_sigma_x: 5. target_pos_sigma_y: 5. - max_slope_pv: 9.5 - if_primary: true - if_jump_one_station: true - if_extend_track: false + is_primary: true + is_jumped: true - name: "AllSecJump" base_iteration: "Default" triplet_chi2_cut: 21.1075 triplet_final_chi2_cut: 21.1075 - max_qp: 3.33333 # 1 / 0.3 + max_qp: 3.3333333 # 1 / 0.3 max_slope_pv: 1.5 target_pos_sigma_x: 10. target_pos_sigma_y: 10. - if_primary: true - if_jump_one_station: true + is_primary: false - name: "AllPrimElectron" base_iteration: "Default" min_n_hits_station_0: 3 - max_qp: 10. # 1 / 0.1 + max_qp: 10. # 1 / 0.05 target_pos_sigma_x: 1. target_pos_sigma_y: 1. - if_primary: true - if_electron: true + is_primary: true + is_electron: true - name: "AllSecElectron" base_iteration: "Default" triplet_chi2_cut: 18.7560 triplet_final_chi2_cut: 18.7560 - max_qp: 10. # 1 / 0.1 + max_qp: 10. # 1 / 0.05 max_slope_pv: 1.5 target_pos_sigma_x: 10. target_pos_sigma_y: 10. - if_primary: false - if_electron: true + is_primary: false + is_electron: true ... diff --git a/macro/L1/configs/ca_params_sts.yaml b/macro/L1/configs/ca_params_sts.yaml index c61cdd1c3e93527f2fd4da6670cdf7a4cbfc8ca6..f3d4618549b4cb50a2508053a7c0eabbf7edbb48 100644 --- a/macro/L1/configs/ca_params_sts.yaml +++ b/macro/L1/configs/ca_params_sts.yaml @@ -1,98 +1,64 @@ -# @brief Main parameter list for CA tracking -# @since 26.05.2023 -# @author S.Zharko <s.zharko@gsi.de> +# Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +# SPDX-License-Identifier: GPL-3.0-only +# Authors: Sergei Zharko [committer] +# +# @file ca_params_sts.yaml +# @brief Main parameter list for CA tracking in the STS(+MVD) running mode +# @since 26.05.2023 +# @author S.Zharko <s.zharko@gsi.de> # # The parameter list contains default parameters to run tracking in a given setup # ... - -# TODO: What to do with filenames (mat budget maps etc.)? -> Probably to user interface - ca: # Parameters defining the CA tracking algorithm execution logic core: # Common parameters for the entire core common: - # Flag to suppress usage of time info from input data even if it's provided - suppress_timeinfo: false - + # Sequence of station names to be IGNORED by tracking + # A station name contains the official detector subsystem abbreviation (MVD, STS, MUCH, TRD, TOF), + # which is followed by the local geometry index of station (the index, which is used in the detector + # interface classes). If there is no index provided, the whole detector subsystem is skept. + # Examples: + # 1) Turn the first and the second STS in the geometry and the full TRD detector off + # inactive_stations: [STS0', 'STS1', 'TRD'] + # 2) Turn first TOF station in the geometry off + # inactive_stations: [TOF0] + # 3) Turn the full TOF off + # inactive_stations: [TOF] + #inactive_stations: ['MUCH'] + inactive_stations: [] + + # Random seed + random_seed: 1 # Track finder parameters track_finder: - # Number of threads - n_threads: 0 # ! L1Algo::fNThreads - # Iteration sequence - iteration_sequence: ["FastPrim", "AllPrim", "AllPrimJump", "AllSec"] - - # Flag to suppress ghost tracks or not - if_suppress_ghost: true - - # Track fitter parameters - track_fitter: - # Default particle mass - # possible variants: "el", "mu", "pi", "K", "p" - default_particle_mass: "mu" # TODO: provide converter - - # Miscillaneous parameters,of the tracking core which are to be kept in the parameter config - misc: - target_field_approx: - # Step along the beam axis between nodal points in field approximation - step_dz : 2.5 # [cm] - - - - # Parameters, specific for CBM (data and MC-info definition) - cbm: - # Standalone running mode - # - 0: standalone mode is not used - # - 1: data for standalone mode is written to configuration file (currently does not work) - # - 2: tracking runs in standalone mode using configuration file (currently does not work) - # - 3: data is written and read (currently does not work) - # - 4: parameters file is saved, but the data does not - standalone_mode: 0 # ! CbmL1::fSTAPDataMode + # The iterations themselves are defined in the ca/possible_iterations branch. + iteration_sequence: ['FastPrim', 'AllPrim', 'AllPrimJump', 'AllSec'] + + # Flag to suppress ghost tracks (true/false) + is_ghost_suppression: true - # Store MC triplet tree .... not related to tracking execution -> only to user-interface + # Max number of doublets per singlet + max_doublets_per_singlet: 150 - # Tracking mode - # - 0: kSts - # - 1: kMcbm - # - 2: kGlobal - tracking_mode: 0 # ! CbmL1::fTrackingMode + # Max number of triplets per doublet + max_triplets_per_doublet: 15 - # Sequence of station names to be IGNORED by tracking - # A station name contains the official detector subsystem abbreviation (MVD, STS, MUCH, TRD, TOF), - # which is followed by the local geometry index of station (the index, which is used in the detector - # interface classes). If there is no index provided, the whole detector subsystem is skept. - # Examples: - # 1) Turn the first and the second STS in the geometry and the full TRD detector off - # skeep_stations: ['STS0', 'STS1', 'TRD'] - # 2) Turn first TOF station in the geometry off - # skeep_stations: ['TOF0'] - # 3) Turn the full TOF off - # skeep_stations: ['TOF'] - skeep_stations: [] - + # Developement flags + dev: + ignore_hit_search_areas: true + use_of_original_field: false + match_doublets_via_mc: false + match_triplets_via_mc: false + extend_tracks_via_mc: false + suppress_overlap_hits_via_mc: false + par_search_w_used: false - # Specific parameters for CA tracking QA - qa: - # (?: Do we need it) - performance_mode: - - # Track cuts - tracks: - # Minimal reconstructable momentum - min_rec_mom: 0.1 # [GeV/c] ! CbmL1Constants::MinRecoMom - - # Lower momentum boundary of the fast tracks [GeV/c] - min_purity: 0.7 # Minimum purity of track (purity: 0.-1.) ! CbmL1Constants::MinPurity - - # Minimal number of stations to be reconstructed - # (!: Can overlap with core iteration parameters) - min_n_stations: 4 # Minimal number of stations ! CbmL1Constants::MinNStations - # Full set of default iterations. Each iteration is assigned to a target track group and has recommended set of # parameters. Later, the iterations from this list can be accessed from user configuration file - default_iterations: + possible_iterations: # A default iteration of CA tracking, is used to initialized all the parameter fields # of other iterations, if the corresponding field is missing # TODO: provide with documentation @@ -102,21 +68,21 @@ ca: triplet_final_chi2_cut: 23.4450 doublet_chi2_cut: 7.56327 pick_gather: 4.0 - triplet_link_chi2_cut: 25. + triplet_link_chi2: 25. max_qp: 2. # 1 / 0.5 [GeV/c]^-1 max_slope_pv: 1.1 max_slope: 2.748 + max_dz: 0.1 target_pos_sigma_x: 0. target_pos_sigma_y: 0. min_n_hits: 4 min_n_hits_station_0: 4 - max_dz: 0.1 first_station_index: 0 - if_extend_track: true - if_primary: false - if_electron: false - if_jump_one_station: false - if_track_from_triplets: false + is_extend_tracks: true + is_primary: false + is_electron: false + is_jumped: false + is_track_from_triplets: false - name: "FastPrim" base_iteration: "Default" @@ -126,7 +92,7 @@ ca: max_dz: 0. target_pos_sigma_x: 1. target_pos_sigma_y: 1. - if_primary: true + is_primary: true - name: "AllPrim" base_iteration: "Default" @@ -134,7 +100,7 @@ ca: max_qp: 20. # 1 / 0.05 target_pos_sigma_x: 1. target_pos_sigma_y: 1. - if_primary: true + is_primary: true - name: "FastPrim2" base_iteration: "Default" @@ -145,7 +111,7 @@ ca: max_dz: 0. target_pos_sigma_x: 5. target_pos_sigma_y: 5. - if_primary: true + is_primary: true - name: "AllSec" base_iteration: "Default" @@ -155,7 +121,7 @@ ca: target_pos_sigma_x: 10. target_pos_sigma_y: 10. max_slope_pv: 1.5 - if_primary: false + is_primary: false - name: "FastPrimJump" base_iteration: "Default" @@ -166,8 +132,8 @@ ca: max_dz: 0. target_pos_sigma_x: 5. target_pos_sigma_y: 5. - if_primary: true - if_jump_one_station: true + is_primary: true + is_jumped: true - name: "AllPrimJump" base_iteration: "Default" @@ -176,8 +142,8 @@ ca: max_qp: 10. # 1 / 0.1 target_pos_sigma_x: 5. target_pos_sigma_y: 5. - if_primary: true - if_jump_one_station: true + is_primary: true + is_jumped: true - name: "AllSecJump" base_iteration: "Default" @@ -187,8 +153,7 @@ ca: max_slope_pv: 1.5 target_pos_sigma_x: 10. target_pos_sigma_y: 10. - if_primary: true - if_jump_one_station: true + is_primary: false - name: "AllPrimElectron" base_iteration: "Default" @@ -196,8 +161,8 @@ ca: max_qp: 20. # 1 / 0.05 target_pos_sigma_x: 1. target_pos_sigma_y: 1. - if_primary: true - if_electron: true + is_primary: true + is_electron: true - name: "AllSecElectron" base_iteration: "Default" @@ -207,8 +172,8 @@ ca: max_slope_pv: 1.5 target_pos_sigma_x: 10. target_pos_sigma_y: 10. - if_primary: false - if_electron: true + is_primary: false + is_electron: true ... diff --git a/macro/L1/configs/ca_params_user_example.yaml b/macro/L1/configs/ca_params_user_example.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5c424d2b64eb5180e42969eae2761c3cb08804fa --- /dev/null +++ b/macro/L1/configs/ca_params_user_example.yaml @@ -0,0 +1,27 @@ +# Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +# SPDX-License-Identifier: GPL-3.0-only +# Authors: Sergei Zharko [committer] +# +# Example of user-configuration file for CA tracking in CBM +# +# +ca: + core: + common: + random_seed: 1000 + track_finder: + # + # TODO: .... + iterations: + - name: "FastPrim" + max_qp: 2 + - name: "AllPrim" + - name: "AllPrimJump" + track_chi2_cut: 40 + - name: "User-1" + base_iteration: "AllSec" + track_chi2_cut: 30 + - name: "AllPrimaryElectron" + track_chi2_cut: 30 + +... diff --git a/macro/mcbm/mcbm_reco_event.C b/macro/mcbm/mcbm_reco_event.C index 0a44b3c264b718e1431bbd86e974d6cef90285b2..a7e041b2fbfa9aa0c18e709255ff845049cb8924 100644 --- a/macro/mcbm/mcbm_reco_event.C +++ b/macro/mcbm/mcbm_reco_event.C @@ -383,6 +383,8 @@ void mcbm_reco_event(Int_t nEvents = 10, TString dataset = "data/test", // L1 tracking auto l1 = (debugWithMC) ? new CbmL1("CA", 5, 3) : new CbmL1("CA"); l1->SetMcbmMode(); + // User configuration example for CA: + //l1->SetConfigUser(srcDir + "/macro/L1/configs/ca_params_user_example.yaml"); if (strcmp(setupName, "mcbm_beam_2021_07_surveyed") == 0) l1->SetMissingHits(1); run->AddTask(l1); diff --git a/macro/qa/qa_compare_ca.C b/macro/qa/qa_compare_ca.C index 3bc59effd5b419a213df06a3f32c8ef16d909923..4204ae75ff35d9ca3bf897884f478b1af75b674b 100644 --- a/macro/qa/qa_compare_ca.C +++ b/macro/qa/qa_compare_ca.C @@ -36,7 +36,7 @@ int qa_compare_ca( pQaChecker->SetFromYAML(configName); // Read file-object map //// ----- Run comparision routine - pQaChecker->Process("P"); + pQaChecker->Process("PB"); //// ----- Scan results bool res = pQaChecker->Scan(); // true - objects are the same, false - objects differ diff --git a/macro/run/run_reco.C b/macro/run/run_reco.C index 6806562132a51a9dc6b7947cefd549c7f4204dd7..fb82b0bcc3ce05b167e53cc4c87ee722a1b97d79 100644 --- a/macro/run/run_reco.C +++ b/macro/run/run_reco.C @@ -377,20 +377,24 @@ void run_reco(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice = if (debugWithMC) { CbmMatchRecoToMC* match1 = new CbmMatchRecoToMC(); run->AddTask(match1); + std::cout << "-I- " << myName << ": Added task " << match1->GetName() << std::endl; } // ----- Track finding in STS (+ MVD) -------------------------------- if (useMvd || useSts) { - run->AddTask(new CbmTrackingDetectorInterfaceInit()); // Geometry interface initializer for tracker + auto pDetIF = new CbmTrackingDetectorInterfaceInit(); + run->AddTask(pDetIF); // Geometry interface initializer for tracker + std::cout << "-I- " << myName << ": Added task " << pDetIF->GetName() << std::endl; // Kalman filter auto kalman = new CbmKF(); run->AddTask(kalman); + std::cout << "-I- " << myName << ": Added task " << kalman->GetName() << std::endl; if (debugWithMC) { auto* pIdealHitProducer = new cbm::ca::IdealHitProducer("IdealHitProducer", 3); pIdealHitProducer->SetConfigName(srcDir + "/macro/L1/configs/config_ideal_hits.yaml"); - //run->AddTask(pIdealHitProducer); + //run->AddTask(pIdealHitProducer); std::cout << "-I- " << myName << ": Added task " << pIdealHitProducer->GetName() << std::endl; } // L1 tracking diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt index 4c00911f6af0443342487045a1f5db63869db966..a43c86b0780e166e6301688e1e5d06e63e666aa8 100644 --- a/reco/L1/CMakeLists.txt +++ b/reco/L1/CMakeLists.txt @@ -217,7 +217,7 @@ install(FILES CbmL1Counters.h L1Algo/L1Track.h utils/CbmCaIdealHitProducer.h utils/CbmCaIdealHitProducerDet.h - L1Algo/utils/CaUvConverter.cxx + L1Algo/utils/CaUvConverter.h qa/CbmCaInputQaBase.h DESTINATION include ) diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index 07ad18c96fb40b3af0c7b203e44a1e02f2a6cae7..3facfc53eadcd29499ffe5f2464c3af53d51e245 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -53,6 +53,7 @@ #include "TProfile2D.h" #include "TROOT.h" #include "TRandom3.h" +#include "TSystem.h" #include "TVector3.h" #include "TVectorD.h" #include <TFile.h> @@ -232,6 +233,7 @@ InitStatus CbmL1::Init() fInitManager.SetMaxTripletPerDoublets(1000); } + //fInitManager.DevSetIsMatchDoubletsViaMc(true); //fInitManager.DevSetIsMatchTripletsViaMc(true); //fInitManager.DevSetIsExtendTracksViaMc(true); @@ -375,6 +377,29 @@ InitStatus CbmL1::Init() } // Parameters initialization, based on the FairRunAna chain else { + // ******************************************** + // ** Base configuration file initialization ** + // ******************************************** + { + // The parameters module of CA algorithm (L1Parameters) contains two sets of data fields: the geometry configura- + // tion and the parameter configuration. The configuration both for geometry and parameters can be set using + // either the accessor functions of the L1InitManager class, or reading the beforehand prepared L1Parameters + // object. On top of that, the parameters configuration (including cuts, algorithm execution scenario etc.) can + // be initialized from the YAML configuration files in two levels (base and user). The base level of the initia- + // lization is required for CbmL1 mode, the user level of the initialization is optional. + + std::string mainConfig = std::string(gSystem->Getenv("VMCWORKDIR")) + "/macro/L1/configs/"; + switch (fTrackingMode) { + case L1Algo::TrackingMode::kSts: mainConfig += "ca_params_sts.yaml"; break; + case L1Algo::TrackingMode::kMcbm: mainConfig += "ca_params_mcbm.yaml"; break; + case L1Algo::TrackingMode::kGlobal: mainConfig += "ca_params_global.yaml"; break; + } + fInitManager.SetConfigMain(mainConfig); + } + + fInitManager.SetDetectorNames(cbm::ca::kDetName); + L1_SHOW(fInitManager.GetDetectorName(L1DetectorID::kSts)); + auto mvdInterface = CbmMvdTrackingInterface::Instance(); auto stsInterface = CbmStsTrackingInterface::Instance(); auto muchInterface = CbmMuchTrackingInterface::Instance(); @@ -421,6 +446,8 @@ InitStatus CbmL1::Init() // ** Target field initialization ** // ********************************* + // FIXME: SZh 22.08.2023: + // Is there anyway to calculate a step between field slices? fInitManager.InitTargetField(/*zStep = */ 2.5 /*cm*/); // Replace zStep -> sizeZfieldRegion = 2 * zStep (TODO) // ************************************** @@ -584,231 +611,6 @@ InitStatus CbmL1::Init() // **************************************** this->GenerateMaterialMaps(); - - // **************************************** - // ** ** - // ** 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 trIterDefault = L1CAIteration("default"); - trIterDefault.SetMinNhits(4); - trIterDefault.SetMinNhitsStation0(4); - trIterDefault.SetDoubletChi2Cut(7.56327f); // = 1.3449 * 2.f / 3.f; // prob = 0.1 - trIterDefault.SetTripletChi2Cut(23.4450f); // = 7.815 * 3; // prob = 0.05 - trIterDefault.SetTripletFinalChi2Cut(23.4450f); //new 7.5); - trIterDefault.SetTripletLinkChi2(25.); // new:10 - trIterDefault.SetTrackChi2Cut(10.); - trIterDefault.SetMaxSlope(2.748f); - trIterDefault.SetMaxSlopePV(1.1f); - trIterDefault.SetMaxDZ(0.1); - trIterDefault.SetPickGather(4.0f); - trIterDefault.SetExtendTracksFlag(true); - - auto trackingIterFastPrim = L1CAIteration(trIterDefault, "FastPrimIter"); - trackingIterFastPrim.SetMinNhitsStation0(3); - trackingIterFastPrim.SetPickGather(3.0f); - trackingIterFastPrim.SetMaxQp(1.0 / 0.5); - trackingIterFastPrim.SetMaxDZ(0); - trackingIterFastPrim.SetTargetPosSigmaXY(1, 1); - trackingIterFastPrim.SetPrimaryFlag(true); - - auto trackingIterAllPrim = L1CAIteration(trIterDefault, "AllPrimIter"); - trackingIterAllPrim.SetMinNhitsStation0(3); - trackingIterAllPrim.SetMaxQp(1.0 / 0.05); - trackingIterAllPrim.SetTargetPosSigmaXY(1, 1); - trackingIterAllPrim.SetPrimaryFlag(true); - - auto trackingIterFastPrim2 = L1CAIteration(trIterDefault, "FastPrim2Iter"); - trackingIterFastPrim2.SetTripletChi2Cut(21.1075f); - trackingIterFastPrim2.SetTripletFinalChi2Cut(21.1075f); - trackingIterFastPrim2.SetPickGather(3.0f); - trackingIterFastPrim2.SetMaxQp(1.0 / 0.5); - trackingIterFastPrim2.SetMaxDZ(0); - trackingIterFastPrim2.SetTargetPosSigmaXY(5, 5); - trackingIterFastPrim2.SetPrimaryFlag(true); - - auto trackingIterAllSec = L1CAIteration(trIterDefault, "AllSecIter"); - trackingIterAllSec.SetTripletChi2Cut(18.7560f); // = 6.252 * 3; // prob = 0.1 - trackingIterAllSec.SetTripletFinalChi2Cut(18.7560f); - trackingIterAllSec.SetMaxQp(1.0 / 0.1); - trackingIterAllSec.SetTargetPosSigmaXY(10, 10); - trackingIterAllSec.SetMaxSlopePV(1.5); - trackingIterAllSec.SetPrimaryFlag(false); - - auto trackingIterFastPrimJump = L1CAIteration(trIterDefault, "FastPrimJumpIter"); - trackingIterFastPrimJump.SetTripletChi2Cut(21.1075f); // prob = 0.01 - trackingIterFastPrimJump.SetTripletFinalChi2Cut(21.1075f); - trackingIterFastPrimJump.SetPickGather(3.0f); - trackingIterFastPrimJump.SetMaxQp(1.0 / 0.5); - trackingIterFastPrimJump.SetMaxDZ(0); - trackingIterFastPrimJump.SetTargetPosSigmaXY(5, 5); - trackingIterFastPrimJump.SetPrimaryFlag(true); - trackingIterFastPrimJump.SetJumpedFlag(true); - - auto trackingIterAllPrimJump = L1CAIteration(trIterDefault, "AllPrimJumpIter"); - trackingIterAllPrimJump.SetTripletChi2Cut(18.7560f); - trackingIterAllPrimJump.SetTripletFinalChi2Cut(18.7560f); - trackingIterAllPrimJump.SetMaxQp(1.0 / 0.1); - trackingIterAllPrimJump.SetTargetPosSigmaXY(5, 5); - trackingIterAllPrimJump.SetPrimaryFlag(true); - trackingIterAllPrimJump.SetJumpedFlag(true); - - auto trackingIterAllSecJump = L1CAIteration(trIterDefault, "AllSecJumpIter"); - trackingIterAllSecJump.SetTripletChi2Cut(21.1075f); - trackingIterAllSecJump.SetTripletFinalChi2Cut(21.1075f); - trackingIterAllSecJump.SetMaxQp(1.0 / 0.1); - trackingIterAllSecJump.SetMaxSlopePV(1.5f); - trackingIterAllSecJump.SetTargetPosSigmaXY(10, 10); - trackingIterAllSecJump.SetPrimaryFlag(false); - trackingIterAllSecJump.SetJumpedFlag(true); - - auto trackingIterAllPrimE = L1CAIteration(trIterDefault, "AllPrimEIter"); - trackingIterAllPrimE.SetMinNhitsStation0(3); - trackingIterAllPrimE.SetMaxQp(1.0 / 0.05); - trackingIterAllPrimE.SetTargetPosSigmaXY(1, 1); - trackingIterAllPrimE.SetPrimaryFlag(true); - trackingIterAllPrimE.SetElectronFlag(true); - - auto trackingIterAllSecE = L1CAIteration(trIterDefault, "AllSecEIter"); - trackingIterAllSecE.SetTripletChi2Cut(18.7560f); - trackingIterAllSecE.SetTripletFinalChi2Cut(18.7560f); - trackingIterAllSecE.SetMaxQp(1.0 / 0.05); - trackingIterAllSecE.SetMaxSlopePV(1.5f); - trackingIterAllSecE.SetTargetPosSigmaXY(10, 10); - trackingIterAllSecE.SetPrimaryFlag(false); - trackingIterAllSecE.SetElectronFlag(true); - - // Select default track finder - if (L1Algo::TrackingMode::kMcbm == fTrackingMode) { - - trackingIterFastPrim.SetMinNhits(4); - trackingIterFastPrim.SetMinNhitsStation0(4); - - trackingIterAllSecE.SetMinNhits(4); - trackingIterAllSecE.SetMinNhitsStation0(4); - trackingIterAllPrim.SetMaxQp(1. / 0.1); - trackingIterAllPrimE.SetMaxQp(1. / 0.1); - trackingIterAllSecE.SetMaxQp(1. / 0.1); - - trackingIterAllSecJump.SetMinNhits(4); - trackingIterAllSecJump.SetMinNhitsStation0(4); - trackingIterFastPrim.SetMaxQp(1.0 / 0.3); - trackingIterAllSec.SetMaxQp(1.0 / 0.3); - trackingIterFastPrimJump.SetMaxQp(1.0 / 0.3); - trackingIterAllPrimJump.SetMaxQp(1.0 / 0.3); - trackingIterAllSecJump.SetMaxQp(1.0 / 0.3); - - trackingIterAllSec.SetMinNhits(4); - trackingIterAllSec.SetMinNhitsStation0(4); - trackingIterFastPrim.SetExtendTracksFlag(false); - trackingIterAllPrim.SetExtendTracksFlag(false); - trackingIterAllPrimJump.SetExtendTracksFlag(false); - trackingIterAllSec.SetExtendTracksFlag(false); - - trackingIterFastPrim.SetMaxSlopePV(9.5); - trackingIterAllPrim.SetMaxSlopePV(9.5); - trackingIterAllPrimJump.SetMaxSlopePV(9.5); - trackingIterAllSec.SetMaxSlopePV(9.5); - - 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) { - - // Initialize CA track finder iterations sequence - - auto globalIterPrimFast = L1CAIteration("globalIterPrimFast"); - { - auto& it = globalIterPrimFast; - it.SetMinNhits(3); - it.SetMinNhitsStation0(3); - it.SetTrackChi2Cut(7.f); //10.f - it.SetTripletChi2Cut(23.4450f); // = 7.815 * 3; // prob = 0.05 - it.SetDoubletChi2Cut(7.56327f); // = 1.3449 * 2.f / 3.f; // prob = 0.1 - it.SetPickGather(3.0f); - it.SetTripletLinkChi2(16.0); - it.SetMaxQp(1.0 / 0.1); //(1.0 / 0.5); - it.SetMaxSlopePV(9.5); - it.SetMaxSlope(.5f); - it.SetMaxDZ(0.05); - it.SetTargetPosSigmaXY(1., 1.); //(1, 1); - //it.SetPrimaryFlag(true); - it.SetExtendTracksFlag(true); - it.SetPrimaryFlag(false); - //it.SetExtendTracksFlag(false); - //it.SetFirstStationIndex(11); - } - - auto trd2dIter2 = L1CAIteration("Trd2dIter2"); - trd2dIter2.SetMinNhits(3); - trd2dIter2.SetMinNhitsStation0(3); - 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.SetTripletLinkChi2(16.); - trd2dIter2.SetMaxQp(1.0 / 0.05); //(1.0 / 0.5); - trd2dIter2.SetMaxSlopePV(9.5f); - trd2dIter2.SetMaxSlope(.5f); - trd2dIter2.SetMaxDZ(0.05); - trd2dIter2.SetTargetPosSigmaXY(8 * 10, 6 * 10); //(1, 1); - trd2dIter2.SetPrimaryFlag(false); - trd2dIter2.SetExtendTracksFlag(true); - //trd2dIter2.SetFirstStationIndex(12); - - auto trd2dIter3 = L1CAIteration("trd2dIter3"); - trd2dIter3.SetMinNhits(4); - trd2dIter3.SetMinNhitsStation0(4); - trd2dIter3.SetTrackChi2Cut(30); //10.f - trd2dIter3.SetTripletChi2Cut(15. * 2.); // = 7.815 * 3; // prob = 0.05 - trd2dIter3.SetDoubletChi2Cut(15.); // = 1.3449 * 2.f / 3.f; // prob = 0.1 - trd2dIter3.SetPickGather(3.0f); - trd2dIter3.SetTripletLinkChi2(200.); - trd2dIter3.SetMaxQp(1.0 / 0.1); //(1.0 / 0.5); - trd2dIter3.SetMaxSlopePV(9.5); - trd2dIter3.SetMaxSlope(.4); //.5f); - trd2dIter3.SetMaxDZ(0.05); - trd2dIter3.SetTargetPosSigmaXY(7 * 10, 6 * 10); //(1, 1); - trd2dIter3.SetPrimaryFlag(false); - trd2dIter3.SetExtendTracksFlag(true); - - // Initialize CA track finder iterations sequence - - fInitManager.SetCAIterationsNumberCrosscheck(1); - //fInitManager.PushBackCAIteration(trackingIterFastPrim); - //fInitManager.PushBackCAIteration(globalIterPrimFast); - fInitManager.PushBackCAIteration(trd2dIter3); - /* - fInitManager.SetCAIterationsNumberCrosscheck(5); - fInitManager.PushBackCAIteration(trackingIterFastPrim); - fInitManager.PushBackCAIteration(trackingIterAllPrim); - fInitManager.PushBackCAIteration(trackingIterAllPrimJump); - fInitManager.PushBackCAIteration(trackingIterAllSec); - */ - } - 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); - } - // ******************************* // ** Initialize search windows ** // ******************************* @@ -821,26 +623,24 @@ InitStatus CbmL1::Init() fInitManager.DevSetIsParSearchWUsed(false); } - - // ********************** - // ** Set special cuts ** - // ********************** - - fInitManager.SetGhostSuppression(fGhostSuppression); - fInitManager.SetTrackingLevel(fTrackingLevel); - fInitManager.SetMomentumCutOff(fMomentumCutOff); - // Form parameters container if (!fInitManager.FormParametersContainer()) { return kFATAL; } - // Write to file if needed + // Write parameters object to file if needed if (1 == fSTAPDataMode || 4 == fSTAPDataMode) { this->WriteSTAPParamObject(); } } // Init L1 algo core + // FIXME: SZh 22.08.2023: + // Re-organize the the relation between CbmL1 and L1Algo. I belive, we don't need a global pointer to the L1Algo + // instance. fpAlgo = &gAlgo; + + // FIXME: SZh 22.08.2023: + // We need to remove the fMissingHits flag. It corresponds to a particular setup in mCBM, which we probably + // should not support anymore. fpAlgo->Init(fTrackingMode, fMissingHits); // @@ -857,7 +657,7 @@ InitStatus CbmL1::Init() fNTofStations = fpAlgo->GetParameters()->GetNstationsActive(L1DetectorID::kTof); fNStations = fpAlgo->GetParameters()->GetNstationsActive(); - LOG(info) << fpAlgo->GetParameters()->ToString(0); + LOG(info) << fpAlgo->GetParameters()->ToString(1); fpIODataManager->SetNofActiveStations(fNStations); LOG(info) << "----- Numbers of stations active in tracking -----"; diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 1db41198f6b9f6059f4547048068ed67d5d4ec07..9b05cd88f7f87e6d03b12214929518d6b73203d4 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -212,13 +212,9 @@ public: /// Only needed in debug mode to produce detailed picture of the material void SetMaterialBudgetParallelProjection() { fMatBudgetParallelProjection = true; } - /// @brief Sets mandatory configuration filename - /// @param path Name of the input tracking configuration file - void SetConfig(const char* path) { fInitManager.GetConfigRW().SetBaseConfigPath(path); } - /// @brief Sets user configuration filename /// @param path Path to the config - void SetConfigUser(const char* path) { fInitManager.GetConfigRW().SetUserConfigPath(path); } + void SetConfigUser(const char* path) { fInitManager.SetConfigUser(path); } /// \brief Sets a name for the input search window file /// If the filename is not defined, a default track finder with Kalman filter is used. Otherwise, an experimental diff --git a/reco/L1/CbmL1DetectorID.h b/reco/L1/CbmL1DetectorID.h index 2ae838bd02d925627b591b8dcd75682635a39bd1..73788924186bc32fa2e2bbe6265d395c64062592 100644 --- a/reco/L1/CbmL1DetectorID.h +++ b/reco/L1/CbmL1DetectorID.h @@ -72,7 +72,6 @@ namespace cbm::ca /// read-out corruption. constexpr CbmCaDetIdArr_t<const char*> kDetName = {{"MVD", "STS", "MUCH", "TRD", "TOF"}}; - /// @brief Types of MC point objects for each detector using PointTypes_t = CbmCaDetIdTypeArr_t<CbmMvdPoint, CbmStsPoint, CbmMuchPoint, CbmTrdPoint, CbmTofPoint>; diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx index 3a7bb63f035ac9a8d3e4c55e5b196744f85da42b..771967bccf471cb774b25e65db90610d639de609 100644 --- a/reco/L1/L1Algo/L1Algo.cxx +++ b/reco/L1/L1Algo/L1Algo.cxx @@ -168,9 +168,7 @@ void L1Algo::ReceiveParameters(L1Parameters&& parameters) [](const L1Station& s, int edge) { return bool(s.fieldStatus) > edge; }) - fParameters.GetStations().cbegin(); - fTrackingLevel = fParameters.GetTrackingLevel(); fGhostSuppression = fParameters.GetGhostSuppression(); - fMomentumCutOff = fParameters.GetMomentumCutOff(); L1FieldRegion::ForceUseOfOriginalField(fParameters.DevIsUseOfOriginalField()); } diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h index 88ac58a8724a4f34969c0bb1cd5a9950ddef1be5..e6aaaeb63bed12f4b0836a1d8d95049f6491adbf 100644 --- a/reco/L1/L1Algo/L1Algo.h +++ b/reco/L1/L1Algo/L1Algo.h @@ -554,9 +554,7 @@ private: // int TripNumThread; - int fTrackingLevel {2}; // currently not used int fGhostSuppression {1}; // NOTE: Should be equal to 0 in TRACKS_FROM_TRIPLETS mode! - float fMomentumCutOff {0.2}; // currently not used /// ----- Debug features ----- #ifdef PULLS diff --git a/reco/L1/L1Algo/L1BaseStationInfo.cxx b/reco/L1/L1Algo/L1BaseStationInfo.cxx index ee99e8f4e493adab40211bd32f5e5050f3cfb929..044ea49e2c8941ba7f98ec8d11123fa89013432c 100644 --- a/reco/L1/L1Algo/L1BaseStationInfo.cxx +++ b/reco/L1/L1Algo/L1BaseStationInfo.cxx @@ -60,7 +60,7 @@ void L1BaseStationInfo::Print(int verbosity) const LOG(info) << "\tDetector ID: " << static_cast<int>(fDetectorID); LOG(info) << "\tStation z position: " << fZref; LOG(info) << "\tTracking status: " << fTrackingStatus; - fL1Station.Print(verbosity - 1); + LOG(info) << "\tL1Staiton: " << fL1Station.ToString(1); LOG(info) << "\tAdditional fields:"; LOG(info) << "\t\tXmax: " << fXmax; LOG(info) << "\t\tYmax: " << fYmax; diff --git a/reco/L1/L1Algo/L1CAIteration.cxx b/reco/L1/L1Algo/L1CAIteration.cxx index e70460b1206ee14106f70a978584dababe7716a8..060fec635671fa8f4c68593f275c87ff29f62728 100644 --- a/reco/L1/L1Algo/L1CAIteration.cxx +++ b/reco/L1/L1Algo/L1CAIteration.cxx @@ -1,4 +1,4 @@ -/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt +/* Copyright (C) 2022-2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only Authors: Sergey Gorbunov, Sergei Zharko [committer] */ @@ -66,32 +66,8 @@ void L1CAIteration::SetTargetPosSigmaXY(float sigmaX, float sigmaY) // --------------------------------------------------------------------------------------------------------------------- // -std::string L1CAIteration::ToString(int indentLevel) const +std::string L1CAIteration::ToString(int) const { - std::stringstream aStream {}; - constexpr char indCh = '\t'; - std::string indent(indentLevel, indCh); - aStream << indent << "\033[1;30m" << fName << "\033[0m\n"; - aStream << indent << indCh << "Is primary: " << fIsPrimary << '\n'; - 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 << "Min n hits : " << fMinNhits << '\n'; - aStream << indent << indCh << "Min n hits for trscs at station 0: " << fMinNhitsStation0 << '\n'; - aStream << indent << indCh << "Track chi2 cut: " << fTrackChi2Cut << '\n'; - aStream << indent << indCh << "Triplet chi2 cut: " << fTripletChi2Cut << '\n'; - aStream << indent << indCh << "Triplet final chi2 cut: " << fTripletFinalChi2Cut << '\n'; - aStream << indent << indCh << "Doublet chi2 cut: " << fDoubletChi2Cut << '\n'; - aStream << indent << indCh << "Pick gather: " << fPickGather << '\n'; - aStream << indent << indCh << "Triplet link chi2: " << fTripletLinkChi2 << '\n'; - aStream << indent << indCh << "Max q / p: " << fMaxQp << '\n'; - aStream << indent << indCh << "Max slope at primary vertex: " << fMaxSlopePV << '\n'; - aStream << indent << indCh << "Max slope: " << fMaxSlope << '\n'; - aStream << indent << indCh << "Max DZ: " << fMaxDZ << '\n'; - aStream << indent << indCh << "Target position sigma X [cm]: " << fTargetPosSigmaX << '\n'; - aStream << indent << indCh << "Target position sigma Y [cm]: " << fTargetPosSigmaY << '\n'; - aStream << indent << indCh << "First tracking station index: " << fFirstStationIndex; - - return aStream.str(); + std::vector<L1CAIteration> vIter {*this}; + return L1CAIteration::ToTableFromVector(vIter); } diff --git a/reco/L1/L1Algo/L1CAIteration.h b/reco/L1/L1Algo/L1CAIteration.h index 1d61d40a388d168ca6a3bf25874c3d4027926a91..6dd2ba872d071ef1396d50e6b68646cd079f2f0f 100644 --- a/reco/L1/L1Algo/L1CAIteration.h +++ b/reco/L1/L1Algo/L1CAIteration.h @@ -18,6 +18,7 @@ #include <boost/serialization/string.hpp> #include <bitset> +#include <iomanip> #include <string> // TODO: discuss the border conditions for the parameters. Implement them (S.Zharko) @@ -56,66 +57,57 @@ public: /// Checks parameters consistency bool Check() const; - /// Gets doublet chi2 upper cut + /// @brief Gets doublet chi2 upper cut float GetDoubletChi2Cut() const { return fDoubletChi2Cut; } - /// flag check: electrons/positrons - true, heavy charged - false + /// @brief flag check: electrons/positrons - true, heavy charged - false bool GetElectronFlag() const { return fIsElectron; } - /// Sets flag: true - extends track candidates with unused hits - bool GetExtendTracksFlag() const { return fIfExtendTracks; } + /// @brief Sets flag: true - extends track candidates with unused hits + bool GetExtendTracksFlag() const { return fIsExtendTracks; } - /// Gets station index of the first station used in tracking + /// @brief Gets station index of the first station used in tracking int GetFirstStationIndex() const { return fFirstStationIndex; } - /// Gets ... TODO - bool GetJumpedFlag() const { return fIfJumped; } + /// @brief Gets flag: true - triplets are built skipping one station + bool GetJumpedFlag() const { return fIsJumped; } - /// Gets correction for accounting overlaping and iff z + /// @brief Gets correction for accounting overlaping and iff z float GetMaxDZ() const { return fMaxDZ; } - /// Gets max considered q/p for tracks + /// @brief Gets max considered q/p for tracks float GetMaxQp() const { return fMaxQp; } - /// Gets max slope (tx\ty) in 3D hit position of a triplet + /// @brief Gets max slope (tx\ty) in 3D hit position of a triplet float GetMaxSlope() const { return fMaxSlope; } - /// Gets max slope (tx\ty) in primary vertex + /// @brief Gets max slope (tx\ty) in primary vertex float GetMaxSlopePV() const { return fMaxSlopePV; } - /// Gets the name of the iteration + /// @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; } - /// Gets size of region [TODO: units??] to attach new hits to the created track + /// @brief Gets size of region [TODO: units??] to attach new hits to the created track float GetPickGather() const { return fPickGather; } - /// Gets min value of dp/dp_error, for which two tiplets are neighbours - float GetTripletLinkChi2() const { return fTripletLinkChi2; } - - /// Checks flag: true - only primary tracks are searched, false - [all or only secondary?] + /// @brief Checks flag: true - only primary tracks are searched, false - [all or only secondary?] bool GetPrimaryFlag() const { return fIsPrimary; } - /// Gets min n hits - int GetMinNhits() const { return fMinNhits; } - - /// Gets min n hits for tracks that start on station 0 - int GetMinNhitsStation0() const { return fMinNhitsStation0; } - - /// Gets sigma target position in X direction [cm] + /// @brief Gets sigma target position in X direction [cm] float GetTargetPosSigmaX() const { return fTargetPosSigmaX; } - /// Gets sigma target position in Y direction [cm] + /// @brief Gets sigma target position in Y direction [cm] float GetTargetPosSigmaY() const { return fTargetPosSigmaY; } - /// Gets track chi2 upper cut + /// @brief Gets track chi2 upper cut float GetTrackChi2Cut() const { return fTrackChi2Cut; } - /// Gets triplet chi2 upper cut - float GetTripletChi2Cut() const { return fTripletChi2Cut; } - - /// Gets triplet chi2 upper cut - float GetTripletFinalChi2Cut() const { return fTripletFinalChi2Cut; } - /// (DEBUG!) Sets flag: /// true: /// all the triplets found on this iteration will be converted to tracks, @@ -128,59 +120,63 @@ public: /// 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; } - /// Prints iteration options + /// @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; - /// Sets doublet chi2 upper cut + /// @brief Sets doublet chi2 upper cut void SetDoubletChi2Cut(float input) { fDoubletChi2Cut = input; } - /// Sets flag: electron tracks - true, heavy ion tracks - false + /// @brief Sets flag: electron tracks - true, heavy ion tracks - false void SetElectronFlag(bool flag) { fIsElectron = flag; } - /// Sets flag: true - extends track candidates with unused hits - void SetExtendTracksFlag(bool flag) { fIfExtendTracks = flag; } + /// @brief Sets flag: true - extends track candidates with unused hits + void SetExtendTracksFlag(bool flag) { fIsExtendTracks = flag; } - /// Sets index of first station used in tracking + /// @brief 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; } + /// @brief Sets flag: true - triplets are built from hits .... TODO + void SetJumpedFlag(bool flag) { fIsJumped = flag; } - /// Sets correction for accounting overlaping and iff z + /// @brief Sets correction for accounting overlaping and iff z void SetMaxDZ(float input) { fMaxDZ = input; } - /// Sets max considered q/p for tracks + /// @brief Sets max considered q/p for tracks void SetMaxQp(float input) { fMaxQp = input; } - /// Sets max slope (tx\ty) in 3D hit position of a triplet + /// @brief Sets max slope (tx\ty) in 3D hit position of a triplet void SetMaxSlope(float input) { fMaxSlope = input; } - /// Sets max slope (tx\ty) in primary vertex + /// @brief Sets max slope (tx\ty) in primary vertex void SetMaxSlopePV(float input) { fMaxSlopePV = input; } - /// Sets name of the iteration + /// @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; } - /// Sets size of region [TODO: units??] to attach new hits to the created track + /// @brief Sets size of region [TODO: units??] to attach new hits to the created track void SetPickGather(float input) { fPickGather = input; } - /// Sets min value of dp/dp_error, for which two tiplets are neighbours - void SetTripletLinkChi2(float input) { fTripletLinkChi2 = input; } - - /// Sets flag: primary tracks - true, secondary tracks - false + /// @brief Sets flag: primary tracks - true, secondary tracks - false void SetPrimaryFlag(bool flag) { fIsPrimary = flag; } - /// Sets flag: true - skip track candidates with level = 0 - void SetMinNhits(int val) { fMinNhits = val; } - - /// Sets min n hits for tracks that start on station 0 - void SetMinNhitsStation0(int val) { fMinNhitsStation0 = val; } - - - /// Sets sigma of target positions in XY plane - /// \param sigmaX Sigma value in X direction [cm] - /// \param sigmaX Sigma value in Y direction [cm] + /// @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 @@ -204,10 +200,19 @@ public: /// Sets triplet chi2 upper cut void SetTripletFinalChi2Cut(float input) { fTripletFinalChi2Cut = input; } - /// String representation of the class contents - /// \param indentLevel Level of indentation for the text (in terms of \t symbols) + /// @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 @@ -230,27 +235,25 @@ private: 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 - bool fIsPrimary = false; ///< Flag: true - only primary tracks are searched for - bool fIsElectron = false; ///< Flag: true - only electrons are searched for - /// \brief Flag to select triplets on the iteration as tracks + /// @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 + /// @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; - bool fIfExtendTracks = false; ///< Flag: true - extends track candidates with unused hits - bool fIfJumped = false; ///< Flag: true - find triplets with skip station - - int fMinNhits = 3; ///< min n hits on the tracks - int fMinNhitsStation0 = 3; ///< min n hits for tracks that start on station 0 - /// Serialization method, used to save L1Hit objects into binary or text file in a defined order friend class boost::serialization::access; template<class Archive> @@ -270,26 +273,67 @@ private: ar& fTargetPosSigmaX; ar& fTargetPosSigmaY; ar& fFirstStationIndex; + ar& fMinNhits; + ar& fMinNhitsStation0; ar& fIsPrimary; ar& fIsElectron; + ar& fIsExtendTracks; + ar& fIsJumped; ar& fIsTrackFromTriplets; - ar& fIfExtendTracks; - ar& fIfJumped; - ar& fMinNhits; - ar& fMinNhitsStation0; } - /// 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 + /// @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); - - // ^ TODO: invent more proper name }; +// --------------------------------------------------------------------------------------------------------------------- +// +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> diff --git a/reco/L1/L1Algo/L1CaTrackFinderSlice.cxx b/reco/L1/L1Algo/L1CaTrackFinderSlice.cxx index 3bc126a16b0864f297f73c0bd7ead6a930a4e5bc..6d98f36807888e878ca8312f738dbfcf57618185 100644 --- a/reco/L1/L1Algo/L1CaTrackFinderSlice.cxx +++ b/reco/L1/L1Algo/L1CaTrackFinderSlice.cxx @@ -625,6 +625,7 @@ inline void L1Algo::findTripletsStep0( // input for (size_t i2_4 = 0; i2_4 < n2_4; ++i2_4) { //if (!T2.IsEntryConsistent(false, i2_4)) { continue; } + // FIXME: SZh 22.08.2023: Remove the hack!! (Why is it used only for kSts?) if (kSts == fTrackingMode && (T2.C44[i2_4] < 0)) { continue; } if (T2.C00[i2_4] < 0 || T2.C11[i2_4] < 0 || T2.C22[i2_4] < 0 || T2.C33[i2_4] < 0 || T2.C55[i2_4] < 0) continue; @@ -2474,6 +2475,7 @@ inline void L1Algo::CAFindTrack(int ista, L1Branch& best_tr, unsigned char& best } //if( curr_L < min_best_l - 1 ) return; // suppouse that only one hit can be added by extender + // TODO: SZh 21.08.2023: Replace hard-coded value with a parameter int ndf = curr_L * 2 - 5; if (kGlobal == fTrackingMode || kMcbm == fTrackingMode) { ndf = curr_L * 2 - 4; } diff --git a/reco/L1/L1Algo/L1ConfigRW.cxx b/reco/L1/L1Algo/L1ConfigRW.cxx index 22f179f05d87e757f435cd7e1d1d87bbefc44439..e2fd919656fc0446f4f409b23dded1c30fa865f7 100644 --- a/reco/L1/L1Algo/L1ConfigRW.cxx +++ b/reco/L1/L1Algo/L1ConfigRW.cxx @@ -9,12 +9,16 @@ #include "L1ConfigRW.h" +#include <boost/algorithm/string.hpp> + #include <iostream> #include <numeric> #include <sstream> +#include <unordered_map> #include <yaml-cpp/yaml.h> +#include "L1Constants.h" #include "L1InitManager.h" using namespace std::string_literals; @@ -23,6 +27,23 @@ using namespace std::string_literals; // L1ConfigRW::L1ConfigRW(L1InitManager* pInitManager, int verbose) : fpInitManager(pInitManager), fVerbose(verbose) {} +// --------------------------------------------------------------------------------------------------------------------- +// +YAML::Node L1ConfigRW::GetNode(std::function<YAML::Node(YAML::Node)> fn) const +{ + auto node = YAML::Node(YAML::NodeType::Undefined); + if (fUserConfigNode) { node = fn(fUserConfigNode); } + if (!node) { node = fn(fMainConfigNode); } + if (!node) { + std::stringstream msg; + msg << "requested node was not found "; + if (fUserConfigNode) { msg << "either in user config (path: " << fsUserConfigPath << ") or "; } + msg << "in main config (path: " << fsMainConfigPath << ")"; + throw std::runtime_error(msg.str()); + } + return node; +} + // --------------------------------------------------------------------------------------------------------------------- // std::vector<std::string> L1ConfigRW::GetNodeKeys(const YAML::Node& node) const @@ -34,12 +55,11 @@ std::vector<std::string> L1ConfigRW::GetNodeKeys(const YAML::Node& node) const res.push_back(item.first.as<std::string>()); } } - catch (const YAML::InvalidNode& exc) { // It is impossible to + catch (const YAML::InvalidNode& exc) { LOG(warn) << "L1 config: attempt to call L1ConfigRW::GetNodeKeys for node, keys of which could not be represented " << "with strings. An empty vector will be returned"; std::vector<std::string>().swap(res); } - return res; } @@ -47,76 +67,229 @@ std::vector<std::string> L1ConfigRW::GetNodeKeys(const YAML::Node& node) const // void L1ConfigRW::Read() { - if (!fsBaseConfigPath.size()) { throw std::runtime_error("the base configuration path is undefined"); } - - // Read possible iterations list - auto configBase = YAML::LoadFile(fsBaseConfigPath)["ca"]; - this->ReadPossibleIterations(configBase["possible_iterations"]); - - // Read actual iteration sequence - const auto& actualIterNode = configBase["core"]["track_finder"]["iteration_sequence"]; - if (!actualIterNode) { - std::stringstream msg; - msg << "Configuration branch ca/core/track_finder/iteration_sequence is not defined in " << fsBaseConfigPath; - throw std::runtime_error(msg.str()); - } - std::vector<std::string> vActualIterationSequenceNames {}; - for (const auto& node : actualIterNode) { - vActualIterationSequenceNames.push_back(node.as<std::string>()); + { // Init CA iterations in L1InitManager + LOG(info) << "- reading track finder iterations"; + auto iters = this->ReadCAIterationVector(); + assert(iters.size()); + fpInitManager->ClearCAIterations(); + fpInitManager->SetCAIterationsNumberCrosscheck(iters.size()); + std::for_each(iters.begin(), iters.end(), [&](auto& iter) { fpInitManager->PushBackCAIteration(iter); }); } - // Init CA iterations in L1InitManager - fpInitManager->ClearCAIterations(); - fpInitManager->SetCAIterationsNumberCrosscheck(vActualIterationSequenceNames.size()); - for (const auto& iterName : vActualIterationSequenceNames) { - fpInitManager->PushBackCAIteration(fmPossibleIterations.at(iterName)); + { // Unset inactive tracking stations + LOG(info) << "- unsetting inactive tracking stations"; + auto inactiveMap = this->ReadInactiveStationMap(); + if (std::any_of(inactiveMap.begin(), inactiveMap.end(), [](const auto& s) { return (s.size() != 0); })) { + for (auto& station : fpInitManager->GetStationInfo()) { + int iDet = static_cast<int>(station.GetDetectorID()); + int iStLoc = station.GetStationID(); + if (inactiveMap[iDet].find(iStLoc) != inactiveMap[iDet].end()) { station.SetTrackingStatus(false); } + } + // Since we disabled some stations, we have to rerun the layout initialization again, thus the station scheme is + // kept consistent + fpInitManager->InitStationLayout(); + } } - // + // Init parameters, independnent from the tracking iteration + LOG(info) << "- reading miscellaneous parameters"; + fpInitManager->SetRandomSeed( + GetNode([](YAML::Node n) { return n["core"]["common"]["random_seed"]; }).as<unsigned int>()); + fpInitManager->SetGhostSuppression( + GetNode([](YAML::Node n) { return n["core"]["track_finder"]["is_ghost_suppression"]; }).as<bool>()); + fpInitManager->SetMaxDoubletsPerSinglet( + GetNode([](YAML::Node n) { return n["core"]["track_finder"]["max_doublets_per_singlet"]; }).as<unsigned int>()); + fpInitManager->SetMaxTripletPerDoublets( + GetNode([](YAML::Node n) { return n["core"]["track_finder"]["max_triplets_per_doublet"]; }).as<unsigned int>()); + LOG(info) << "- reading developement parameters"; + // Dev flags + fpInitManager->DevSetIgnoreHitSearchAreas( + GetNode([](YAML::Node n) { return n["core"]["dev"]["ignore_hit_search_areas"]; }).as<bool>()); + fpInitManager->DevSetUseOfOriginalField( + GetNode([](YAML::Node n) { return n["core"]["dev"]["use_of_original_field"]; }).as<bool>()); + fpInitManager->DevSetIsMatchDoubletsViaMc( + GetNode([](YAML::Node n) { return n["core"]["dev"]["match_doublets_via_mc"]; }).as<bool>()); + fpInitManager->DevSetIsMatchTripletsViaMc( + GetNode([](YAML::Node n) { return n["core"]["dev"]["match_triplets_via_mc"]; }).as<bool>()); + fpInitManager->DevSetIsExtendTracksViaMc( + GetNode([](YAML::Node n) { return n["core"]["dev"]["extend_tracks_via_mc"]; }).as<bool>()); + fpInitManager->DevSetIsSuppressOverlapHitsViaMc( + GetNode([](YAML::Node n) { return n["core"]["dev"]["suppress_overlap_hits_via_mc"]; }).as<bool>()); } - // --------------------------------------------------------------------------------------------------------------------- // -void L1ConfigRW::ReadPossibleIterations(const YAML::Node& node) +std::vector<L1CAIteration> L1ConfigRW::ReadCAIterationVector() { - // Default iterations map initialization - // The first iteration in the list should be "Default" and provide all the fields filled. Other iterations in the list - // either can be created from the default one or from iterations above in the list. + std::vector<L1CAIteration> res; + + // Read iterations store + std::unordered_map<std::string, L1CAIteration> mPossibleIterations; + { + auto currentNode = fMainConfigNode["possible_iterations"]; + assert(currentNode); + for (const auto& iterNode : currentNode) { + std::string thisIterName = iterNode["name"].as<std::string>(""); + std::string baseIterName = iterNode["base_iteration"].as<std::string>(""); - for (const auto& iterNode : node) { - std::string thisIterName = iterNode["name"].as<std::string>(""); - std::string baseIterName = iterNode["base_iteration"].as<std::string>(""); + if (baseIterName.size()) { // Create iteration from previously defined one + if (mPossibleIterations.find(baseIterName) == mPossibleIterations.end()) { + std::stringstream msg; + msg << "A CA iteration \"" << thisIterName << "\" requires a base iteration with name \"" << baseIterName + << "\", which was not registered yet. Please, place an entry with the requested base iteration above " + << "in the possible_iterations node"; + throw std::runtime_error(std::move(msg.str())); + } + mPossibleIterations[thisIterName] = ReadSingleCAIteration(iterNode, mPossibleIterations.at(baseIterName)); + } + else { + mPossibleIterations[thisIterName] = ReadSingleCAIteration(iterNode, L1CAIteration()); + } + } + } - if (baseIterName.size()) { // Create an iteration from already defined one - if (fmPossibleIterations.find(baseIterName) == fmPossibleIterations.end()) { + // Read actual iteration sequence + // + if (fUserConfigNode) { + auto currentNode = fUserConfigNode["core"]["track_finder"]["iterations"]; + if (currentNode) { + for (const auto& iterNode : currentNode) { + std::string thisIterName = iterNode["name"].as<std::string>(""); + std::string baseIterName = iterNode["base_iteration"].as<std::string>(""); + LOG(info) << "- Reading user iteration " << thisIterName << "(" << baseIterName << ")"; + if (mPossibleIterations.find(thisIterName) != mPossibleIterations.end()) { + // This is an update of existing possible iteration + LOG(info) << "- Select A"; + res.push_back(ReadSingleCAIteration(iterNode, mPossibleIterations.at(thisIterName))); + } + else if (mPossibleIterations.find(baseIterName) != mPossibleIterations.end()) { + // This is a user iteration based on the existing possible iteration + LOG(info) << "- Select B"; + res.push_back(ReadSingleCAIteration(iterNode, mPossibleIterations.at(baseIterName))); + } + else { + // Try to find a base iteration from user-defined + auto itFound = std::find_if(res.begin(), res.end(), [&](auto& i) { return i.GetName() == baseIterName; }); + if (itFound != res.end()) { + LOG(info) << "- Select C"; + res.push_back(ReadSingleCAIteration(iterNode, *itFound)); + } + else { + LOG(info) << "- Select D"; + res.push_back(ReadSingleCAIteration(iterNode, L1CAIteration())); + } + } + } + } + } + + if (res.size() == 0) { + auto currentNode = fMainConfigNode["core"]["track_finder"]["iteration_sequence"]; + assert(currentNode); + assert(currentNode.size()); + for (const auto& iterNode : currentNode) { + std::string thisIterName = iterNode.as<std::string>(); + if (mPossibleIterations.find(thisIterName) == mPossibleIterations.end()) { std::stringstream msg; - msg << "A CA iteration \"" << thisIterName << "\" requires a base iteration \"" << baseIterName - << "\", which " - "was not registered yet. Please, place an entry with the requested base iteration above in the " - "possible_iterations node"; + msg << "Unknow iteration in the iteration sequence, defined in main config file: " << thisIterName; throw std::runtime_error(std::move(msg.str())); } - fmPossibleIterations[thisIterName] = ReadSingleCAIteration(iterNode, fmPossibleIterations.at(baseIterName)); - } - else { - fmPossibleIterations[thisIterName] = ReadSingleCAIteration(iterNode, L1CAIteration()); + res.push_back(mPossibleIterations.at(thisIterName)); } } + + return res; } // --------------------------------------------------------------------------------------------------------------------- // -std::vector<L1CAIteration> L1ConfigRW::ReadCAIterations(const YAML::Node& node) const +std::vector<std::set<int>> L1ConfigRW::ReadInactiveStationMap() { - std::vector<L1CAIteration> vIters; - if (node) { - // Loop over input sub-nodes. Each sub-node corresponds to one L1CAIteration object - for (const auto& input : node) { - vIters.push_back(ReadSingleCAIteration(input, L1CAIteration())); - } // Loop over input sub-nodes: end + // Check, if the "skip_stations" branch exists either in the user config or in the main config + std::string sNodePath = "ca/core/common/inactive_stations"; + auto node = this->GetNode([](YAML::Node n) { return n["core"]["common"]["inactive_stations"]; }); + + // Fill map of inactive stations + std::vector<std::set<int>> vGeoIdToTrackingStatus(fpInitManager->GetNstationsGeometry()); + + if (node && node.size()) { + std::unordered_map<std::string, int> mDetNameToID; + for (int iDet = 0; iDet < L1Constants::size::kMaxNdetectors; ++iDet) { + auto detName = boost::algorithm::to_lower_copy(fpInitManager->GetDetectorName(static_cast<L1DetectorID>(iDet))); + if (!detName.size()) { continue; } + mDetNameToID[detName] = iDet; + } + for (const auto& item : node) { + std::string stName = item.as<std::string>(); + if (!stName.size()) { continue; } + // + // Check name for spaces + if (std::any_of(stName.begin(), stName.end(), [](auto c) { return c == ' ' || c == '\t' || c == '\n'; })) { + std::stringstream msg; + msg << "Illegal station name in the configuration branch \"" << sNodePath << "\": \"" << stName + << "\" contains illegal characters"; + throw std::runtime_error(msg.str()); + } + // + // Split stName into a detector name and a station number + std::vector<std::string> vNames; + boost::algorithm::split(vNames, stName, boost::is_any_of(":")); + if (vNames.size() > 2) { + std::stringstream msg; + msg << "Illegal station name in the configuration branch \"" << sNodePath << "\": \"" << stName + << "\" contains more then one colon character"; + throw std::runtime_error(msg.str()); + } + // + // Parse detector name + const auto& detName = boost::algorithm::to_lower_copy(vNames.front()); + auto it = mDetNameToID.find(detName); + if (it == mDetNameToID.end()) { + std::stringstream msg; + msg << "L1ConfigRW: legal but undefined name of the detector \"" << detName << "\" (originally \"" << stName + << "\") was passed to the " << sNodePath << " config " + << "branch"; + throw std::runtime_error(msg.str()); + } + + int nStations = fpInitManager->GetNstationsGeometry(static_cast<L1DetectorID>(it->second)); + if (vNames.size() == 2) { // Disable one particular station + try { + int iStLoc = std::stoi(vNames.back()); + if (iStLoc < 0 || iStLoc >= nStations) { throw std::runtime_error("illegal local station index"); } + vGeoIdToTrackingStatus[it->second].insert(iStLoc); + } + catch (const std::exception&) { + std::stringstream msg; + msg << "Illegal station name in the configuration branch \"" << sNodePath << "\": \"" << stName + << "\" contains expression after the colon symbol, which cannot be translated " + << "to a local number of station"; + throw std::runtime_error(msg.str()); + } + } + else { // Disable all stations for this detector + for (int iStLoc = 0; iStLoc < nStations; ++iStLoc) { + vGeoIdToTrackingStatus[it->second].insert(iStLoc); + } + } + } + + std::stringstream msg; + msg << "\033[1;31m L1ConfigRW: the next tracking stations will be disabled from the configuration file:\n"; + for (int iDet = 0; iDet < static_cast<int>(mDetNameToID.size()); ++iDet) { + const auto& detName = fpInitManager->GetDetectorName(static_cast<L1DetectorID>(iDet)); + int nStations = fpInitManager->GetNstationsGeometry(static_cast<L1DetectorID>(iDet)); + for (int iStLoc = 0; iStLoc < nStations; ++iStLoc) { + if (vGeoIdToTrackingStatus[iDet].find(iStLoc) != vGeoIdToTrackingStatus[iDet].end()) { + msg << "\t- " << detName << iStLoc << '\n'; + } + } + } + msg << "\033[0m"; + LOG(warn) << msg.str(); } - return vIters; + + return vGeoIdToTrackingStatus; } // --------------------------------------------------------------------------------------------------------------------- @@ -145,8 +318,7 @@ L1CAIteration L1ConfigRW::ReadSingleCAIteration(const YAML::Node& node, const L1 iter.SetExtendTracksFlag(node["if_extend_tracks"].as<bool>(defaultIter.GetExtendTracksFlag())); iter.SetJumpedFlag(node["is_jumped"].as<bool>(defaultIter.GetJumpedFlag())); iter.SetMinNhits(node["min_n_hits"].as<int>(defaultIter.GetMinNhits())); - iter.SetMinNhitsStation0(node["min_n_hits_sta_0"].as<int>(defaultIter.GetMinNhitsStation0())); - if (fVerbose > 3) { LOG(info) << "L1 config:\n" << iter.ToString(1); } + iter.SetMinNhitsStation0(node["min_n_hits_station_0"].as<int>(defaultIter.GetMinNhitsStation0())); } catch (const YAML::InvalidNode& exc) { const auto nodeKeys = this->GetNodeKeys(node); @@ -161,4 +333,32 @@ L1CAIteration L1ConfigRW::ReadSingleCAIteration(const YAML::Node& node, const L1 // --------------------------------------------------------------------------------------------------------------------- // -void L1ConfigRW::WriteYaml(const std::string& /*filename*/) {} +void L1ConfigRW::SetMainConfigPath(const std::string& path) +{ + if (path.size()) { + try { + fsMainConfigPath = path; + fMainConfigNode = YAML::LoadFile(fsMainConfigPath)["ca"]; + LOG(info) << "L1ConfigRW: Registering main configuraiton file: \"\033[1;32m" << path << "\033[0m\""; + } + catch (const std::exception& err) { + LOG(error) << "ERROR: " << err.what(); + } + } +} + +// --------------------------------------------------------------------------------------------------------------------- +// +void L1ConfigRW::SetUserConfigPath(const std::string& path) +{ + if (path.size()) { + try { + fsUserConfigPath = path; + fUserConfigNode = YAML::LoadFile(fsUserConfigPath)["ca"]; + LOG(info) << "L1ConfigRW: Registering user configuraiton file: \"\033[1;32m" << path << "\033[0m\""; + } + catch (const std::exception& err) { + LOG(error) << "ERROR: " << err.what(); + } + } +} diff --git a/reco/L1/L1Algo/L1ConfigRW.h b/reco/L1/L1Algo/L1ConfigRW.h index 6685aea9146a7c650c3d1dbd92694c8aae0f480f..1137d506dc0e21f70754ac9d88f9ac881a2b2247 100644 --- a/reco/L1/L1Algo/L1ConfigRW.h +++ b/reco/L1/L1Algo/L1ConfigRW.h @@ -14,6 +14,8 @@ #include <unordered_map> #include <vector> +#include <yaml-cpp/yaml.h> + #include "L1CAIteration.h" namespace YAML @@ -21,61 +23,67 @@ namespace YAML class Node; } class L1InitManager; +enum class L1DetectorID; /// Class L1ConfigRW provides internal read and write methods for L1 tracking algorithm parameters class L1ConfigRW { public: - /// Constructor - /// \param pInitManager Pointer to the L1InitManager instance + /// @brief Constructor + /// @param pInitManager Pointer to the L1InitManager instance L1ConfigRW(L1InitManager* pInitManager, int verbose = 0); - /// Destructor - ~L1ConfigRW() {} + /// @brief Destructor + ~L1ConfigRW() = default; /// @brief Reads configuration from files void Read(); - /// Writes parameters to the file - /// \param filename Name of the configuration file - void WriteYaml(const std::string& filename); - - /// Reads CA track finder iterations from YAML node - /// \param node YAML node containing the iterations - /// \return A vector of iterations - std::vector<L1CAIteration> ReadCAIterations(const YAML::Node& node) const; + /// @brief Reads CA track finder iterations from YAML node + /// @return A vector of iterations + std::vector<L1CAIteration> ReadCAIterationVector(); - /// @brief Sets base config file + /// @brief Sets main config file /// @param path Path to the file - void SetBaseConfigPath(const std::string& path) { fsBaseConfigPath = path; } + void SetMainConfigPath(const std::string& path); /// @brief Sets user config file /// @param path Path to user config file - void SetUserConfigPath(const std::string& path) { fsUserConfigPath = path; } - + void SetUserConfigPath(const std::string& path); private: - /// @brief Reads possible iterations from node - /// @param node YAML node, containing a list of default (possible) iterations - void ReadPossibleIterations(const YAML::Node& node); + /// @brief Reads inactive tracking station map + /// @return A vector of sets of disabled station local indexes vs. the the detector index + std::vector<std::set<int>> ReadInactiveStationMap(); + + /// @brief Accesses a node either from user config or from main config + /// @param fn A function, which returns a YAML::Node reference object + /// @note If the node is not found in both configs + /// @throw std::runtime_error, if the path does not exist in the config + /// + /// This function is to be used, if the desired node should exist either in main or in user config. Firstly, + /// the user config is checked, if it is provided. If the node is not found in user config, the main config + /// is checked. If the node does not exist in the main config as well, an exception will be thrown. + YAML::Node GetNode(std::function<YAML::Node(YAML::Node)> fn) const; /// @brief Reads iteration from config file /// @param node YAML node containing an iteration /// @param defaultIter Default iteration - /// @return An iteration object + /// @return A CA-iteration object L1CAIteration ReadSingleCAIteration(const YAML::Node& node, const L1CAIteration& defaultIter) const; - /// Gets parameters content of the node - /// \param node YAML node - /// \return Vector of key names + /// @brief Gets parameters content of the node + /// @param node YAML node + /// @return Vector of key names std::vector<std::string> GetNodeKeys(const YAML::Node& node) const; L1InitManager* fpInitManager = nullptr; ///< Pointer to the L1InitManager instance int fVerbose = 0; ///< Verbosity level - std::string fsBaseConfigPath = ""; ///< Path to base config file (mandatory) - std::string fsUserConfigPath = ""; ///< Path to user config file (optional) + std::string fsMainConfigPath = ""; ///< Path to the main config file (mandatory) + std::string fsUserConfigPath = ""; ///< Path to the user config file (optional) - std::unordered_map<std::string, L1CAIteration> fmPossibleIterations; ///< full list of possible CA iterations + YAML::Node fMainConfigNode {YAML::NodeType::Undefined}; ///< Main configuration node + YAML::Node fUserConfigNode {YAML::NodeType::Undefined}; ///< User configuration node }; #endif // L1ConfigRW_h diff --git a/reco/L1/L1Algo/L1Constants.h b/reco/L1/L1Algo/L1Constants.h index 08047172e5c3d41c2c8fa3eb86d4a7fdec8dcccf..eed01d2eecfb502c54a9edfe9ca416a50247563a 100644 --- a/reco/L1/L1Algo/L1Constants.h +++ b/reco/L1/L1Algo/L1Constants.h @@ -77,7 +77,8 @@ namespace L1Constants { /* Particle masses used for track fit */ constexpr float kMuonMass = 0.10565800f; ///< Muon mass [GeV/c2] !! TODO: discrepancy in last two digits - constexpr float kPionMass = 0.13957039f; ///< Pion mass [GeV/c2] + constexpr float kPionMass = 0.13957039f; ///< Pion mass [GeV/c2] + constexpr float kKaonMass = 0.493677f; ///< Kaon mass [GeV/c2] (PDG 22.08.2023) constexpr float kElectronMass = 0.000511f; ///< Electron mass [GeV/c2] constexpr float kProtonMass = 0.93827209f; ///< Proton mass [GeV/c2] (0.93827208816 - PDG 11.08.2022) constexpr double kSpeedOfLight = 29.9792458; ///< Speed of light [cm/ns] diff --git a/reco/L1/L1Algo/L1EArray.h b/reco/L1/L1Algo/L1EArray.h index 272238f7312f622c3d79c8bd3dac75c5ba940b99..cf4ba2b31cac686ae2a19e5c636037816255c762 100644 --- a/reco/L1/L1Algo/L1EArray.h +++ b/reco/L1/L1Algo/L1EArray.h @@ -19,7 +19,9 @@ /// @tparam T Type of data in the underlying array template<class E, class T> class L1EArray : public std::array<T, static_cast<std::size_t>(E::kEND)> { - using U = typename std::underlying_type<E>::type; ///< Underlying type of enumeration + using U = typename std::underlying_type<E>::type; ///< Underlying type of enumeration + using Arr = std::array<T, static_cast<std::size_t>(E::kEND)>; + public: /// @brief Mutable access operator, indexed by enum entry T& operator[](const E& entry) @@ -38,6 +40,9 @@ public: /// @brief Constant access operator, indexed by underlying index type const T& operator[](U index) const { return std::array<T, static_cast<std::size_t>(E::kEND)>::operator[](index); } + + /// @brief Convertion operator to the base array class + operator Arr&() const { return *this; } }; #endif // L1EArray_h diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx index fc219754a6c96f1a3afabd80fccc61cdffffbee2..00d5b610c870aee958420fdf508be149a882036f 100644 --- a/reco/L1/L1Algo/L1InitManager.cxx +++ b/reco/L1/L1Algo/L1InitManager.cxx @@ -51,16 +51,11 @@ void L1InitManager::ClearSetupInfo() { // Clear stations set and a thickness map fvStationInfo.clear(); - std::fill(fParameters.fThickMap.begin(), fParameters.fThickMap.end(), L1Material()); + fParameters.fThickMap.fill(L1Material()); fInitController.SetFlag(EInitKey::kStationsInfo, false); // Set number of stations do default values - std::fill(fParameters.fvFirstGeoId.begin(), fParameters.fvFirstGeoId.end(), 0); - std::fill(fParameters.fvLocalToGeoIdMap.begin(), fParameters.fvLocalToGeoIdMap.end(), 0); - std::fill(fParameters.fvGeoToActiveMap.begin(), fParameters.fvGeoToActiveMap.end(), 0); - std::fill(fParameters.fvActiveToGeoMap.begin(), fParameters.fvActiveToGeoMap.end(), 0); - fParameters.fNstationsActiveTotal = -1; - fInitController.SetFlag(EInitKey::kStationLayoutInitialized, false); + this->ClearStationLayout(); // Clear active detectors fActiveDetectorIDs.clear(); @@ -72,7 +67,7 @@ void L1InitManager::ClearSetupInfo() fInitController.SetFlag(EInitKey::kPrimaryVertexField, false); // Clear target position - std::fill(fParameters.fTargetPos.begin(), fParameters.fTargetPos.end(), L1Utils::kNaN); + fParameters.fTargetPos.fill(L1Utils::kNaN); fTargetZ = 0.; fInitController.SetFlag(EInitKey::kTargetPos, false); @@ -81,12 +76,10 @@ void L1InitManager::ClearSetupInfo() fInitController.SetFlag(EInitKey::kFieldFunction, false); // Clear other flags - fParameters.fTrackingLevel = 0; + fParameters.fRandomSeed = 1; fParameters.fGhostSuppression = 0; - fParameters.fMomentumCutOff = 0; - fInitController.SetFlag(EInitKey::kTrackingLevel, false); + fInitController.SetFlag(EInitKey::kRandomSeed, false); fInitController.SetFlag(EInitKey::kGhostSuppression, false); - fInitController.SetFlag(EInitKey::kMomentumCutOff, false); fParameters.fDevIsIgnoreHitSearchAreas = false; fParameters.fDevIsUseOfOriginalField = false; @@ -114,6 +107,7 @@ bool L1InitManager::FormParametersContainer() LOG(info) << "L1InitManager: reading parameter configuration ..."; try { fConfigRW.Read(); + LOG(info) << "L1InitManager: reading parameter configuration ... \033[1;32mdone\033[0m"; } catch (const std::runtime_error& err) { LOG(error) << "L1InitManager: reading parameter configuration ... \033[1;31mfail\033[0m. Reason: " << err.what(); @@ -214,6 +208,7 @@ std::vector<L1BaseStationInfo>& L1InitManager::GetStationInfo() // void L1InitManager::InitStationLayout() { + this->ClearStationLayout(); std::sort(fvStationInfo.begin(), fvStationInfo.end()); for (const auto& aStation : fvStationInfo) { @@ -228,6 +223,8 @@ void L1InitManager::InitStationLayout() const auto& aStation = fvStationInfo[iStGeo]; int iDet = static_cast<int>(aStation.GetDetectorID()); int iStLocal = aStation.GetStationID(); + // Fill local -> geo map + fParameters.fvGeoToLocalIdMap[iStGeo] = std::make_pair(aStation.GetDetectorID(), iStLocal); // Fill geo -> local map fParameters.fvLocalToGeoIdMap[fParameters.fvFirstGeoId[iDet] + iStLocal] = iStGeo; // Fill geo <-> active map @@ -421,14 +418,14 @@ void L1InitManager::SetGhostSuppression(int ghostSuppression) // ---------------------------------------------------------------------------------------------------------------------- // -void L1InitManager::SetMomentumCutOff(float momentumCutOff) +void L1InitManager::SetRandomSeed(unsigned int seed) { - if (fInitController.GetFlag(EInitKey::kMomentumCutOff)) { - LOG(warn) << "L1InitManager::SetMomentumCutOff: attempt of reinitializating the momentum cutoff value. Ignore"; + if (fInitController.GetFlag(EInitKey::kRandomSeed)) { + LOG(warn) << "L1InitManager::SetRandomSeed: attempt of reinitializating the random seed. Ignore"; return; } - fParameters.fMomentumCutOff = momentumCutOff; - fInitController.SetFlag(EInitKey::kMomentumCutOff); + fParameters.fRandomSeed = seed; + fInitController.SetFlag(EInitKey::kRandomSeed); } // ---------------------------------------------------------------------------------------------------------------------- @@ -449,18 +446,6 @@ void L1InitManager::SetTargetPosition(double x, double y, double z) fInitController.SetFlag(EInitKey::kTargetPos); } -// ---------------------------------------------------------------------------------------------------------------------- -// -void L1InitManager::SetTrackingLevel(int trackingLevel) -{ - if (fInitController.GetFlag(EInitKey::kTrackingLevel)) { - LOG(warn) << "L1InitManager::SetTrackingLevel: attempt of reinitialization the tracking level. Ignore"; - return; - } - fParameters.fTrackingLevel = trackingLevel; - fInitController.SetFlag(EInitKey::kTrackingLevel); -} - // ---------------------------------------------------------------------------------------------------------------------- // void L1InitManager::WriteParametersObject(const std::string& fileName) const @@ -487,9 +472,6 @@ void L1InitManager::WriteParametersObject(const std::string& fileName) const // void L1InitManager::CheckCAIterationsInit() { - // - // 1) Check number of iterations - // bool ifInitPassed = true; if (!fInitController.GetFlag(EInitKey::kCAIterations)) { int nIterationsActual = fParameters.fCAIterations.size(); @@ -522,6 +504,18 @@ void L1InitManager::CheckStationsInfoInit() << " L1Constants::size::kMaxNstations value"; } } - fInitController.SetFlag(EInitKey::kStationsInfo, ifInitPassed); } + +// --------------------------------------------------------------------------------------------------------------------- +// +void L1InitManager::ClearStationLayout() +{ + fParameters.fvFirstGeoId.fill(0); + fParameters.fvLocalToGeoIdMap.fill(0); + fParameters.fvGeoToLocalIdMap.fill(std::make_pair(static_cast<L1DetectorID>(0), -1)); + fParameters.fvGeoToActiveMap.fill(-1); // Note: by default all the stations are inactive + fParameters.fvActiveToGeoMap.fill(0); + fParameters.fNstationsActiveTotal = -1; + fInitController.SetFlag(EInitKey::kStationLayoutInitialized, false); +} diff --git a/reco/L1/L1Algo/L1InitManager.h b/reco/L1/L1Algo/L1InitManager.h index eba788929d82cb2f1667fbc3a3d3b3b0cff42c8c..d61e1230d3299292d4638b7d277e1aaedeb7e9ec 100644 --- a/reco/L1/L1Algo/L1InitManager.h +++ b/reco/L1/L1Algo/L1InitManager.h @@ -21,6 +21,7 @@ #include "L1CAIteration.h" #include "L1ConfigRW.h" #include "L1Constants.h" +#include "L1EArray.h" #include "L1Field.h" #include "L1ObjectInitController.h" #include "L1Parameters.h" @@ -84,9 +85,8 @@ private: kCAIterationsNumberCrosscheck, ///< 5) If the number of CA track finder is initialized kCAIterations, ///< 6) If the CA track finder iterations were initialized kSearchWindows, ///< 7) If the hit search windows were initialized - kTrackingLevel, ///< 8) kGhostSuppression, ///< 9) - kMomentumCutOff, ///< 10) + kRandomSeed, ///< 10) If the random seed is provided kStationLayoutInitialized, ///< 11) If stations layout is initialized kEnd ///< 12) [technical] number of entries in the enumeration }; @@ -95,6 +95,8 @@ private: using L1DetectorIDSet_t = std::set<L1DetectorID>; using L1FieldFunction_t = std::function<void(const double (&xyz)[3], double (&B)[3])>; using InitController_t = L1ObjectInitController<static_cast<int>(EInitKey::kEnd), EInitKey>; + template<typename T> + using L1DetectorIDArr_t = std::array<T, L1Constants::size::kMaxNdetectors>; public: /// Default constructor @@ -141,15 +143,17 @@ public: /// @return Reference to configuration module L1ConfigRW& GetConfigRW() { return fConfigRW; } + /// @brief Gets name of the detector + /// @param detId Index of the detector + /// @return Name of the detector + const std::string& GetDetectorName(L1DetectorID detId) const { return fvDetectorNames[static_cast<int>(detId)]; } + /// Gets ghost suppression flag int GetGhostSuppression() const { return fParameters.fGhostSuppression; } /// Gets a name of the input configuration file const std::string& GetInputConfigName() const { return fConfigInputName; } - /// Gets momentum cutoff - float GetMomentumCutOff() const { return fParameters.fMomentumCutOff; } - /// Gets a const reference to L1ObjectInitController const InitController_t& GetInitController() const { return fInitController; } @@ -171,9 +175,6 @@ public: /// @brief Gets a reference to the stations array std::vector<L1BaseStationInfo>& GetStationInfo(); - /// Gets tracking level - int GetTrackingLevel() const { return fParameters.fTrackingLevel; } - /// @brief Initializes station layout /// /// This function is to be called after all the tracking stations (L1BaseStationInfo objects) are added to the @@ -209,20 +210,34 @@ public: /// Sets a number of CA track finder iterations to provide initialization cross-check void SetCAIterationsNumberCrosscheck(int nIterations); + /// @brief Sets base configuration file + /// @param baseConfig Path to base configuration file + /// @note The base configuraiton file is mandatory until the tracking configuration is initialized from + /// beforehand created L1Parameters file. + void SetConfigMain(const std::string& baseConfig) { fConfigRW.SetMainConfigPath(baseConfig); } + + /// @brief Sets user configuration file + /// @param userConfig Path to user configuration file + /// @note The user configuraiton file is optional + void SetConfigUser(const std::string& userConfig) { fConfigRW.SetUserConfigPath(userConfig); } + + /// @brief Sets detector names + /// @param container Container of the detector names + template<size_t Size> + void SetDetectorNames(const std::array<const char*, Size>& container) + { + static_assert(Size <= L1Constants::size::kMaxNdetectors, + "Please, be ensured that the L1Constants::size::kMaxNdetectors is not lower then the " + "L1DetectorID::kEND value, provided by your setup"); + std::copy(container.begin(), container.end(), fvDetectorNames.begin()); + } + /// Sets a magnetic field function, which will be applied for all the stations void SetFieldFunction(const L1FieldFunction_t& fieldFcn); /// FIXME: ... void SetGhostSuppression(int ghostSuppression); - /// Sets a name of the input configuration file. If the file is undefined, default settings will be used. If the file is - /// defined, the default settings will be overwritten with - /// \param filename Name of the input L1 parameters configuration - void SetInputConfigName(const std::string& filename) { fConfigInputName = filename; } - - /// - void SetMomentumCutOff(float momentumCutOff); - /// Sets a name of the output configuration file. The output file is created from the fields, saved in the resulted /// L1Parameters object /// \param filename Name of the output L1 parameters configuration @@ -230,8 +245,8 @@ public: /// @brief Sets pseudo-random numbers generator seed /// @param seed Seed value - /// @note The default seed is 0 - void SetRandomSeed(unsigned int seed) { fParameters.fRandomSeed = seed; } + /// @note The default seed is 1 + void SetRandomSeed(unsigned int seed); /// Sets target position /// \param x Position X component [cm] @@ -239,8 +254,6 @@ public: /// \param z Position Z component [cm] void SetTargetPosition(double x, double y, double z); - /// - void SetTrackingLevel(int trackingLevel); /// Sets upper-bound cut on max number of doublets per one singlet void SetMaxDoubletsPerSinglet(unsigned int value) { fParameters.fMaxDoubletsPerSinglet = value; } @@ -302,6 +315,9 @@ private: /// \return true If all L1BaseStationInfo objects were initialized properly. Similar effect can be achieved by void CheckStationsInfoInit(); + /// @brief Returns station layout into undefined condition + void ClearStationLayout(); + // ***************** // ** Data fields ** @@ -309,8 +325,9 @@ private: // * Basic fields * - InitController_t fInitController {}; ///< Initialization flags - L1DetectorIDSet_t fActiveDetectorIDs {}; ///< Set of tracking detectors, active during this analysis session + InitController_t fInitController {}; ///< Initialization flags + L1DetectorIDSet_t fActiveDetectorIDs {}; ///< Set of tracking detectors, active during the run + L1DetectorIDArr_t<std::string> fvDetectorNames {}; ///< Names of the detectors // * Target fields * diff --git a/reco/L1/L1Algo/L1Parameters.cxx b/reco/L1/L1Algo/L1Parameters.cxx index 9ad3136445dda2681dc08c90da62d0d9b0177275..2de0fd80eab4dff7c47dd135c538724bb454f3ed 100644 --- a/reco/L1/L1Algo/L1Parameters.cxx +++ b/reco/L1/L1Algo/L1Parameters.cxx @@ -206,85 +206,104 @@ void L1Parameters::Print(int /*verbosityLevel*/) const { LOG(info) << ToString() // std::string L1Parameters::ToString(int verbosity, int indentLevel) const { - // FIXME: SZh: Fill it with other parameters - using namespace L1Constants::clrs; // color the log text - std::stringstream aStream {}; - constexpr char indentChar = '\t'; - std::string indent(indentLevel, indentChar); - aStream << '\n'; - aStream << indent - << "----- L1 parameters list -------------------------------------------------------------------------\n"; - - aStream << indent << kCLb << "COMPILE TIME CONSTANTS:\n" << kCL; - aStream << indent << indentChar << "Bits to code one station: " << L1Constants::size::kStationBits << '\n'; - aStream << indent << indentChar << "Bits to code one thread: " << L1Constants::size::kThreadBits << '\n'; - aStream << indent << indentChar << "Bits to code one triplet: " << L1Constants::size::kTripletBits << '\n'; - aStream << indent << indentChar << "Max number of stations: " << L1Constants::size::kMaxNstations << '\n'; - aStream << indent << indentChar << "Max number of threads: " << L1Constants::size::kMaxNthreads << '\n'; - aStream << indent << indentChar << "Max number of triplets: " << L1Constants::size::kMaxNtriplets << '\n'; - aStream << indent << kCLb << "RUNTIME CONSTANTS:\n" << kCL; - aStream << indent << indentChar << "Random seed: " << fRandomSeed << '\n'; - aStream << indent << indentChar << "Max number of doublets per singlet: " << fMaxDoubletsPerSinglet << '\n'; - aStream << indent << indentChar << "Max number of triplets per doublet: " << fMaxTripletPerDoublets << '\n'; - aStream << indent << indentChar << "Tracking level: " << fTrackingLevel << '\n'; - aStream << indent << indentChar << "Ghost suppresion: " << fGhostSuppression << '\n'; - aStream << indent << indentChar << "Min tracks momentum: " << fMomentumCutOff << '\n'; - aStream << indent << indentChar << "Max number of triplets per doublet: " << fMaxTripletPerDoublets << '\n'; - aStream << indent << kCLb << "CA TRACK FINDER ITERATIONS:\n" << kCL; - for (int idx = 0; idx < static_cast<int>(fCAIterations.size()); ++idx) { - aStream << indent << indentChar << idx << ") " << fCAIterations[idx].ToString(indentLevel + 1) << '\n'; - } - aStream << indent << kCLb << "GEOMETRY:\n" << kCL; - aStream << indent << indentChar << kCLb << "TARGET:\n" << kCL; - aStream << indent << indentChar << indentChar << "Position:\n"; + using L1Constants::clrs::kCL; // color the log text + using L1Constants::clrs::kCLb; + using L1Constants::clrs::kGN; + using L1Constants::clrs::kRD; + using std::setfill; + using std::setw; + std::stringstream msg {}; + if (verbosity < 1) { return msg.str(); } + + constexpr char indentCh = '\t'; + std::string indent(indentLevel, indentCh); + + /// Sets red/green color dependently from flag + auto ClrFlg = [&](bool flag) { return (flag ? kGN : kRD); }; + + msg << " ----- CA parameters list -----\n"; + msg << indent << kCLb << "COMPILE TIME CONSTANTS:\n" << kCL; + msg << indent << indentCh << "Bits to code one station: " << L1Constants::size::kStationBits << '\n'; + msg << indent << indentCh << "Bits to code one thread: " << L1Constants::size::kThreadBits << '\n'; + msg << indent << indentCh << "Bits to code one triplet: " << L1Constants::size::kTripletBits << '\n'; + msg << indent << indentCh << "Max number of detectors: " << L1Constants::size::kMaxNdetectors << '\n'; + msg << indent << indentCh << "Max number of stations: " << L1Constants::size::kMaxNstations << '\n'; + msg << indent << indentCh << "Max number of threads: " << L1Constants::size::kMaxNthreads << '\n'; + msg << indent << indentCh << "Max number of triplets: " << L1Constants::size::kMaxNtriplets << '\n'; + msg << indent << kCLb << "RUNTIME CONSTANTS:\n" << kCL; + msg << indent << indentCh << "Random seed: " << fRandomSeed << '\n'; + msg << indent << indentCh << "Max number of doublets per singlet: " << fMaxDoubletsPerSinglet << '\n'; + msg << indent << indentCh << "Max number of triplets per doublet: " << fMaxTripletPerDoublets << '\n'; + msg << indent << indentCh << "Ghost suppresion: " << fGhostSuppression << '\n'; + msg << indent << kCLb << "CA TRACK FINDER ITERATIONS:\n" << kCL; + msg << L1CAIteration::ToTableFromVector(fCAIterations); + msg << indent << kCLb << "GEOMETRY:\n" << kCL; + msg << indent << indentCh << kCLb << "TARGET:\n" << kCL; + msg << indent << indentCh << indentCh << "Position:\n"; for (int dim = 0; dim < 3 /*nDimensions*/; ++dim) { - aStream << indent << indentChar << indentChar << indentChar << char(120 + dim) << " = " << fTargetPos[dim][0] - << " cm\n"; + msg << indent << indentCh << indentCh << indentCh << char(120 + dim) << " = " << fTargetPos[dim][0] << " cm\n"; } - aStream << indent << indentChar << kCLb << "NUMBER OF STATIONS:\n" << kCL; - aStream << indent << indentChar << indentChar << "Number of stations (Geometry): "; + msg << indent << indentCh << kCLb << "NUMBER OF STATIONS:\n" << kCL; + msg << indent << indentCh << indentCh << "Number of stations (Geometry): "; for (int iDet = 0; iDet < L1Constants::size::kMaxNdetectors; ++iDet) { - aStream << std::setw(2) << std::setfill(' ') << this->GetNstationsGeometry(static_cast<L1DetectorID>(iDet)) << ' '; + msg << setw(2) << setfill(' ') << this->GetNstationsGeometry(static_cast<L1DetectorID>(iDet)) << ' '; } - aStream << " | total = " << std::setw(2) << std::setfill(' ') << this->GetNstationsGeometry(); - aStream << '\n'; - aStream << indent << indentChar << indentChar << "Number of stations (Active): "; + msg << " | total = " << setw(2) << setfill(' ') << this->GetNstationsGeometry(); + msg << '\n'; + msg << indent << indentCh << indentCh << "Number of stations (Active): "; for (int iDet = 0; iDet < L1Constants::size::kMaxNdetectors; ++iDet) { - aStream << std::setw(2) << std::setfill(' ') << this->GetNstationsActive(static_cast<L1DetectorID>(iDet)) << ' '; + msg << setw(2) << setfill(' ') << this->GetNstationsActive(static_cast<L1DetectorID>(iDet)) << ' '; } - aStream << " | total = " << std::setw(2) << std::setfill(' ') << this->GetNstationsActive(); - aStream << '\n'; - aStream << indent << indentChar << indentChar << "Active station indexes: "; - for (int idx = 0; idx < fNstationsActiveTotal; ++idx) { - aStream << std::setw(3) << std::setfill(' ') << fvGeoToActiveMap[idx] << ' '; + msg << " | total = " << setw(2) << setfill(' ') << this->GetNstationsActive(); + msg << '\n' << indent << indentCh << indentCh << kCL << "Geometry station indices: "; + for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) { + bool isActive = fvGeoToActiveMap[iStGeo] != -1; + msg << ClrFlg(isActive) << setw(3) << setfill(' ') << iStGeo << ' '; } - aStream << '\n'; - - aStream << indent << indentChar << kCLb << "STATIONS:\n" << kCL; - for (int idx = 0; idx < fNstationsActiveTotal; ++idx) { - aStream << indent << indentChar << idx << ") " << fStations[idx].ToString(verbosity, indentLevel + 2) << '\n'; + msg << '\n' << indent << indentCh << indentCh << kCL << "Local station indices: "; + for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) { + bool isActive = fvGeoToActiveMap[iStGeo] != -1; + msg << ClrFlg(isActive) << setw(3) << setfill(' ') << static_cast<int>(fvGeoToLocalIdMap[iStGeo].second) << ' '; + } + msg << '\n' << indent << indentCh << indentCh << kCL << "Detector indices: "; + for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) { + bool isActive = fvGeoToActiveMap[iStGeo] != -1; + msg << ClrFlg(isActive) << setw(3) << setfill(' ') << static_cast<int>(fvGeoToLocalIdMap[iStGeo].first) << ' '; + } + msg << '\n' << indent << indentCh << indentCh << kCL << "Active station indices: "; + for (int iStGeo = 0; iStGeo < this->GetNstationsGeometry(); ++iStGeo) { + bool isActive = fvGeoToActiveMap[iStGeo] != -1; + msg << ClrFlg(isActive) << setw(3) << setfill(' ') << fvGeoToActiveMap[iStGeo] << ' '; + } + msg << kCL << '\n'; + + msg << indent << indentCh << kCLb << "STATIONS:\n" << kCL; + msg << indent << indentCh << setw(9) << setfill(' ') << "Active ID" << ' '; + msg << fStations[0].ToString(1, 0, true) << '\n'; + for (int iStAct = 0; iStAct < this->GetNstationsActive(); ++iStAct) { + msg << indent << indentCh << setw(9) << setfill(' ') << iStAct << ' '; + msg << fStations[iStAct].ToString(verbosity, 0) << '\n'; } - aStream << indent << kCLb << "DEV FLAGS:" << kCL << " (for debug only)\n"; - aStream << indent << indentChar << "Hits search area is ignored: " << fDevIsIgnoreHitSearchAreas << '\n'; - aStream << indent << indentChar << "Non-approx. field is used: " << fDevIsMatchDoubletsViaMc << '\n'; - aStream << indent << indentChar << "Doublets matching via MC: " << fDevIsMatchDoubletsViaMc << '\n'; - aStream << indent << indentChar << "Triplets matching via MC: " << fDevIsMatchTripletsViaMc << '\n'; - aStream << indent << indentChar << "Extend tracks with MC matching: " << fDevIsExtendTracksViaMc << '\n'; - aStream << indent << indentChar << "Overlap hits matching via MC: " << fDevIsSuppressOverlapHitsViaMc << '\n'; - aStream << indent << indentChar << "Use hit search windows: " << fDevIsParSearchWUsed << '\n'; + msg << indent << kCLb << "DEV FLAGS:" << kCL << " (for debug only)\n"; + msg << indent << indentCh << "Hits search area is ignored: " << fDevIsIgnoreHitSearchAreas << '\n'; + msg << indent << indentCh << "Non-approx. field is used: " << fDevIsMatchDoubletsViaMc << '\n'; + msg << indent << indentCh << "Doublets matching via MC: " << fDevIsMatchDoubletsViaMc << '\n'; + msg << indent << indentCh << "Triplets matching via MC: " << fDevIsMatchTripletsViaMc << '\n'; + msg << indent << indentCh << "Extend tracks with MC matching: " << fDevIsExtendTracksViaMc << '\n'; + msg << indent << indentCh << "Overlap hits matching via MC: " << fDevIsSuppressOverlapHitsViaMc << '\n'; + msg << indent << indentCh << "Use hit search windows: " << fDevIsParSearchWUsed << '\n'; if (fDevIsParSearchWUsed) { - aStream << indent << "SEARCH WINDOWS:\n"; + msg << indent << "SEARCH WINDOWS:\n"; for (int iSt = 1; iSt < fNstationsActiveTotal; ++iSt) { for (int iIter = 0; iIter < (int) fCAIterations.size(); ++iIter) { - aStream << indent << "- station: " << iSt << ", iteration: " << iIter << '\n'; - aStream << GetSearchWindow(iSt, iIter).ToString() << '\n'; + msg << indent << "- station: " << iSt << ", iteration: " << iIter << '\n'; + msg << GetSearchWindow(iSt, iIter).ToString() << '\n'; } } } - aStream << indent - << "--------------------------------------------------------------------------------------------------\n"; - return aStream.str(); + msg << '\n'; + return msg.str(); } diff --git a/reco/L1/L1Algo/L1Parameters.h b/reco/L1/L1Algo/L1Parameters.h index bc53ac71010d23a51002e341879bf1c318d26bd6..4b0a650f7f6861f7c7bacf26defb9445c4b8aa1e 100644 --- a/reco/L1/L1Algo/L1Parameters.h +++ b/reco/L1/L1Algo/L1Parameters.h @@ -11,9 +11,12 @@ #define L1Parameters_h 1 #include <boost/serialization/array.hpp> +#include <boost/serialization/utility.hpp> +#include <array> #include <numeric> #include <type_traits> +#include <utility> #include "L1CAIteration.h" #include "L1Constants.h" @@ -45,6 +48,8 @@ class alignas(L1Constants::misc::kAlignment) L1Parameters { friend class L1InitManager; using L1DetectorID_t = std::underlying_type_t<L1DetectorID>; + template<typename T> + using StationArray_t = std::array<T, L1Constants::size::kMaxNstations>; public: /// Default constructor @@ -71,14 +76,6 @@ public: /// String representation of the class contents std::string ToString(int verbosity = 0, int indentLevel = 0) const; - // TODO: SZh 15.05.2023: Setters should be removed from the class, since parameters - // can be initialized only via L1InitManager. - /// Sets upper-bound cut on max number of doublets per one singlet - void SetMaxDoubletsPerSinglet(unsigned int value) { fMaxDoubletsPerSinglet = value; } - - /// Sets upper-bound cut on max number of triplets per one doublet - void SetMaxTripletPerDoublets(unsigned int value) { fMaxTripletPerDoublets = value; } - /// Gets upper-bound cut on max number of doublets per one singlet unsigned int GetMaxDoubletsPerSinglet() const { return fMaxDoubletsPerSinglet; } @@ -100,8 +97,16 @@ public: return fvFirstGeoId[static_cast<int>(detectorID) + 1] - fvFirstGeoId[static_cast<int>(detectorID)]; } + /// @brief Gets local index of station + /// @param geoIndex geometry index of the tracking station + /// @return A pair (detectorID, local index of the tracking station) + [[gnu::always_inline]] std::pair<L1DetectorID, int> GetStationIndexLocal(int geoIndex) const + { + return fvGeoToLocalIdMap[geoIndex]; + } + /// @brief Calculates global index of station among geometry (accounts for inactive stations) - /// @param localIndex index of the detector subsystem module/station/layer provided by detector subsystem experts + /// @param localIndex local index of the tracking station (for a particular detector) /// @param detectorID ID of the detector subsystem [[gnu::always_inline]] int GetStationIndexGeometry(int localIndex, L1DetectorID detectorID) const { @@ -109,7 +114,7 @@ public: } /// @brief Calculates global index of station used by track finder - /// @param localIndex index of the detector subsystem module/station/layer provided by detector subsystem experts + /// @param localIndex local index of the tracking station (for a particular detector) /// @param detectorID ID of the detector subsystem [[gnu::always_inline]] int GetStationIndexActive(int localIndex, L1DetectorID detectorID) const { @@ -187,12 +192,6 @@ public: /// Gets ghost suppression flag int GetGhostSuppression() const { return fGhostSuppression; } - /// Gets tracking level - int GetTrackingLevel() const { return fTrackingLevel; } - - /// Gets momentum cutoff - float GetMomentumCutOff() const { return fMomentumCutOff; } - /// Class invariant checker void CheckConsistency() const; @@ -251,9 +250,12 @@ private: /// @brief Map of (local, det) to geo indices /// /// @note Usage: - /// iStGeo = fvGeoToLocalIdMap[fvFirstGeoId[iDet] + iStLocal]; + /// iStGeo = fvLocaToGeoIdMap[fvFirstGeoId[iDet] + iStLocal]; /// geo index. - alignas(L1Constants::misc::kAlignment) std::array<int, L1Constants::size::kMaxNstations> fvLocalToGeoIdMap {}; + alignas(L1Constants::misc::kAlignment) StationArray_t<int> fvLocalToGeoIdMap {}; + + /// @brief Map of geo to (local, det) indices + alignas(L1Constants::misc::kAlignment) StationArray_t<std::pair<L1DetectorID, int>> fvGeoToLocalIdMap {}; /// @brief Map of geo to active indices /// @@ -262,10 +264,11 @@ private: /// @example Let stations 1 and 4 be inactive. Then: /// geometry index: 0 1 2 3 4 5 6 7 8 9 0 0 0 0 /// active index: 0 -1 1 2 -1 3 4 5 6 7 0 0 0 0 - alignas(L1Constants::misc::kAlignment) std::array<int, L1Constants::size::kMaxNstations> fvGeoToActiveMap {}; + alignas(L1Constants::misc::kAlignment) StationArray_t<int> fvGeoToActiveMap {}; /// @brief Map of active to geo indices - alignas(L1Constants::misc::kAlignment) std::array<int, L1Constants::size::kMaxNstations> fvActiveToGeoMap {}; + alignas(L1Constants::misc::kAlignment) StationArray_t<int> fvActiveToGeoMap {}; + alignas(L1Constants::misc::kAlignment) int fNstationsActiveTotal = -1; ///< total number of active tracking stations @@ -278,11 +281,9 @@ private: std::array<L1SearchWindow, L1Constants::size::kMaxNstations* L1Constants::size::kMaxNtrackGroups> fSearchWindows = {}; - int fTrackingLevel = 0; ///< tracking level int fGhostSuppression = 0; ///< flag: if true, ghost tracks are suppressed - float fMomentumCutOff = 0; ///< minimum momentum of tracks int fRandomSeed = 1; ///< random seed - + float fDefaultMass = L1Constants::phys::kMuonMass; // *************************** // ** Flags for development ** @@ -317,14 +318,16 @@ private: ar& fvFirstGeoId; ar& fvLocalToGeoIdMap; + ar& fvGeoToLocalIdMap; ar& fvGeoToActiveMap; + ar& fvActiveToGeoMap; ar& fNstationsActiveTotal; + ar& fSearchWindows; - ar& fTrackingLevel; ar& fGhostSuppression; - ar& fMomentumCutOff; ar& fRandomSeed; + ar& fDefaultMass; ar& fDevIsIgnoreHitSearchAreas; ar& fDevIsUseOfOriginalField; diff --git a/reco/L1/L1Algo/L1Station.cxx b/reco/L1/L1Algo/L1Station.cxx index c464689766c64d973128f680bbef5b50d10ab231..69febba3b58ebe997158fdfcf723d47028806bff 100644 --- a/reco/L1/L1Algo/L1Station.cxx +++ b/reco/L1/L1Algo/L1Station.cxx @@ -68,32 +68,39 @@ void L1Station::CheckConsistency() const fieldSlice.CheckConsistency(); } -// TODO: Improve log style (S.Zh.) //------------------------------------------------------------------------------------------------------------------------------------ // -void L1Station::Print(int verbosity) const { LOG(info) << ToString(verbosity); } - -//------------------------------------------------------------------------------------------------------------------------------------ -// -std::string L1Station::ToString(int verbosityLevel, int indentLevel) const +std::string L1Station::ToString(int verbosityLevel, int indentLevel, bool isHeader) const { - std::stringstream aStream {}; + std::stringstream msg {}; constexpr char indentChar = '\t'; + constexpr char columnSize = 15; std::string indent(indentLevel, indentChar); - if (verbosityLevel == 0) { aStream << "station type = " << type << ", z = " << fZ[0] << " cm"; } + if (verbosityLevel == 0) { msg << "station type = " << type << ", z = " << fZ[0] << " cm"; } else { - aStream << '\n'; - aStream << indent << "z pos [cm]: " << std::setw(12) << std::setfill(' ') << fZ[0] << '\n'; - aStream << indent << "X_max [cm]: " << std::setw(12) << std::setfill(' ') << Xmax[0] << '\n'; - aStream << indent << "Y_max [cm]: " << std::setw(12) << std::setfill(' ') << Ymax[0] << '\n'; - aStream << indent << "Station type: " << std::setw(12) << std::setfill(' ') << type << '\n'; - aStream << indent << "Is time used: " << std::setw(12) << std::setfill(' ') << timeInfo << '\n'; - aStream << indent << "Is in field: " << std::setw(12) << std::setfill(' ') << fieldStatus << '\n'; - + if (isHeader) { + verbosityLevel = 0; + msg << indent; + msg << std::setw(columnSize) << std::setfill(' ') << "type" << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << "time status" << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << "field status" << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << "z [cm]" << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << "Ymax [cm]" << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << "Xmax [cm]"; + } + else { + msg << indent; + msg << std::setw(columnSize) << std::setfill(' ') << this->GetType() << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << this->GetTimeStatus() << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << this->GetFieldStatus() << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << this->GetZScal() << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << this->GetXmaxScal() << ' '; + msg << std::setw(columnSize) << std::setfill(' ') << this->GetYmaxScal(); + } if (verbosityLevel > 3) { - aStream << indent << "Field approcimation coefficients:\n"; - aStream << fieldSlice.ToString(indentLevel + 1) << '\n'; + msg << indent << "Field approcimation coefficients:\n"; + msg << fieldSlice.ToString(indentLevel + 1) << '\n'; } } - return aStream.str(); + return msg.str(); } diff --git a/reco/L1/L1Algo/L1Station.h b/reco/L1/L1Algo/L1Station.h index 77f1cb1aa633a535ecef4117ff1ab8f74722a5e0..61a13ad21c0fd182577d0699cd5b42f5f0a4d1dd 100644 --- a/reco/L1/L1Algo/L1Station.h +++ b/reco/L1/L1Algo/L1Station.h @@ -33,7 +33,7 @@ public: L1FieldSlice fieldSlice {}; - /// Serialization function + // Serialization block friend class boost::serialization::access; template<class Archive> void serialize(Archive& ar, const unsigned int) @@ -49,20 +49,42 @@ public: ar& fieldSlice; } + /// @brief Verifies class invariant consistency + /// @note Object is considered undefined in the creation time, so this function should be called after the object + /// initialization + void CheckConsistency() const; - /// Prints object fields - /// \param verbosity Verbosity level of the output - void Print(int verbosity = 0) const; + /// @brief Gets type of the station + int GetType() const { return type; } - /// String representation of class contents - /// \param verbosityLevel Verbosity level of the output - /// \param indentLevel Number of indent characters in the output - std::string ToString(int verbosityLevel = 0, int indentLevel = 0) const; + /// @brief Gets time-measurement flag + int GetTimeStatus() const { return timeInfo; } - /// Verifies class invariant consistency - /// \note Object is considered undefined in the creation time, so this function should be called after the object - /// initialization - void CheckConsistency() const; + /// @brief Gets field status flag + int GetFieldStatus() const { return fieldStatus; } + + /// @brief Gets simdized z-position of the station + fvec GetZSimd() const { return fZ; } + + /// @brief Gets scalar z-position of the station + fscal GetZScal() const { return fZ[0]; } + + /// @brief Gets simdized limit of the station size in x-axis direction + fvec GetXmaxSimd() const { return Xmax; } + + /// @brief Gets scalar limit of the station size in x-axis direction + fscal GetXmaxScal() const { return Xmax[0]; } + + /// @brief Gets simdized limit of the station size in y-axis direction + fvec GetYmaxSimd() const { return Ymax; } + + /// @brief Gets scalar limit of the station size in y-axis direction + fscal GetYmaxScal() const { return Ymax[0]; } + + /// @brief String representation of class contents + /// @param verbosityLevel Verbosity level of the output + /// @param indentLevel Number of indent characters in the output + std::string ToString(int verbosityLevel = 0, int indentLevel = 0, bool isHeader = false) const; } _fvecalignment; diff --git a/reco/L1/L1Algo/utils/CaUvConverter.cxx b/reco/L1/L1Algo/utils/CaUvConverter.cxx index 6767a2b2556bd0e79fae25d3f6be0028d4bf2c28..dfae0670868cbf868adff3bbb1bae9d8d26d1203 100644 --- a/reco/L1/L1Algo/utils/CaUvConverter.cxx +++ b/reco/L1/L1Algo/utils/CaUvConverter.cxx @@ -35,7 +35,6 @@ void CaUvConverter::SetFromUV(double phiU, double phiV) fsinY = fcosU / det; } - //---------------------------------------------------------------------------------------------------------------------- // void CaUvConverter::SetFromXYCovMatrix(double phiU, double dx2, double dxy, double dy2) diff --git a/reco/L1/catools/CaToolsWindowFinder.cxx b/reco/L1/catools/CaToolsWindowFinder.cxx index a46a424349644c7f438ef353453de6b98c699b79..501bc325746b4f67b02d04ec72f635dacbb84d4c 100644 --- a/reco/L1/catools/CaToolsWindowFinder.cxx +++ b/reco/L1/catools/CaToolsWindowFinder.cxx @@ -267,19 +267,10 @@ void WindowFinder::Process(Option_t* /*opt*/) void WindowFinder::ReadTrackingIterationsFromYAML(const char* filename) { L1ConfigRW reader(/*pInitManager = */ nullptr, 0); - YAML::Node config; - try { - config = YAML::LoadFile(filename); - } - catch (const YAML::BadFile& exc) { - throw std::runtime_error("file does not exist"); - } - catch (const YAML::ParserException& exc) { - throw std::runtime_error("file is formatted improperly"); - } + reader.SetMainConfigPath(filename); // Get iterations - fvCaIters = reader.ReadCAIterations(config["l1"]["algorithm"]["iterations"]); + fvCaIters = reader.ReadCAIterationVector(); // Print iterations: for (const auto& iter : fvCaIters) { diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx index f052cbae76909255aa641c6a09fc78ec6b494eee..d1d3b944fe1764d83383ed941090dcc1059b592b 100644 --- a/reco/L1/qa/CbmCaOutputQa.cxx +++ b/reco/L1/qa/CbmCaOutputQa.cxx @@ -633,7 +633,7 @@ void OutputQa::ReadParameters(const char* filename) manager.ReadParametersObject(filename); manager.SendParameters(*fpParameters); - LOG(info) << fpParameters->ToString(5); + LOG(info) << fpParameters->ToString(1); } // ---------------------------------------------------------------------------------------------------------------------