15#include <boost/algorithm/string.hpp>
20#include <unordered_map>
22#include <yaml-cpp/yaml.h>
38 auto node = YAML::Node(YAML::NodeType::Undefined);
46 std::stringstream msg;
47 msg <<
"requested node was not found ";
52 throw std::runtime_error(msg.str());
61 std::vector<std::string> res;
62 res.reserve(node.size());
64 for (
const auto& item : node) {
65 res.push_back(item.first.as<std::string>());
68 catch (
const YAML::InvalidNode& exc) {
70 <<
"L1 config: attempt to call ConfigReader::GetNodeKeys for node, keys of which could not be represented "
71 <<
"with strings. An empty vector will be returned";
72 std::vector<std::string>().swap(res);
84 LOG(info) <<
"- disabling inactive tracking stations";
88 if (std::any_of(inactiveMap.begin(), inactiveMap.end(), [](
const auto& s) { return (s.size() != 0); })) {
90 int iDet =
static_cast<int>(station.GetDetectorID());
91 int iStLoc = station.GetStationID();
92 if (inactiveMap[iDet].find(iStLoc) != inactiveMap[iDet].end()) {
93 station.SetTrackingStatus(
false);
104 LOG(info) <<
"- reading track finder iterations";
107 assert(iters.size());
110 std::for_each(iters.begin(), iters.end(), [&](
auto& iter) { fpInitManager->PushBackCAIteration(iter); });
117 LOG(info) <<
"- reading miscellaneous parameters";
121 GetNode([](YAML::Node n) {
return n[
"core"][
"common"][
"random_seed"]; }).as<
unsigned int>());
123 GetNode([](YAML::Node n) {
return n[
"core"][
"track_finder"][
"is_ghost_suppression"]; }).as<
bool>());
125 GetNode([](YAML::Node n) {
return n[
"core"][
"track_finder"][
"max_doublets_per_singlet"]; }).as<
unsigned int>());
127 GetNode([](YAML::Node n) {
return n[
"core"][
"track_finder"][
"max_triplets_per_doublet"]; }).as<
unsigned int>());
132 LOG(info) <<
"- reading developement parameters";
136 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"ignore_hit_search_areas"]; }).as<
bool>());
138 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"use_of_original_field"]; }).as<
bool>());
140 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"match_doublets_via_mc"]; }).as<
bool>());
142 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"match_triplets_via_mc"]; }).as<
bool>());
144 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"extend_tracks_via_mc"]; }).as<
bool>());
146 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"suppress_overlap_hits_via_mc"]; }).as<
bool>());
153 std::vector<Iteration> res;
156 std::unordered_map<std::string, Iteration> mPossibleIterations;
160 for (
const auto& iterNode : currentNode) {
161 std::string thisIterName = iterNode[
"name"].as<std::string>(
"");
162 std::string baseIterName = iterNode[
"base_iteration"].as<std::string>(
"");
164 if (baseIterName.size()) {
165 if (mPossibleIterations.find(baseIterName) == mPossibleIterations.end()) {
166 std::stringstream msg;
167 msg <<
"A CA iteration \"" << thisIterName <<
"\" requires a base iteration with name \"" << baseIterName
168 <<
"\", which was not registered yet. Please, place an entry with the requested base iteration above "
169 <<
"in the possible_iterations node";
170 throw std::runtime_error(std::move(msg.str()));
172 mPossibleIterations[thisIterName] =
ReadSingleCAIteration(iterNode, mPossibleIterations.at(baseIterName));
184 LOG(info) <<
"- Reading user iterations ";
187 auto currentNode =
fUserConfigNode[
"core"][
"track_finder"][
"iterations"];
189 for (
const auto& iterNode : currentNode) {
190 std::string thisIterName = iterNode[
"name"].as<std::string>(
"");
191 std::string baseIterName = iterNode[
"base_iteration"].as<std::string>(
"");
193 LOG(info) <<
"- Reading user iteration " << thisIterName <<
"(" << baseIterName <<
")";
195 if (mPossibleIterations.find(thisIterName) != mPossibleIterations.end()) {
198 LOG(info) <<
"- Select A";
202 else if (mPossibleIterations.find(baseIterName) != mPossibleIterations.end()) {
205 LOG(info) <<
"- Select B";
211 auto itFound = std::find_if(res.begin(), res.end(), [&](
auto& i) { return i.GetName() == baseIterName; });
212 if (itFound != res.end()) {
214 LOG(info) <<
"- Select C";
220 LOG(info) <<
"- Select D";
229 if (res.size() == 0) {
230 auto currentNode =
fMainConfigNode[
"core"][
"track_finder"][
"iteration_sequence"];
232 assert(currentNode.size());
233 for (
const auto& iterNode : currentNode) {
234 std::string thisIterName = iterNode.as<std::string>();
235 if (mPossibleIterations.find(thisIterName) == mPossibleIterations.end()) {
236 std::stringstream msg;
237 msg <<
"Unknow iteration in the iteration sequence, defined in main config file: " << thisIterName;
238 throw std::runtime_error(std::move(msg.str()));
240 res.push_back(mPossibleIterations.at(thisIterName));
252 std::string sNodePath =
"ca/core/common/inactive_stations";
253 auto node = this->
GetNode([](YAML::Node n) {
return n[
"core"][
"common"][
"inactive_stations"]; });
258 if (node && node.size()) {
259 std::unordered_map<std::string, int> mDetNameToID;
262 if (!detName.size()) {
265 mDetNameToID[detName] = iDet;
267 for (
const auto& item : node) {
268 std::string stName = item.as<std::string>();
269 if (!stName.size()) {
274 if (std::any_of(stName.begin(), stName.end(), [](
auto c) { return c ==
' ' || c ==
'\t' || c ==
'\n'; })) {
275 std::stringstream msg;
276 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName
277 <<
"\" contains illegal characters";
278 throw std::runtime_error(msg.str());
282 std::vector<std::string> vNames;
283 boost::algorithm::split(vNames, stName, boost::is_any_of(
":"));
284 if (vNames.size() > 2) {
285 std::stringstream msg;
286 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName
287 <<
"\" contains more then one colon character";
288 throw std::runtime_error(msg.str());
292 const auto& detName = boost::algorithm::to_lower_copy(vNames.front());
293 auto it = mDetNameToID.find(detName);
294 if (it == mDetNameToID.end()) {
295 std::stringstream msg;
296 msg <<
"ConfigReader: legal but undefined name of the detector \"" << detName <<
"\" (originally \"" << stName
297 <<
"\") was passed to the " << sNodePath <<
" config "
299 throw std::runtime_error(msg.str());
303 if (vNames.size() == 2) {
305 int iStLoc = std::stoi(vNames.back());
306 if (iStLoc < 0 || iStLoc >= nStations) {
307 throw std::runtime_error(
"illegal local station index");
309 vGeoIdToTrackingStatus[it->second].insert(iStLoc);
311 catch (
const std::exception&) {
312 std::stringstream msg;
313 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName
314 <<
"\" contains expression after the colon symbol, which cannot be translated "
315 <<
"to a local number of station";
316 throw std::runtime_error(msg.str());
320 for (
int iStLoc = 0; iStLoc < nStations; ++iStLoc) {
321 vGeoIdToTrackingStatus[it->second].insert(iStLoc);
326 std::stringstream msg;
327 msg <<
"\033[1;31m ConfigReader: the next tracking stations will be disabled from the configuration file:\n";
328 for (
int iDet = 0; iDet < static_cast<int>(mDetNameToID.size()); ++iDet) {
331 for (
int iStLoc = 0; iStLoc < nStations; ++iStLoc) {
332 if (vGeoIdToTrackingStatus[iDet].find(iStLoc) != vGeoIdToTrackingStatus[iDet].end()) {
333 msg <<
"\t- " << detName << iStLoc <<
'\n';
338 LOG(warn) << msg.str();
341 return vGeoIdToTrackingStatus;
350 std::string sNodePath =
"ca/core/common/misalignment_tolerance";
352 YAML::Node node(YAML::NodeType::Undefined);
355 node = this->
GetNode([](YAML::Node n) {
return n[
"core"][
"common"][
"misalignment_tolerance"]; });
357 catch (
const std::exception&) {
361 std::stringstream msg;
362 msg <<
"Ca ConfigReader: misalignment_tolerance node was not found\n ";
372 LOG(info) << msg.str();
373 LOG(info) <<
"Ca ConfigReader: run with zero misalignment tolerance";
378 std::unordered_map<std::string, int> mDetNameToID;
381 if (!detName.empty()) {
382 mDetNameToID[detName] = iDet;
386 for (
const auto& item : node) {
387 std::string stName = boost::algorithm::to_lower_copy(item.first.as<std::string>());
389 auto it = mDetNameToID.find(stName);
390 if (it == mDetNameToID.end()) {
391 std::stringstream msg;
392 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName <<
"\"";
393 throw std::runtime_error(msg.str());
395 int iDetSystem = it->second;
396 auto v = item.second.as<std::vector<double>>();
398 std::stringstream msg;
399 msg <<
"Illegal number of misalignbment tolerances in configuration branch \"" << sNodePath <<
"\": \"" << stName
400 <<
"\": " <<
v.size() <<
" values were passed, while 3 values are expected";
401 throw std::runtime_error(msg.str());
413 iter.SetName(node[
"name"].as<std::string>());
414 iter.SetTrackChi2Cut(node[
"track_chi2_cut"].as<float>(defaultIter.
GetTrackChi2Cut()));
415 iter.SetTripletChi2Cut(node[
"triplet_chi2_cut"].as<float>(defaultIter.
GetTripletChi2Cut()));
416 iter.SetTripletFinalChi2Cut(node[
"triplet_final_chi2_cut"].as<float>(defaultIter.
GetTripletFinalChi2Cut()));
417 iter.SetDoubletChi2Cut(node[
"doublet_chi2_cut"].as<float>(defaultIter.
GetDoubletChi2Cut()));
418 iter.SetPickGather(node[
"pick_gather"].as<float>(defaultIter.
GetPickGather()));
419 iter.SetTripletLinkChi2(node[
"triplet_link_chi2"].as<float>(defaultIter.
GetTripletLinkChi2()));
420 iter.SetMaxQp(node[
"max_qp"].as<float>(defaultIter.
GetMaxQp()));
421 iter.SetMaxSlopePV(node[
"max_slope_pv"].as<float>(defaultIter.
GetMaxSlopePV()));
422 iter.SetMaxSlope(node[
"max_slope"].as<float>(defaultIter.
GetMaxSlope()));
423 iter.SetMaxDZ(node[
"max_dz"].as<float>(defaultIter.
GetMaxDZ()));
424 iter.SetTargetPosSigmaXY(node[
"target_pos_sigma_x"].as<float>(defaultIter.
GetTargetPosSigmaX()),
426 iter.SetFirstStationIndex(node[
"first_station_index"].as<int>(defaultIter.
GetFirstStationIndex()));
427 iter.SetPrimaryFlag(node[
"is_primary"].as<bool>(defaultIter.
GetPrimaryFlag()));
428 iter.SetElectronFlag(node[
"is_electron"].as<bool>(defaultIter.
GetElectronFlag()));
430 iter.SetExtendTracksFlag(node[
"is_extend_tracks"].as<bool>(defaultIter.
GetExtendTracksFlag()));
431 iter.SetMaxStationGap(node[
"max_station_gap"].as<int>(defaultIter.
GetMaxStationGap()));
432 iter.SetMinNhits(node[
"min_n_hits"].as<int>(defaultIter.
GetMinNhits()));
433 iter.SetMinNhitsStation0(node[
"min_n_hits_station_0"].as<int>(defaultIter.
GetMinNhitsStation0()));
435 catch (
const YAML::InvalidNode& exc) {
437 const auto nodeKeysStr =
438 std::accumulate(nodeKeys.cbegin(), nodeKeys.cend(), std::string(
""),
439 [](std::string lhs, std::string rhs) { return std::move(lhs) +
"\n\t" + std::move(rhs); });
440 LOG(fatal) <<
"L1 config: attempt to access key which does not exist in the configuration file (message from "
441 <<
"YAML exception: " << exc.what() <<
"). Defined keys: " << nodeKeysStr;
455 LOG(info) <<
"ConfigReader: Registering main configuraiton file: \"\033[1;32m" << path <<
"\033[0m\"";
458 catch (
const std::exception& err) {
459 LOG(error) <<
"ERROR: " << err.what();
473 LOG(info) <<
"ConfigReader: Registering user configuraiton file: \"\033[1;32m" << path <<
"\033[0m\"";
476 catch (
const std::exception& err) {
477 LOG(error) <<
"ERROR: " << err.what();
Configuration parameter file reader for the CA tracking algorithm (header)
Compile-time constants definition for the CA tracking algorithm.
Input data management class for the CA tracking algorithm (header)
A reader for the CA parameters from the YAML configuration files.
YAML::Node fUserConfigNode
User configuration node.
std::vector< Iteration > ReadCAIterationVector()
Reads CA track finder iterations from YAML node.
int fVerbose
Verbosity level.
void SetUserConfigPath(const std::string &path)
Sets user config file.
Iteration ReadSingleCAIteration(const YAML::Node &node, const Iteration &defaultIter) const
Reads iteration from config file.
YAML::Node fMainConfigNode
Main configuration node.
bool fbGeometryLock
Geometry initialization locked.
void ReadMisalignmentTolerance()
Reads the misalignment tolerance.
YAML::Node GetNode(std::function< YAML::Node(YAML::Node)> fn) const
Accesses a node either from user config or from main config.
std::vector< std::set< int > > ReadInactiveStationMap()
Reads inactive tracking station map.
std::string fsUserConfigPath
Path to the user config file (optional)
InitManager * fpInitManager
Pointer to the L1InitManager instance.
void Read()
Reads configuration from files.
std::vector< std::string > GetNodeKeys(const YAML::Node &node) const
Gets parameters content of the node.
std::string fsMainConfigPath
Path to the main config file (mandatory)
ConfigReader(InitManager *pInitManager, int verbose=1)
Constructor.
void SetMainConfigPath(const std::string &path)
Sets main config file.
A CA Parameters object initialization class.
std::vector< StationInitializer > & GetStationInfo()
Gets a reference to the stations array.
void SetCAIterationsNumberCrosscheck(int nIterations)
Sets a number of CA track finder iterations to provide initialization cross-check.
int GetNstationsGeometry() const
Gets total number of stations, provided by setup geometry.
void ClearCAIterations()
Clears vector of CA track finder iterations.
void DevSetIsExtendTracksViaMc(bool value=true)
Flag to match triplets using Mc information.
void InitStationLayout()
Initializes station layout.
void SetMaxDoubletsPerSinglet(unsigned int value)
Sets upper-bound cut on max number of doublets per one singlet.
void SetGhostSuppression(int ghostSuppression)
Sets the flag to enable/disable the ghost suppression routine.
void DevSetIsMatchTripletsViaMc(bool value=true)
Flag to match triplets using Mc information.
void SetRandomSeed(unsigned int seed)
Sets pseudo-random numbers generator seed.
void DevSetUseOfOriginalField(bool value=true)
Force use of the original field (not approximated)
void DevSetIsMatchDoubletsViaMc(bool value=true)
Flag to match doublets using MC information.
void DevSetIgnoreHitSearchAreas(bool value=true)
Ignore hit search areas.
const std::string & GetDetectorName(EDetectorID detId) const
Gets name of the detector.
void SetMisalignmentTolerance(EDetectorID detectorId, double x, double y, double t)
Sets misalignment parameters in X direction.
void DevSetIsSuppressOverlapHitsViaMc(bool value=true)
Flag to match triplets using Mc information.
void SetMaxTripletPerDoublets(unsigned int value)
Sets upper-bound cut on max number of triplets per one doublet.
A set of parameters for the CA Track finder iteration.
int GetMinNhits() const
Gets min n hits.
float GetTripletChi2Cut() const
Gets triplet chi2 upper cut.
float GetMaxSlope() const
Gets max slope (tx\ty) in 3D hit position of a triplet.
float GetPickGather() const
Gets size of region [TODO: units??] to attach new hits to the created track.
float GetTrackChi2Cut() const
Gets track chi2 upper cut.
bool GetElectronFlag() const
flag check: electrons/positrons - true, heavy charged - false
float GetDoubletChi2Cut() const
Gets doublet chi2 upper cut.
float GetTripletFinalChi2Cut() const
Gets triplet chi2 upper cut.
int GetMaxStationGap() const
Gets flag: true - triplets are also built with skipping <= GetMaxStationGap stations.
int GetMinNhitsStation0() const
Gets min n hits for tracks that start on station 0.
float GetTargetPosSigmaX() const
Gets sigma target position in X direction [cm].
bool GetTrackFromTripletsFlag() const
float GetTripletLinkChi2() const
Gets min value of dp/dp_error, for which two tiplets are neighbours.
float GetMaxQp() const
Gets max considered q/p for tracks.
float GetMaxDZ() const
Gets correction for accounting overlaping and iff z.
bool GetPrimaryFlag() const
Checks flag: true - only primary tracks are searched, false - [all or only secondary?...
float GetTargetPosSigmaY() const
Gets sigma target position in Y direction [cm].
int GetFirstStationIndex() const
Gets station index of the first station used in tracking.
bool GetExtendTracksFlag() const
Sets flag: true - extends track candidates with unused hits.
float GetMaxSlopePV() const
Gets max slope (tx\ty) in primary vertex.
constexpr int MaxNdetectors
Max number of tracking detectors.
EDetectorID
Enumeration for the tracking detector subsystems in CBM-CA.