9 #include "nlohmann/json.hpp" 18 #define ITCONF_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ 19 inline void to_json(nlohmann::json &nlohmann_json_j, const Type &nlohmann_json_t) { \ 20 NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \ 22 inline void from_json(const nlohmann::json &nlohmann_json_j, Type &nlohmann_json_t) { \ 23 NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) \ 25 inline void to_json(nlohmann::ordered_json &nlohmann_json_j, const Type &nlohmann_json_t) { \ 26 NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \ 28 inline void from_json(const nlohmann::ordered_json &nlohmann_json_j, Type &nlohmann_json_t) { \ 29 NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) \ 74 m_seed_partitioner_name,
75 m_pre_bkfit_filter_name,
76 m_post_bkfit_filter_name,
77 m_duplicate_cleaner_name,
78 m_default_track_scorer_name,
79 m_requires_seed_hit_sorting,
81 m_backward_drop_seed_hits,
82 m_backward_fit_min_hits,
112 std::map<std::string, clean_seeds_func> seed_cleaners;
113 std::map<std::string, partition_seeds_func> seed_partitioners;
114 std::map<std::string, filter_candidates_func> candidate_filters;
115 std::map<std::string, clean_duplicates_func> duplicate_cleaners;
116 std::map<std::string, track_score_func> track_scorers;
121 FuncCatalog &get_catalog() {
128 auto &fc = get_catalog(); \ 129 const std::lock_guard<std::mutex> lock(fc.catalog_mutex) 133 fc.seed_cleaners.insert({
name,
func});
137 fc.seed_partitioners.insert({
name,
func});
141 fc.candidate_filters.insert({
name,
func});
145 fc.duplicate_cleaners.insert({
name,
func});
149 fc.track_scorers.insert({
name,
func});
161 es +=
" '" +
name +
"' not found in function registry.";
162 throw std::runtime_error(es);
170 return resolve_func_name(fc.seed_cleaners,
name, __func__);
174 return resolve_func_name(fc.seed_partitioners,
name, __func__);
178 return resolve_func_name(fc.candidate_filters,
name, __func__);
182 return resolve_func_name(fc.duplicate_cleaners,
name, __func__);
186 return resolve_func_name(fc.track_scorers,
name, __func__);
206 dprintf(
" Set post_bkfit_filter for '%s' %s\n",
211 dprintf(
" Set duplicate_cleaner for '%s' %s\n",
241 s =
"ConfigJsonPatcher";
254 m_json = std::make_unique<nlohmann::json>();
258 template void ConfigJsonPatcher::load<IterationsInfo>(
const IterationsInfo &
o);
259 template void ConfigJsonPatcher::load<IterationConfig>(
const IterationConfig &
o);
271 auto &itc_arr = m_json->at(
"m_iterations");
272 for (
int i = 0;
i <
o.size(); ++
i) {
278 nlohmann::json::json_pointer jp(
path);
286 throw std::runtime_error(
"JSON stack empty on cd_up");
303 template <
typename T>
305 nlohmann::json::json_pointer jp(
path);
310 template void ConfigJsonPatcher::replace<double>(
const std::string &
path,
double val);
312 template <
typename T>
314 nlohmann::json::json_pointer jp(
path);
324 nlohmann::json::json_pointer jp(
path);
330 throw std::runtime_error(
exc_hdr(__func__) +
"null not expected");
332 if (
j.is_boolean() ||
j.is_number() ||
j.is_string()) {
333 throw std::runtime_error(
exc_hdr(__func__) +
"value not expected on this parsing level");
339 static const std::regex index_range_re(
"^\\[(\\d+)..(\\d+)\\]$", std::regex::optimize);
343 std::regex_search(
key,
m, index_range_re);
347 throw std::runtime_error(
exc_hdr(__func__) +
"array range encountered when current json is not an array");
348 int first = std::stoi(
m.str(1));
349 int last = std::stoi(
m.str(2));
354 if (
value.is_array()) {
355 for (
auto &el :
value)
362 }
else if (
value.is_array() ||
value.is_object()) {
368 }
else if (
value.is_number() ||
value.is_boolean() ||
value.is_string()) {
371 nlohmann::json::json_pointer jp(
s);
380 throw std::runtime_error(
exc_hdr(__func__) +
"unexpected value type");
383 }
else if (
j.is_array() &&
j.empty()) {
384 }
else if (
j.is_array()) {
397 static const std::regex index_re(
"^(?:\\[\\d+..\\d+\\]|\\d+(?:/.*)?)$", std::regex::optimize);
399 bool has_index =
false, has_plain =
false;
400 for (
int i = 0;
i < (
int)
j.size(); ++
i) {
404 throw std::runtime_error(
exc_hdr(__func__) +
"array elements expected to be objects");
406 for (nlohmann::json::const_iterator
it = el.begin();
it != el.end(); ++
it) {
407 if (std::regex_search(
it.key(), index_re)) {
410 throw std::runtime_error(
exc_hdr(__func__) +
"indexed array entry following plain one");
414 throw std::runtime_error(
exc_hdr(__func__) +
"plain array entry following indexed one");
419 for (
auto &element :
j) {
420 n_replaced +=
replace(element);
424 throw std::runtime_error(
exc_hdr(__func__) +
"plain array detected when current is not an array");
426 throw std::runtime_error(
exc_hdr(__func__) +
"plain array of different size than at current pos");
429 for (
int i = 0;
i < (
int)
j.size(); ++
i) {
438 throw std::runtime_error(
exc_hdr(__func__) +
"unexpected json type");
465 void open_ofstream(std::ofstream &ofs,
const std::string &
fname,
const char *
pfx =
nullptr) {
469 snprintf(
m, 2048,
"%s%sError opening %s for write: %m",
pfx ?
pfx :
"",
pfx ?
" " :
"",
fname.c_str());
470 throw std::runtime_error(
m);
475 void open_ifstream(std::ifstream &ifs,
const std::string &
fname,
const char *
pfx =
nullptr) {
479 snprintf(
m, 2048,
"%s%sError opening %s for read: %m",
pfx ?
pfx :
"",
pfx ?
" " :
"",
fname.c_str());
480 throw std::runtime_error(
m);
485 bool skipws_ifstream(std::ifstream &ifs) {
486 while (std::isspace(ifs.peek()))
493 const std::vector<std::string> &
fnames,
502 open_ifstream(ifs,
fname, __func__);
505 printf(
"%s begin reading from file %s.\n", __func__,
fname.c_str());
508 int n_read = 0, n_tot_replaced = 0;
509 while (skipws_ifstream(ifs)) {
515 std::cout <<
" Read JSON entity " << n_read <<
" -- applying patch:\n";
522 std::cout <<
" Replaced " << n_replaced <<
" entries.\n";
525 n_tot_replaced += n_replaced;
529 printf(
"%s read %d JSON entities from file %s, replaced %d parameters.\n",
538 rep.inc_counts(1, n_read, n_tot_replaced);
541 if (
rep.n_replacements > 0) {
555 open_ifstream(ifs,
fname, __func__);
558 printf(
"%s begin reading from file %s.\n", __func__,
fname.c_str());
561 if (!skipws_ifstream(ifs))
562 throw std::runtime_error(
"empty file");
566 int track_algo =
j[
"m_track_algorithm"];
569 for (
int i = 0;
i < its_info.
size(); ++
i) {
570 if (its_info[
i].m_track_algorithm == track_algo) {
576 throw std::runtime_error(
"matching IterationConfig not found");
579 std::cout <<
" Read JSON entity, Iteration index is " << iii <<
" -- cloning and applying JSON patch:\n";
593 printf(
"%s read 1 JSON entity from file %s, replaced %d parameters.\n", __func__,
fname.c_str(), n_replaced);
598 rep.inc_counts(1, 1, n_replaced);
600 if (
rep.n_replacements > 0) {
607 return std::unique_ptr<IterationConfig>(icp);
612 open_ifstream(ifs,
fname, __func__);
615 printf(
"%s begin reading from file %s.\n", __func__,
fname.c_str());
618 if (!skipws_ifstream(ifs))
619 throw std::runtime_error(
"empty file");
625 std::cout <<
" Read JSON entity, iteration index is " <<
j[
"m_iteration_index"] <<
", track algorithm is " 626 <<
j[
"m_track_algorithm"] <<
". Instantiating IterationConfig object and over-laying it with JSON.\n";
633 return std::unique_ptr<IterationConfig>(icp);
642 bool include_iter_info_preamble) {
643 bool has_pct_d = fname_fmt.find(
"%d") != std::string::npos;
644 bool has_pct_s = fname_fmt.find(
"%s") != std::string::npos;
646 assert((has_pct_d || has_pct_s) &&
"JSON save filename-format must include a %d or %s substring");
647 assert(!(has_pct_d && has_pct_s) &&
"JSON save filename-format must include only one of %d or %s substrings");
649 for (
int ii = 0;
ii < its_info.
size(); ++
ii) {
654 snprintf(
fname, 1024, fname_fmt.c_str(),
ii);
659 open_ofstream(ofs,
fname, __func__);
661 if (include_iter_info_preamble) {
662 ofs <<
"{ \"m_iterations/" <<
ii <<
"\": ";
665 nlohmann::ordered_json
j;
671 if (include_iter_info_preamble) {
681 nlohmann::ordered_json
j = its_info;
697 std::cout <<
"Layer 43, m_select_max_dphi = " <<
j[
"/m_layer_configs/43/m_select_max_dphi"_json_pointer] <<
"\n";
700 { "op": "replace", "path": "/m_layer_configs/43/m_select_max_dphi", "value": 3.141 } 703 std::cout << "Layer 43, m_select_max_dphi = " <<
j[
"/m_layer_configs/43/m_select_max_dphi"_json_pointer] <<
"\n";
705 auto &jx =
j[
"/m_layer_configs/60"_json_pointer];
707 json::json_pointer jp(lojz);
713 printf(
"Layer 43 : m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
719 printf(
"Layer 60 : m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
729 auto &
x =
j[
"/m_layer_configs"_json_pointer];
730 std::cout <<
"Typename /m_layer_configs " <<
x.type_name() <<
"\n";
731 auto &y =
j[
"/m_layer_configs/143"_json_pointer];
732 std::cout <<
"Typename /m_layer_configs/143 " << y.type_name() <<
", is_null=" << y.is_null() <<
"\n";
742 cjp.
cd(
"/m_layer_configs/43/m_select_max_dphi");
743 std::cout <<
"Layer 43, m_select_max_dphi = " << cjp.
get(
"") <<
"\n";
747 std::cout <<
"Layer 43, m_select_max_dphi = " << cjp.
get(
"/m_layer_configs/43/m_select_max_dphi") <<
"\n";
750 std::cout <<
"Replacing layer 60 m_select_max_dphi with full path\n";
751 cjp.
replace(
"/m_layer_configs/60/m_select_max_dphi", 99.876);
754 std::cout <<
"Trying to replace an non-existent array entry\n";
755 cjp.
replace(
"/m_layer_configs/1460/m_select_max_dphi", 666.666);
757 std::cout <<
"Caugth exception: " << exc.what() <<
"\n";
760 std::cout <<
"Trying to replace an non-existent object entry\n";
761 cjp.
replace(
"/m_layer_configs/1/moo_select_max_dphi", 666.666);
763 std::cout <<
"Caugth exception: " << exc.what() <<
"\n";
766 std::cout <<
"Replacing m_select_max_dphi on layers 1 to 3 to 7.7\n";
767 cjp.
cd(
"/m_layer_configs");
768 cjp.
replace(1, 3,
"/m_select_max_dphi", 7.7);
776 printf(
"Layer 43: m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
782 printf(
"Layer 60: m_select_max_dphi = %f\n", it_cfg.
m_layer_configs[60].m_select_max_dphi);
783 for (
int i = 0;
i < 5; ++
i)
784 printf(
"Layer %2d: m_select_max_dphi = %f\n",
i, it_cfg.
m_layer_configs[
i].m_select_max_dphi);
790 auto &
j = cjp.
get(
"");
792 auto &
x =
j[
"/m_layer_configs"_json_pointer];
793 std::cout <<
"Typename /m_layer_configs " <<
x.type_name() <<
"\n";
794 auto &y =
j[
"/m_layer_configs/143"_json_pointer];
795 std::cout <<
"Typename /m_layer_configs/143 " << y.type_name() <<
", is_null=" << y.is_null() <<
"\n";
nlohmann::json * m_current
std::string m_pre_bkfit_filter_name
static void register_seed_partitioner(const std::string &name, partition_seeds_func func)
static void register_track_scorer(const std::string &name, track_score_func func)
void to_json(nlohmann::json &nlohmann_json_j, const mkfit::LayerControl &nlohmann_json_t)
std::string dump(int indent=2)
std::string m_seed_cleaner_name
std::string m_seed_partitioner_name
static void register_duplicate_cleaner(const std::string &name, clean_duplicates_func func)
std::function< track_score_cf > track_score_func
clean_seeds_func m_seed_cleaner
static std::string to_string(const XMLCh *ch)
void replace(const std::string &path, T val)
#define ITCONF_DEFINE_TYPE_NON_INTRUSIVE(Type,...)
static filter_candidates_func get_candidate_filter(const std::string &name)
void test_Direct(IterationConfig &it_cfg)
void patch_Files(IterationsInfo &its_info, const std::vector< std::string > &fnames, ConfigJsonPatcher::PatchReport *report=nullptr)
std::string exc_hdr(const char *func=nullptr) const
std::function< filter_candidates_cf > filter_candidates_func
std::vector< nlohmann::json * > m_json_stack
std::vector< IterationLayerConfig > m_layer_configs
static void register_seed_cleaner(const std::string &name, clean_seeds_func func)
static partition_seeds_func get_seed_partitioner(const std::string &name)
void setupStandardFunctionsFromNames()
std::string m_default_track_scorer_name
partition_seeds_func m_seed_partitioner
std::unique_ptr< IterationConfig > patchLoad_File(const IterationsInfo &its_info, const std::string &fname, ConfigJsonPatcher::PatchReport *report=nullptr)
nlohmann::json & get(const std::string &path)
key
prepare the HTCondor submission files and eventually submit them
std::string m_post_bkfit_filter_name
void cd(const std::string &path)
std::vector< std::string > m_path_stack
void save_Iterations(IterationsInfo &its_info, const std::string &fname_fmt, bool include_iter_info_preamble)
void test_Patcher(IterationConfig &it_cfg)
void from_json(const nlohmann::json &nlohmann_json_j, mkfit::LayerControl &nlohmann_json_t)
static const char * algoint_to_cstr(int algo)
filter_candidates_func m_post_bkfit_filter
static track_score_func get_track_scorer(const std::string &name)
static clean_duplicates_func get_duplicate_cleaner(const std::string &name)
clean_duplicates_func m_duplicate_cleaner
std::unique_ptr< IterationConfig > load_File(const std::string &fname)
void dump(IterationsInfo &its_info)
std::unique_ptr< nlohmann::json > m_json
void cd_up(const std::string &path="")
ConfigJsonPatcher(bool verbose=false)
track_score_func m_default_track_scorer
std::function< clean_seeds_cf > clean_seeds_func
static clean_seeds_func get_seed_cleaner(const std::string &name)
filter_candidates_func m_pre_bkfit_filter
void cd_top(const std::string &path="")
std::vector< SteeringParams > m_steering_params
std::function< clean_duplicates_cf > clean_duplicates_func
std::string m_duplicate_cleaner_name
static void register_candidate_filter(const std::string &name, filter_candidates_func func)
cont
load Luminosity info ##
std::function< partition_seeds_cf > partition_seeds_func
std::string get_abs_path() const