15#include <boost/algorithm/string.hpp>
20#include <unordered_map>
22#include <yaml-cpp/yaml.h>
39 auto node = YAML::Node(YAML::NodeType::Undefined);
46 if (!node && !optional) {
47 std::stringstream msg;
48 msg <<
"requested node was not found ";
53 throw std::runtime_error(msg.str());
62 std::vector<std::string> res;
63 res.reserve(node.size());
65 for (
const auto& item : node) {
66 res.push_back(item.first.as<std::string>());
69 catch (
const YAML::InvalidNode& exc) {
71 <<
"L1 config: attempt to call ConfigReader::GetNodeKeys for node, keys of which could not be represented "
72 <<
"with strings. An empty vector will be returned";
73 std::vector<std::string>().swap(res);
85 LOG(info) <<
"- disabling inactive tracking stations";
89 if (std::any_of(inactiveMap.begin(), inactiveMap.end(), [](
const auto& s) { return (s.size() != 0); })) {
91 int iDet =
static_cast<int>(station.GetDetectorID());
92 int iStLoc = station.GetStationID();
93 if (inactiveMap[iDet].find(iStLoc) != inactiveMap[iDet].end()) {
94 station.SetTrackingStatus(
false);
105 LOG(info) <<
"- reading track finder iterations";
108 assert(iters.size());
111 std::for_each(iters.begin(), iters.end(), [&](
auto& iter) { fpInitManager->PushBackCAIteration(iter); });
118 LOG(info) <<
"- reading miscellaneous parameters";
122 GetNode([](YAML::Node n) {
return n[
"core"][
"common"][
"random_seed"]; }).as<
unsigned int>());
124 GetNode([](YAML::Node n) {
return n[
"core"][
"track_finder"][
"is_ghost_suppression"]; }).as<
bool>());
126 GetNode([](YAML::Node n) {
return n[
"core"][
"track_finder"][
"max_doublets_per_singlet"]; }).as<
unsigned int>());
128 GetNode([](YAML::Node n) {
return n[
"core"][
"track_finder"][
"max_triplets_per_doublet"]; }).as<
unsigned int>());
133 LOG(info) <<
"- reading developement parameters";
137 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"ignore_hit_search_areas"]; }).as<
bool>());
139 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"use_of_original_field"]; }).as<
bool>());
141 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"match_doublets_via_mc"]; }).as<
bool>());
143 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"match_triplets_via_mc"]; }).as<
bool>());
145 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"extend_tracks_via_mc"]; }).as<
bool>());
147 GetNode([](YAML::Node n) {
return n[
"core"][
"dev"][
"suppress_overlap_hits_via_mc"]; }).as<
bool>());
154 std::vector<Iteration> res;
157 std::unordered_map<std::string, Iteration> mPossibleIterations;
161 for (
const auto& iterNode : currentNode) {
162 std::string thisIterName = iterNode[
"name"].as<std::string>(
"");
163 std::string baseIterName = iterNode[
"base_iteration"].as<std::string>(
"");
165 if (baseIterName.size()) {
166 if (mPossibleIterations.find(baseIterName) == mPossibleIterations.end()) {
167 std::stringstream msg;
168 msg <<
"A CA iteration \"" << thisIterName <<
"\" requires a base iteration with name \"" << baseIterName
169 <<
"\", which was not registered yet. Please, place an entry with the requested base iteration above "
170 <<
"in the possible_iterations node";
171 throw std::runtime_error(std::move(msg.str()));
173 mPossibleIterations[thisIterName] =
ReadSingleCAIteration(iterNode, mPossibleIterations.at(baseIterName));
185 LOG(info) <<
"- Reading user iterations ";
188 auto currentNode =
fUserConfigNode[
"core"][
"track_finder"][
"iterations"];
190 for (
const auto& iterNode : currentNode) {
191 std::string thisIterName = iterNode[
"name"].as<std::string>(
"");
192 std::string baseIterName = iterNode[
"base_iteration"].as<std::string>(
"");
194 LOG(info) <<
"- Reading user iteration " << thisIterName <<
"(" << baseIterName <<
")";
196 if (mPossibleIterations.find(thisIterName) != mPossibleIterations.end()) {
199 LOG(info) <<
"- Select A";
203 else if (mPossibleIterations.find(baseIterName) != mPossibleIterations.end()) {
206 LOG(info) <<
"- Select B";
212 auto itFound = std::find_if(res.begin(), res.end(), [&](
auto& i) { return i.GetName() == baseIterName; });
213 if (itFound != res.end()) {
215 LOG(info) <<
"- Select C";
221 LOG(info) <<
"- Select D";
230 if (res.size() == 0) {
231 auto currentNode =
fMainConfigNode[
"core"][
"track_finder"][
"iteration_sequence"];
233 assert(currentNode.size());
234 for (
const auto& iterNode : currentNode) {
235 std::string thisIterName = iterNode.as<std::string>();
236 if (mPossibleIterations.find(thisIterName) == mPossibleIterations.end()) {
237 std::stringstream msg;
238 msg <<
"Unknow iteration in the iteration sequence, defined in main config file: " << thisIterName;
239 throw std::runtime_error(std::move(msg.str()));
241 res.push_back(mPossibleIterations.at(thisIterName));
253 std::string sNodePath =
"ca/core/common/inactive_stations";
254 auto node =
GetNode([](YAML::Node n) {
return n[
"core"][
"common"][
"inactive_stations"]; },
true);
256 return std::vector<std::set<int>>{};
262 if (node && node.size()) {
263 std::unordered_map<std::string, int> mDetNameToID;
266 if (!detName.size()) {
269 mDetNameToID[detName] = iDet;
271 for (
const auto& item : node) {
272 std::string stName = item.as<std::string>();
273 if (!stName.size()) {
278 if (std::any_of(stName.begin(), stName.end(), [](
auto c) { return c ==
' ' || c ==
'\t' || c ==
'\n'; })) {
279 std::stringstream msg;
280 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName
281 <<
"\" contains illegal characters";
282 throw std::runtime_error(msg.str());
286 std::vector<std::string> vNames;
287 boost::algorithm::split(vNames, stName, boost::is_any_of(
":"));
288 if (vNames.size() > 2) {
289 std::stringstream msg;
290 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName
291 <<
"\" contains more then one colon character";
292 throw std::runtime_error(msg.str());
296 const auto& detName = boost::algorithm::to_lower_copy(vNames.front());
297 auto it = mDetNameToID.find(detName);
298 if (it == mDetNameToID.end()) {
299 std::stringstream msg;
300 msg <<
"ConfigReader: legal but undefined name of the detector \"" << detName <<
"\" (originally \"" << stName
301 <<
"\") was passed to the " << sNodePath <<
" config "
303 throw std::runtime_error(msg.str());
307 if (vNames.size() == 2) {
309 int iStLoc = std::stoi(vNames.back());
310 if (iStLoc < 0 || iStLoc >= nStations) {
311 throw std::runtime_error(
"illegal local station index");
313 vGeoIdToTrackingStatus[it->second].insert(iStLoc);
315 catch (
const std::exception&) {
316 std::stringstream msg;
317 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName
318 <<
"\" contains expression after the colon symbol, which cannot be translated "
319 <<
"to a local number of station";
320 throw std::runtime_error(msg.str());
324 for (
int iStLoc = 0; iStLoc < nStations; ++iStLoc) {
325 vGeoIdToTrackingStatus[it->second].insert(iStLoc);
330 std::stringstream msg;
331 msg <<
"\033[1;31m ConfigReader: the next tracking stations will be disabled from the configuration file:\n";
332 for (
int iDet = 0; iDet < static_cast<int>(mDetNameToID.size()); ++iDet) {
335 for (
int iStLoc = 0; iStLoc < nStations; ++iStLoc) {
336 if (vGeoIdToTrackingStatus[iDet].find(iStLoc) != vGeoIdToTrackingStatus[iDet].end()) {
337 msg <<
"\t- " << detName << iStLoc <<
'\n';
342 LOG(warn) << msg.str();
345 return vGeoIdToTrackingStatus;
354 std::string sNodePath =
"ca/core/common/misalignment_tolerance";
356 YAML::Node node(YAML::NodeType::Undefined);
359 node = this->
GetNode([](YAML::Node n) {
return n[
"core"][
"common"][
"misalignment_tolerance"]; });
361 catch (
const std::exception&) {
365 std::stringstream msg;
366 msg <<
"Ca ConfigReader: misalignment_tolerance node was not found\n ";
376 LOG(info) << msg.str();
377 LOG(info) <<
"Ca ConfigReader: run with zero misalignment tolerance";
382 std::unordered_map<std::string, int> mDetNameToID;
385 if (!detName.empty()) {
386 mDetNameToID[detName] = iDet;
390 for (
const auto& item : node) {
391 std::string stName = boost::algorithm::to_lower_copy(item.first.as<std::string>());
393 auto it = mDetNameToID.find(stName);
394 if (it == mDetNameToID.end()) {
395 std::stringstream msg;
396 msg <<
"Illegal station name in the configuration branch \"" << sNodePath <<
"\": \"" << stName <<
"\"";
397 throw std::runtime_error(msg.str());
399 int iDetSystem = it->second;
400 auto v = item.second.as<std::vector<double>>();
402 std::stringstream msg;
403 msg <<
"Illegal number of misalignbment tolerances in configuration branch \"" << sNodePath <<
"\": \"" << stName
404 <<
"\": " <<
v.size() <<
" values were passed, while 3 values are expected";
405 throw std::runtime_error(msg.str());
417 iter.SetName(node[
"name"].as<std::string>());
418 iter.SetTrackChi2Cut(node[
"track_chi2_cut"].as<float>(defaultIter.
GetTrackChi2Cut()));
419 iter.SetTripletChi2Cut(node[
"triplet_chi2_cut"].as<float>(defaultIter.
GetTripletChi2Cut()));
420 iter.SetTripletFinalChi2Cut(node[
"triplet_final_chi2_cut"].as<float>(defaultIter.
GetTripletFinalChi2Cut()));
421 iter.SetDoubletChi2Cut(node[
"doublet_chi2_cut"].as<float>(defaultIter.
GetDoubletChi2Cut()));
422 iter.SetPickGather(node[
"pick_gather"].as<float>(defaultIter.
GetPickGather()));
423 iter.SetTripletLinkChi2(node[
"triplet_link_chi2"].as<float>(defaultIter.
GetTripletLinkChi2()));
424 iter.SetMaxQp(node[
"max_qp"].as<float>(defaultIter.
GetMaxQp()));
425 iter.SetMaxSlopePV(node[
"max_slope_pv"].as<float>(defaultIter.
GetMaxSlopePV()));
426 iter.SetMaxSlope(node[
"max_slope"].as<float>(defaultIter.
GetMaxSlope()));
427 iter.SetMaxDZ(node[
"max_dz"].as<float>(defaultIter.
GetMaxDZ()));
428 iter.SetTargetPosSigmaXY(node[
"target_pos_sigma_x"].as<float>(defaultIter.
GetTargetPosSigmaX()),
430 iter.SetFirstStationIndex(node[
"first_station_index"].as<int>(defaultIter.
GetFirstStationIndex()));
431 iter.SetPrimaryFlag(node[
"is_primary"].as<bool>(defaultIter.
GetPrimaryFlag()));
432 iter.SetElectronFlag(node[
"is_electron"].as<bool>(defaultIter.
GetElectronFlag()));
434 iter.SetExtendTracksFlag(node[
"is_extend_tracks"].as<bool>(defaultIter.
GetExtendTracksFlag()));
435 iter.SetMaxStationGap(node[
"max_station_gap"].as<int>(defaultIter.
GetMaxStationGap()));
436 iter.SetMinNhits(node[
"min_n_hits"].as<int>(defaultIter.
GetMinNhits()));
437 iter.SetMinNhitsStation0(node[
"min_n_hits_station_0"].as<int>(defaultIter.
GetMinNhitsStation0()));
439 catch (
const YAML::InvalidNode& exc) {
441 const auto nodeKeysStr =
442 std::accumulate(nodeKeys.cbegin(), nodeKeys.cend(), std::string(
""),
443 [](std::string lhs, std::string rhs) { return std::move(lhs) +
"\n\t" + std::move(rhs); });
444 LOG(fatal) <<
"L1 config: attempt to access key which does not exist in the configuration file (message from "
445 <<
"YAML exception: " << exc.what() <<
"). Defined keys: " << nodeKeysStr;
459 LOG(info) <<
"ConfigReader: Registering main configuraiton file: \"\033[1;32m" << path <<
"\033[0m\"";
462 catch (
const std::exception& err) {
463 LOG(error) <<
"ERROR: " << err.what();
477 LOG(info) <<
"ConfigReader: Registering user configuraiton file: \"\033[1;32m" << path <<
"\033[0m\"";
480 catch (
const std::exception& err) {
481 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, bool optional=false) 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.