diff --git a/macro/L1/configs/CMakeLists.txt b/macro/L1/configs/CMakeLists.txt index d54f6841605146e2d8a4bfe4eca359b94958b1b4..c7026042c3ac6929f88d581aa4fe20d26ea2396d 100644 --- a/macro/L1/configs/CMakeLists.txt +++ b/macro/L1/configs/CMakeLists.txt @@ -1,3 +1,5 @@ Install(FILES config_ideal_hits_mcbm.yaml + ca_params_mcbm.yaml + ca_params_sts.yaml DESTINATION share/cbmroot/macro/L1/configs ) diff --git a/macro/L1/configs/README b/macro/L1/configs/README index 94b5e815e97b9a545ebf5bd2d0022293e6f6ca98..f0a984b4bc2410e74ef70306117a213e8d9d303a 100644 --- a/macro/L1/configs/README +++ b/macro/L1/configs/README @@ -6,3 +6,7 @@ DESCRIPTION: FILES: config_ideal_hits_mcbm.yaml Example of a configuration file for the cbm::ca::IdealHitProducer task for mCBM. + ca_params_mcbm.yaml + Mandatory configuration file to initialize tracking in mCBM. + ca_params_sts.yaml + Mandatory configuration file to initialize STS-tracking in CBM. diff --git a/macro/L1/configs/ca_params_mcbm.yaml b/macro/L1/configs/ca_params_mcbm.yaml new file mode 100644 index 0000000000000000000000000000000000000000..380b1a6af114726bfacfc6a005fa820e3455df92 --- /dev/null +++ b/macro/L1/configs/ca_params_mcbm.yaml @@ -0,0 +1,224 @@ +# @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 +# ... + +# 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 + + # 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: + # Tracking mode + # - 0: kSts + # - 1: kMcbm + # - 2: kGlobal + tracking_mode: 1 # ! CbmL1::fTrackingMode + + # 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: [] + + + + # 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. + max_qp: 2. # 1 / 0.5 [GeV/c]^-1 + max_slope_pv: 1.1 + max_slope: 2.748 + 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 + # + - 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_dz: 0. + target_pos_sigma_x: 1. + target_pos_sigma_y: 1. + max_slope_pv: 9.5 + if_primary: true + if_extend_track: false + + - name: "AllPrim" + base_iteration: "Default" + min_n_hits_station_0: 3 + max_qp: 10. # 1 / 0.1 + target_pos_sigma_x: 1. + target_pos_sigma_y: 1. + max_slope_pv: 9.5 + if_primary: true + if_extend_track: false + + - 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. + if_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 + target_pos_sigma_x: 10. + target_pos_sigma_y: 10. + max_slope_pv: 9.5 + if_primary: false + if_extend_track: 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_dz: 0. + target_pos_sigma_x: 5. + target_pos_sigma_y: 5. + if_primary: true + if_jump_one_station: true + + - name: "AllPrimJump" + base_iteration: "Default" + triplet_chi2_cut: 18.7560 + triplet_final_chi2_cut: 18.7560 + max_qp: 3.33333 # 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 + + - name: "AllSecJump" + base_iteration: "Default" + triplet_chi2_cut: 21.1075 + triplet_final_chi2_cut: 21.1075 + max_qp: 3.33333 # 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 + + - name: "AllPrimElectron" + base_iteration: "Default" + min_n_hits_station_0: 3 + max_qp: 10. # 1 / 0.1 + target_pos_sigma_x: 1. + target_pos_sigma_y: 1. + if_primary: true + if_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_slope_pv: 1.5 + target_pos_sigma_x: 10. + target_pos_sigma_y: 10. + if_primary: false + if_electron: true + +... + diff --git a/macro/L1/configs/ca_params_sts.yaml b/macro/L1/configs/ca_params_sts.yaml new file mode 100644 index 0000000000000000000000000000000000000000..c61cdd1c3e93527f2fd4da6670cdf7a4cbfc8ca6 --- /dev/null +++ b/macro/L1/configs/ca_params_sts.yaml @@ -0,0 +1,215 @@ +# @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 +# ... + +# 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 + + + # 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 + + # Store MC triplet tree .... not related to tracking execution -> only to user-interface + + # Tracking mode + # - 0: kSts + # - 1: kMcbm + # - 2: kGlobal + tracking_mode: 0 # ! CbmL1::fTrackingMode + + # 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: [] + + + # 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: + # 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 + - 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. + max_qp: 2. # 1 / 0.5 [GeV/c]^-1 + max_slope_pv: 1.1 + max_slope: 2.748 + 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 + + - 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. + if_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. + if_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. + if_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: 1.5 + if_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. + if_primary: true + if_jump_one_station: 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. + if_primary: true + if_jump_one_station: 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. + if_primary: true + if_jump_one_station: true + + - 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. + if_primary: true + if_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. + if_primary: false + if_electron: true + + +... + diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index add7f7e4dc0f3be3d389d3d4dbb0b80e31c64e33..07ad18c96fb40b3af0c7b203e44a1e02f2a6cae7 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -147,15 +147,6 @@ InitStatus CbmL1::ReInit() return Init(); } -// --------------------------------------------------------------------------------------------------------------------- -// -void CbmL1::SetInputConfigName(const char* filename) -{ - LOG(info) << "Reading parameters from configuration file: " << filename; - LOG(warn) << "\033[1;31mParameters configuration for tracking is not finalized! To be used only for tests! \033[0m"; - fInitManager.SetInputConfigName(std::string(filename)); -} - // --------------------------------------------------------------------------------------------------------------------- // InitStatus CbmL1::Init() diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 81e48c78590cc3fc111c3f257b257e860875605d..1db41198f6b9f6059f4547048068ed67d5d4ec07 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -212,11 +212,13 @@ public: /// Only needed in debug mode to produce detailed picture of the material void SetMaterialBudgetParallelProjection() { fMatBudgetParallelProjection = true; } - /// \brief Sets a name for the input configuration file - /// If the file is undefined, default tracking parameters will be used. Otherwise, the default parameters will be - /// overridden with ones from the configuration file - /// \param filename Name of the input tracking configuration file - void SetInputConfigName(const char* filename); + /// @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); } /// \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/L1Algo/L1ConfigRW.cxx b/reco/L1/L1Algo/L1ConfigRW.cxx index 1f4fb02bf48813211b8a72d633610e87558ccbdd..22f179f05d87e757f435cd7e1d1d87bbefc44439 100644 --- a/reco/L1/L1Algo/L1ConfigRW.cxx +++ b/reco/L1/L1Algo/L1ConfigRW.cxx @@ -43,6 +43,68 @@ std::vector<std::string> L1ConfigRW::GetNodeKeys(const YAML::Node& node) const return res; } +// --------------------------------------------------------------------------------------------------------------------- +// +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 + fpInitManager->ClearCAIterations(); + fpInitManager->SetCAIterationsNumberCrosscheck(vActualIterationSequenceNames.size()); + for (const auto& iterName : vActualIterationSequenceNames) { + fpInitManager->PushBackCAIteration(fmPossibleIterations.at(iterName)); + } + + // +} + + +// --------------------------------------------------------------------------------------------------------------------- +// +void L1ConfigRW::ReadPossibleIterations(const YAML::Node& node) +{ + // 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. + + 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 an iteration from already defined one + if (fmPossibleIterations.find(baseIterName) == fmPossibleIterations.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"; + throw std::runtime_error(std::move(msg.str())); + } + fmPossibleIterations[thisIterName] = ReadSingleCAIteration(iterNode, fmPossibleIterations.at(baseIterName)); + } + else { + fmPossibleIterations[thisIterName] = ReadSingleCAIteration(iterNode, L1CAIteration()); + } + } +} + // --------------------------------------------------------------------------------------------------------------------- // std::vector<L1CAIteration> L1ConfigRW::ReadCAIterations(const YAML::Node& node) const @@ -51,39 +113,7 @@ std::vector<L1CAIteration> L1ConfigRW::ReadCAIterations(const YAML::Node& node) if (node) { // Loop over input sub-nodes. Each sub-node corresponds to one L1CAIteration object for (const auto& input : node) { - try { - auto caIter = L1CAIteration(input["name"].as<std::string>()); - caIter.SetTrackChi2Cut(input["track_chi2_cut"].as<float>(caIter.GetTrackChi2Cut())); - caIter.SetTripletChi2Cut(input["triplet_chi2_cut"].as<float>(caIter.GetTripletChi2Cut())); - caIter.SetTripletFinalChi2Cut(input["triplet_final_chi2_cut"].as<float>(caIter.GetTripletFinalChi2Cut())); - caIter.SetDoubletChi2Cut(input["doublet_chi2_cut"].as<float>(caIter.GetDoubletChi2Cut())); - caIter.SetPickGather(input["pick_gather"].as<float>(caIter.GetPickGather())); - caIter.SetTripletLinkChi2(input["triplet_link_chi2"].as<float>(caIter.GetTripletLinkChi2())); - caIter.SetMaxQp(input["max_qp"].as<float>(caIter.GetMaxQp())); - caIter.SetMaxSlopePV(input["max_slope_pv"].as<float>(caIter.GetMaxSlopePV())); - caIter.SetMaxSlope(input["max_slope"].as<float>(caIter.GetMaxSlope())); - caIter.SetMaxDZ(input["max_dz"].as<float>(caIter.GetMaxDZ())); - caIter.SetTargetPosSigmaXY(input["target_pos_sigma_x"].as<float>(caIter.GetTargetPosSigmaX()), - input["target_pos_sigma_y"].as<float>(caIter.GetTargetPosSigmaY())); - caIter.SetFirstStationIndex(input["first_station_index"].as<int>(caIter.GetFirstStationIndex())); - caIter.SetPrimaryFlag(input["is_primary"].as<bool>(caIter.GetPrimaryFlag())); - caIter.SetElectronFlag(input["is_electron"].as<bool>(caIter.GetElectronFlag())); - caIter.SetTrackFromTripletsFlag(input["is_track_from_triplets"].as<bool>(caIter.GetTrackFromTripletsFlag())); - caIter.SetExtendTracksFlag(input["if_extend_tracks"].as<bool>(caIter.GetExtendTracksFlag())); - caIter.SetJumpedFlag(input["is_jumped"].as<bool>(caIter.GetJumpedFlag())); - caIter.SetMinNhits(input["min_n_hits"].as<int>(caIter.GetMinNhits())); - caIter.SetMinNhitsStation0(input["min_n_hits_sta_0"].as<int>(caIter.GetMinNhitsStation0())); - if (fVerbose > 3) { LOG(info) << "L1 config:\n" << caIter.ToString(1); } - vIters.push_back(caIter); - } - catch (const YAML::InvalidNode& exc) { - const auto nodeKeys = this->GetNodeKeys(input); - const auto nodeKeysStr = - std::accumulate(nodeKeys.cbegin(), nodeKeys.cend(), std::string(""), - [](std::string lhs, std::string rhs) { return std::move(lhs) + "\n\t" + std::move(rhs); }); - LOG(fatal) << "L1 config: attempt to access key which does not exist in the configuration file (message from " - << "YAML exception: " << exc.what() << "). Defined keys: " << nodeKeysStr; - } + vIters.push_back(ReadSingleCAIteration(input, L1CAIteration())); } // Loop over input sub-nodes: end } return vIters; @@ -91,46 +121,42 @@ std::vector<L1CAIteration> L1ConfigRW::ReadCAIterations(const YAML::Node& node) // --------------------------------------------------------------------------------------------------------------------- // -void L1ConfigRW::ReadYaml(const std::string& filename) +L1CAIteration L1ConfigRW::ReadSingleCAIteration(const YAML::Node& node, const L1CAIteration& defaultIter) const { - // Load YAML node from the file - YAML::Node config; + auto iter = L1CAIteration(); 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"); - } - - // Tracking iterations - this->InitCAIterations(config["l1"]["algorithm"]["iterations"]); -} - -// --------------------------------------------------------------------------------------------------------------------- -// -void L1ConfigRW::InitCAIterations(const YAML::Node& node) -{ - assert(fpInitManager); // Class itself can be used without the init manager, but this function cannot - auto vIters = this->ReadCAIterations(node); - if (vIters.size()) { - if (fVerbose > -1) { - LOG(info) << "L1 config: Reading CA tracking iterations sequence. Default iterations will be ignored"; - } - fpInitManager->ClearCAIterations(); - fpInitManager->SetCAIterationsNumberCrosscheck(vIters.size()); - if (fVerbose > 2) { LOG(info) << "L1 config: " << fVerbose << " CA iterations were recorded"; } - if (fVerbose > 3) { LOG(info) << "L1 config: Recorded iterations:"; } - for (const auto& caIter : vIters) { - fpInitManager->PushBackCAIteration(caIter); - } + iter.SetName(node["name"].as<std::string>()); + iter.SetTrackChi2Cut(node["track_chi2_cut"].as<float>(defaultIter.GetTrackChi2Cut())); + iter.SetTripletChi2Cut(node["triplet_chi2_cut"].as<float>(defaultIter.GetTripletChi2Cut())); + iter.SetTripletFinalChi2Cut(node["triplet_final_chi2_cut"].as<float>(defaultIter.GetTripletFinalChi2Cut())); + iter.SetDoubletChi2Cut(node["doublet_chi2_cut"].as<float>(defaultIter.GetDoubletChi2Cut())); + iter.SetPickGather(node["pick_gather"].as<float>(defaultIter.GetPickGather())); + iter.SetTripletLinkChi2(node["triplet_link_chi2"].as<float>(defaultIter.GetTripletLinkChi2())); + iter.SetMaxQp(node["max_qp"].as<float>(defaultIter.GetMaxQp())); + iter.SetMaxSlopePV(node["max_slope_pv"].as<float>(defaultIter.GetMaxSlopePV())); + iter.SetMaxSlope(node["max_slope"].as<float>(defaultIter.GetMaxSlope())); + iter.SetMaxDZ(node["max_dz"].as<float>(defaultIter.GetMaxDZ())); + iter.SetTargetPosSigmaXY(node["target_pos_sigma_x"].as<float>(defaultIter.GetTargetPosSigmaX()), + node["target_pos_sigma_y"].as<float>(defaultIter.GetTargetPosSigmaY())); + iter.SetFirstStationIndex(node["first_station_index"].as<int>(defaultIter.GetFirstStationIndex())); + iter.SetPrimaryFlag(node["is_primary"].as<bool>(defaultIter.GetPrimaryFlag())); + iter.SetElectronFlag(node["is_electron"].as<bool>(defaultIter.GetElectronFlag())); + iter.SetTrackFromTripletsFlag(node["is_track_from_triplets"].as<bool>(defaultIter.GetTrackFromTripletsFlag())); + 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); } } - else { - LOG(warn) << "L1 config: CA tracking iterations sequence was not found in the parameters file, default will be " - << "used. To define iterations please use the following path in the YAML file: l1/algorithm/iterations"; + catch (const YAML::InvalidNode& exc) { + const auto nodeKeys = this->GetNodeKeys(node); + const auto nodeKeysStr = + std::accumulate(nodeKeys.cbegin(), nodeKeys.cend(), std::string(""), + [](std::string lhs, std::string rhs) { return std::move(lhs) + "\n\t" + std::move(rhs); }); + LOG(fatal) << "L1 config: attempt to access key which does not exist in the configuration file (message from " + << "YAML exception: " << exc.what() << "). Defined keys: " << nodeKeysStr; } + return iter; } // --------------------------------------------------------------------------------------------------------------------- diff --git a/reco/L1/L1Algo/L1ConfigRW.h b/reco/L1/L1Algo/L1ConfigRW.h index 0a1a16f40a45191d096d9d5d2c09c3cc2af17881..6685aea9146a7c650c3d1dbd92694c8aae0f480f 100644 --- a/reco/L1/L1Algo/L1ConfigRW.h +++ b/reco/L1/L1Algo/L1ConfigRW.h @@ -11,6 +11,7 @@ #define L1ConfigRW_h 1 #include <string> +#include <unordered_map> #include <vector> #include "L1CAIteration.h" @@ -31,9 +32,8 @@ public: /// Destructor ~L1ConfigRW() {} - /// Reads parameters from the file - /// \param filename Name of the configuration file - void ReadYaml(const std::string& filename); + /// @brief Reads configuration from files + void Read(); /// Writes parameters to the file /// \param filename Name of the configuration file @@ -44,10 +44,25 @@ public: /// \return A vector of iterations std::vector<L1CAIteration> ReadCAIterations(const YAML::Node& node) const; + /// @brief Sets base config file + /// @param path Path to the file + void SetBaseConfigPath(const std::string& path) { fsBaseConfigPath = path; } + + /// @brief Sets user config file + /// @param path Path to user config file + void SetUserConfigPath(const std::string& path) { fsUserConfigPath = path; } + + private: - /// Calls CA track finder iterations reader and initialize the iterations in the init manager - /// \param node YAML node containing the iterations - void InitCAIterations(const YAML::Node& node); + /// @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 iteration from config file + /// @param node YAML node containing an iteration + /// @param defaultIter Default iteration + /// @return An iteration object + L1CAIteration ReadSingleCAIteration(const YAML::Node& node, const L1CAIteration& defaultIter) const; /// Gets parameters content of the node /// \param node YAML node @@ -56,6 +71,11 @@ private: 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::unordered_map<std::string, L1CAIteration> fmPossibleIterations; ///< full list of possible CA iterations }; #endif // L1ConfigRW_h diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx index 2bd6fcda99233bdb4a3c8de1a834e974d93324ae..fc219754a6c96f1a3afabd80fccc61cdffffbee2 100644 --- a/reco/L1/L1Algo/L1InitManager.cxx +++ b/reco/L1/L1Algo/L1InitManager.cxx @@ -110,19 +110,14 @@ void L1InitManager::ClearCAIterations() // NOTE: this function should be called once in the SendParameters bool L1InitManager::FormParametersContainer() { - // Read configuration file - // NOTE: We consider parameters from the configuration file as ones with a higher priority, so all the defined - // variables there would be rewritten by the configuration - if (fConfigInputName != "") { - try { - fConfigRW.ReadYaml(fConfigInputName); - LOG(info) << "L1InitManager: parameters configuration file \"" << fConfigInputName << "\" was loaded"; - } - catch (const std::runtime_error& err) { - LOG(error) << "L1InitManager: parameters configuration file \"" << fConfigInputName << "\" was defined, " - << "but the loading failed. Reason: " << err.what(); - return false; - } + // Read configuration files + LOG(info) << "L1InitManager: reading parameter configuration ..."; + try { + fConfigRW.Read(); + } + catch (const std::runtime_error& err) { + LOG(error) << "L1InitManager: reading parameter configuration ... \033[1;31mfail\033[0m. Reason: " << err.what(); + return false; } if (!fParameters.fDevIsParSearchWUsed) { fInitController.SetFlag(EInitKey::kSearchWindows, true); } diff --git a/reco/L1/L1Algo/L1InitManager.h b/reco/L1/L1Algo/L1InitManager.h index e4ad499dcc3c4c67c1045a4f6ebf55903c4ec48d..eba788929d82cb2f1667fbc3a3d3b3b0cff42c8c 100644 --- a/reco/L1/L1Algo/L1InitManager.h +++ b/reco/L1/L1Algo/L1InitManager.h @@ -8,6 +8,15 @@ #ifndef L1InitManager_h #define L1InitManager_h 1 +#include <array> +#include <bitset> +#include <memory> //unique_ptr +#include <numeric> +#include <set> +#include <string> +#include <type_traits> +#include <unordered_map> + #include "L1BaseStationInfo.h" #include "L1CAIteration.h" #include "L1ConfigRW.h" @@ -18,14 +27,6 @@ #include "L1Utils.h" #include "L1Vector.h" -//#include <string> -#include <array> -#include <bitset> -#include <memory> //unique_ptr -#include <numeric> -#include <set> -#include <type_traits> - class L1ConfigRW; class L1Algo; @@ -136,6 +137,10 @@ public: /// \return Success flag bool FormParametersContainer(); + /// @brief Accessor to configuration module + /// @return Reference to configuration module + L1ConfigRW& GetConfigRW() { return fConfigRW; } + /// Gets ghost suppression flag int GetGhostSuppression() const { return fParameters.fGhostSuppression; }