CMS 3D CMS Logo

IterationConfig.cc
Go to the documentation of this file.
5 
6 //#define DEBUG
7 #include "Debug.h"
8 
9 #include "nlohmann/json.hpp"
10 
11 #include <fstream>
12 #include <mutex>
13 #include <regex>
14 #include <iostream>
15 #include <iomanip>
16 
17 // Redefine to also support ordered_json ... we want to keep variable order in JSON save files.
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__)) \
21  } \
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__)) \
24  } \
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__)) \
27  } \
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__)) \
30  }
31 
32 namespace mkfit {
33 
34  // Begin AUTO code, some members commented out.
35 
37  /* int */ m_layer)
38 
40  /* std::vector<LayerControl> */ m_layer_plan,
41  /* std::string */ m_track_scorer_name,
42  /* int */ m_region,
43  /* int */ m_fwd_search_pickup,
44  /* int */ m_bkw_fit_last,
45  /* int */ m_bkw_search_pickup)
46 
48  /* int */ m_layer,
49  /* float */ m_select_min_dphi,
50  /* float */ m_select_max_dphi,
51  /* float */ m_select_min_dq,
52  /* float */ m_select_max_dq,
53  /* std::vector<float> */ m_winpars_fwd,
54  /* std::vector<float> */ m_winpars_bkw)
55 
57  /* int */ nlayers_per_seed,
58  /* int */ maxCandsPerSeed,
59  /* int */ maxHolesPerCand,
60  /* int */ maxConsecHoles,
61  /* float */ chi2Cut_min,
62  /* float */ chi2CutOverlap,
63  /* float */ pTCutOverlap,
64  /* bool */ recheckOverlap,
65  /* bool */ useHitSelectionV2,
66  /* int */ minHitsQF,
67  /* float */ minPtCut,
68  /* unsigned int */ maxClusterSize)
69 
71  /* int */ m_iteration_index,
72  /* int */ m_track_algorithm,
73  /* std::string */ m_seed_cleaner_name,
74  /* std::string */ m_seed_partitioner_name,
75  /* std::string */ m_pre_bkfit_filter_name,
76  /* std::string */ m_post_bkfit_filter_name,
77  /* std::string */ m_duplicate_cleaner_name,
78  /* std::string */ m_default_track_scorer_name,
79  /* bool */ m_requires_seed_hit_sorting,
80  /* bool */ m_backward_search,
81  /* bool */ m_backward_drop_seed_hits,
82  /* int */ m_backward_fit_min_hits,
83  /* float */ sc_ptthr_hpt,
84  /* float */ sc_drmax_bh,
85  /* float */ sc_dzmax_bh,
86  /* float */ sc_drmax_eh,
87  /* float */ sc_dzmax_eh,
88  /* float */ sc_drmax_bl,
89  /* float */ sc_dzmax_bl,
90  /* float */ sc_drmax_el,
91  /* float */ sc_dzmax_el,
92  /* float */ dc_fracSharedHits,
93  /* float */ dc_drth_central,
94  /* float */ dc_drth_obarrel,
95  /* float */ dc_drth_forward,
96  /* mkfit::IterationParams */ m_params,
97  /* mkfit::IterationParams */ m_backward_params,
98  /* int */ m_n_regions,
99  /* vector<int> */ m_region_order,
100  /* vector<mkfit::SteeringParams> */ m_steering_params,
101  /* vector<mkfit::IterationLayerConfig> */ m_layer_configs)
102 
104  /* vector<mkfit::IterationConfig> */ m_iterations)
105 
106  // End AUTO code.
107 
108  // Begin IterationConfig function catalogs
109 
110  namespace {
111  struct FuncCatalog {
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;
117 
118  std::mutex catalog_mutex;
119  };
120 
121  FuncCatalog &get_catalog() {
122  CMS_SA_ALLOW static FuncCatalog func_catalog;
123  return func_catalog;
124  }
125  } // namespace
126 
127 #define GET_FC \
128  auto &fc = get_catalog(); \
129  const std::lock_guard<std::mutex> lock(fc.catalog_mutex)
130 
132  GET_FC;
133  fc.seed_cleaners.insert({name, func});
134  }
136  GET_FC;
137  fc.seed_partitioners.insert({name, func});
138  }
140  GET_FC;
141  fc.candidate_filters.insert({name, func});
142  }
144  GET_FC;
145  fc.duplicate_cleaners.insert({name, func});
146  }
148  GET_FC;
149  fc.track_scorers.insert({name, func});
150  }
151 
152  namespace {
153  template <class T>
154  typename T::mapped_type resolve_func_name(const T &cont, const std::string &name, const char *func) {
155  if (name.empty()) {
156  return nullptr;
157  }
158  auto ii = cont.find(name);
159  if (ii == cont.end()) {
160  std::string es(func);
161  es += " '" + name + "' not found in function registry.";
162  throw std::runtime_error(es);
163  }
164  return ii->second;
165  }
166  } // namespace
167 
169  GET_FC;
170  return resolve_func_name(fc.seed_cleaners, name, __func__);
171  }
173  GET_FC;
174  return resolve_func_name(fc.seed_partitioners, name, __func__);
175  }
177  GET_FC;
178  return resolve_func_name(fc.candidate_filters, name, __func__);
179  }
181  GET_FC;
182  return resolve_func_name(fc.duplicate_cleaners, name, __func__);
183  }
185  GET_FC;
186  return resolve_func_name(fc.track_scorers, name, __func__);
187  }
188 
189 #undef GET_FC
190 
191  // End IterationConfig function catalogs
192 
195  dprintf(" Set seed_cleaner for '%s' %s\n", m_seed_cleaner_name.c_str(), m_seed_cleaner ? "SET" : "NOT SET");
196 
198  dprintf(
199  " Set seed_partitioner for '%s' %s\n", m_seed_partitioner_name.c_str(), m_seed_partitioner ? "SET" : "NOT SET");
200 
202  dprintf(
203  " Set pre_bkfit_filter for '%s' %s\n", m_pre_bkfit_filter_name.c_str(), m_pre_bkfit_filter ? "SET" : "NOT SET");
204 
206  dprintf(" Set post_bkfit_filter for '%s' %s\n",
207  m_post_bkfit_filter_name.c_str(),
208  m_post_bkfit_filter ? "SET" : "NOT SET");
209 
211  dprintf(" Set duplicate_cleaner for '%s' %s\n",
212  m_duplicate_cleaner_name.c_str(),
213  m_duplicate_cleaner ? "SET" : "NOT SET");
214 
216  for (auto &sp : m_steering_params) {
217  sp.m_track_scorer =
218  sp.m_track_scorer_name.empty() ? m_default_track_scorer : get_track_scorer(sp.m_track_scorer_name);
219  }
220  }
221 
222  // ============================================================================
223  // ConfigJsonPatcher
224  // ============================================================================
225 
227 
229 
231  std::string s;
232  s.reserve(64);
233  for (auto &p : m_path_stack)
234  s += p;
235  return s;
236  }
237 
239  std::string s;
240  s.reserve(128);
241  s = "ConfigJsonPatcher";
242  if (func) {
243  s += "::";
244  s += func;
245  }
246  s += " '";
247  s += get_abs_path();
248  s += "' ";
249  return s;
250  }
251 
252  template <class T>
253  void ConfigJsonPatcher::load(const T &o) {
254  m_json = std::make_unique<nlohmann::json>();
255  *m_json = o;
256  cd_top();
257  }
258  template void ConfigJsonPatcher::load<IterationsInfo>(const IterationsInfo &o);
259  template void ConfigJsonPatcher::load<IterationConfig>(const IterationConfig &o);
260 
261  template <class T>
263  from_json(*m_json, o);
264  }
265  template void ConfigJsonPatcher::save<IterationConfig>(IterationConfig &o);
266 
267  // Must not bork the IterationConfig elements of IterationsInfo ... default
268  // deserializator apparently reinitializes the vectors with defaults c-tors.
269  template <>
270  void ConfigJsonPatcher::save<IterationsInfo>(IterationsInfo &o) {
271  auto &itc_arr = m_json->at("m_iterations");
272  for (int i = 0; i < o.size(); ++i) {
273  from_json(itc_arr[i], o[i]);
274  }
275  }
276 
278  nlohmann::json::json_pointer jp(path);
279  m_json_stack.push_back(m_current);
280  m_path_stack.push_back(path);
281  m_current = &m_current->at(jp);
282  }
283 
285  if (m_json_stack.empty())
286  throw std::runtime_error("JSON stack empty on cd_up");
287 
288  m_current = m_json_stack.back();
289  m_json_stack.pop_back();
290  m_path_stack.pop_back();
291  if (!path.empty())
292  cd(path);
293  }
294 
296  m_current = m_json.get();
297  m_json_stack.clear();
298  m_path_stack.clear();
299  if (!path.empty())
300  cd(path);
301  }
302 
303  template <typename T>
305  nlohmann::json::json_pointer jp(path);
306  m_current->at(jp) = val;
307  }
308  template void ConfigJsonPatcher::replace<int>(const std::string &path, int val);
309  template void ConfigJsonPatcher::replace<float>(const std::string &path, float val);
310  template void ConfigJsonPatcher::replace<double>(const std::string &path, double val);
311 
312  template <typename T>
314  nlohmann::json::json_pointer jp(path);
315  for (int i = first; i <= last; ++i) {
316  m_current->at(i).at(jp) = val;
317  }
318  }
319  template void ConfigJsonPatcher::replace<int>(int first, int last, const std::string &path, int val);
320  template void ConfigJsonPatcher::replace<float>(int first, int last, const std::string &path, float val);
321  template void ConfigJsonPatcher::replace<double>(int first, int last, const std::string &path, double val);
322 
324  nlohmann::json::json_pointer jp(path);
325  return m_current->at(jp);
326  }
327 
329  if (j.is_null())
330  throw std::runtime_error(exc_hdr(__func__) + "null not expected");
331 
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");
334  }
335 
336  int n_replaced = 0;
337 
338  if (j.is_object()) {
339  static const std::regex index_range_re("^\\[(\\d+)..(\\d+)\\]$", std::regex::optimize);
340 
341  for (auto &[key, value] : j.items()) {
342  std::smatch m;
343  std::regex_search(key, m, index_range_re);
344 
345  if (m.size() == 3) {
346  if (!m_current->is_array())
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));
350  for (int i = first; i <= last; ++i) {
351  std::string s("/");
352  s += std::to_string(i);
353  cd(s);
354  if (value.is_array()) {
355  for (auto &el : value)
356  n_replaced += replace(el);
357  } else {
358  n_replaced += replace(value);
359  }
360  cd_up();
361  }
362  } else if (value.is_array() || value.is_object()) {
363  std::string s("/");
364  s += key;
365  cd(s);
366  n_replaced += replace(value);
367  cd_up();
368  } else if (value.is_number() || value.is_boolean() || value.is_string()) {
369  std::string s("/");
370  s += key;
371  nlohmann::json::json_pointer jp(s);
372  if (m_current->at(jp) != value) {
373  if (m_verbose)
374  std::cout << " " << get_abs_path() << s << ": " << m_current->at(jp) << " -> " << value << "\n";
375 
376  m_current->at(jp) = value;
377  ++n_replaced;
378  }
379  } else {
380  throw std::runtime_error(exc_hdr(__func__) + "unexpected value type");
381  }
382  }
383  } else if (j.is_array() && j.empty()) {
384  } else if (j.is_array()) {
385  // Arrays are somewhat tricky.
386  // At the moment all elements are expected to be objects.
387  // This means arrays of basic types are not supported (like layer index arrays).
388  // Should not be too hard to add support for this.
389  // Now, the objects in the array can be of two kinds:
390  // a) Their keys can be json_pointer strings starting with numbers or ranges [i_low..i_high].
391  // b) They can be actual elements of the array. In this case we require the length of
392  // the array to be equal to existing length in the configuration.
393  // It is not allowed for these two kinds to mix.
394 
395  // Determine the kind of array: json_ptr or object
396 
397  static const std::regex index_re("^(?:\\[\\d+..\\d+\\]|\\d+(?:/.*)?)$", std::regex::optimize);
398 
399  bool has_index = false, has_plain = false;
400  for (int i = 0; i < (int)j.size(); ++i) {
401  const nlohmann::json &el = j[i];
402 
403  if (!el.is_object())
404  throw std::runtime_error(exc_hdr(__func__) + "array elements expected to be objects");
405 
406  for (nlohmann::json::const_iterator it = el.begin(); it != el.end(); ++it) {
407  if (std::regex_search(it.key(), index_re)) {
408  has_index = true;
409  if (has_plain)
410  throw std::runtime_error(exc_hdr(__func__) + "indexed array entry following plain one");
411  } else {
412  has_plain = true;
413  if (has_index)
414  throw std::runtime_error(exc_hdr(__func__) + "plain array entry following indexed one");
415  }
416  }
417  }
418  if (has_index) {
419  for (auto &element : j) {
420  n_replaced += replace(element);
421  }
422  } else {
423  if (m_current && !m_current->is_array())
424  throw std::runtime_error(exc_hdr(__func__) + "plain array detected when current is not an array");
425  if (m_current->size() != j.size())
426  throw std::runtime_error(exc_hdr(__func__) + "plain array of different size than at current pos");
427 
428  std::string s;
429  for (int i = 0; i < (int)j.size(); ++i) {
430  s = "/";
431  s += std::to_string(i);
432  cd(s);
433  n_replaced += replace(j[i]);
434  cd_up();
435  }
436  }
437  } else {
438  throw std::runtime_error(exc_hdr(__func__) + "unexpected json type");
439  }
440 
441  return n_replaced;
442  }
443 
445 
446  // ============================================================================
447  // patch_File steering function
448  // ============================================================================
449  /*
450  See example JSON patcher input: "mkFit/config-parse/test.json"
451 
452  The file can contain several valid JSON dumps in sequence.
453 
454  '/' character can be used to descend more than one level at a time.
455 
456  A number can be used to specify an array index. This can be combined with
457  the '/' syntax.
458 
459  "[first,last]" key (as string) can be used to denote a range of array
460  elements. Such a key must not be combined with a '/' syntax.
461 */
462 
463  namespace {
464  // Open file for writing, throw exception on failure.
465  void open_ofstream(std::ofstream &ofs, const std::string &fname, const char *pfx = nullptr) {
466  ofs.open(fname, std::ofstream::trunc);
467  if (!ofs) {
468  char m[2048];
469  snprintf(m, 2048, "%s%sError opening %s for write: %m", pfx ? pfx : "", pfx ? " " : "", fname.c_str());
470  throw std::runtime_error(m);
471  }
472  }
473 
474  // Open file for reading, throw exception on failure.
475  void open_ifstream(std::ifstream &ifs, const std::string &fname, const char *pfx = nullptr) {
476  ifs.open(fname);
477  if (!ifs) {
478  char m[2048];
479  snprintf(m, 2048, "%s%sError opening %s for read: %m", pfx ? pfx : "", pfx ? " " : "", fname.c_str());
480  throw std::runtime_error(m);
481  }
482  }
483 
484  // Skip white-space, return true if more characters are available, false if eof.
485  bool skipws_ifstream(std::ifstream &ifs) {
486  while (std::isspace(ifs.peek()))
487  ifs.get();
488  return !ifs.eof();
489  }
490  } // namespace
491 
493  const std::vector<std::string> &fnames,
496  cjp.load(its_info);
497 
499 
500  for (auto &fname : fnames) {
501  std::ifstream ifs;
502  open_ifstream(ifs, fname, __func__);
503 
504  if (m_verbose) {
505  printf("%s begin reading from file %s.\n", __func__, fname.c_str());
506  }
507 
508  int n_read = 0, n_tot_replaced = 0;
509  while (skipws_ifstream(ifs)) {
511  ifs >> j;
512  ++n_read;
513 
514  if (m_verbose) {
515  std::cout << " Read JSON entity " << n_read << " -- applying patch:\n";
516  // std::cout << j.dump(3) << "\n";
517  }
518 
519  int n_replaced = cjp.replace(j);
520 
521  if (m_verbose) {
522  std::cout << " Replaced " << n_replaced << " entries.\n";
523  }
524  cjp.cd_top();
525  n_tot_replaced += n_replaced;
526  }
527 
528  if (m_verbose) {
529  printf("%s read %d JSON entities from file %s, replaced %d parameters.\n",
530  __func__,
531  n_read,
532  fname.c_str(),
533  n_tot_replaced);
534  }
535 
536  ifs.close();
537 
538  rep.inc_counts(1, n_read, n_tot_replaced);
539  }
540 
541  if (rep.n_replacements > 0) {
542  cjp.save(its_info);
543  }
544 
545  if (report)
546  report->inc_counts(rep);
547  }
548 
549  std::unique_ptr<IterationConfig> ConfigJson::patchLoad_File(const IterationsInfo &its_info,
550  const std::string &fname,
553 
554  std::ifstream ifs;
555  open_ifstream(ifs, fname, __func__);
556 
557  if (m_verbose) {
558  printf("%s begin reading from file %s.\n", __func__, fname.c_str());
559  }
560 
561  if (!skipws_ifstream(ifs))
562  throw std::runtime_error("empty file");
563 
565  ifs >> j;
566  int track_algo = j["m_track_algorithm"];
567 
568  int iii = -1;
569  for (int i = 0; i < its_info.size(); ++i) {
570  if (its_info[i].m_track_algorithm == track_algo) {
571  iii = i;
572  break;
573  }
574  }
575  if (iii == -1)
576  throw std::runtime_error("matching IterationConfig not found");
577 
578  if (m_verbose) {
579  std::cout << " Read JSON entity, Iteration index is " << iii << " -- cloning and applying JSON patch:\n";
580  }
581 
582  IterationConfig *icp = new IterationConfig(its_info[iii]);
583  IterationConfig &ic = *icp;
584 
586  cjp.load(ic);
587 
588  int n_replaced = cjp.replace(j);
589 
590  cjp.cd_top();
591 
592  if (m_verbose) {
593  printf("%s read 1 JSON entity from file %s, replaced %d parameters.\n", __func__, fname.c_str(), n_replaced);
594  }
595 
596  ifs.close();
597 
598  rep.inc_counts(1, 1, n_replaced);
599 
600  if (rep.n_replacements > 0) {
601  cjp.save(ic);
602  }
603 
604  if (report)
605  report->inc_counts(rep);
606 
607  return std::unique_ptr<IterationConfig>(icp);
608  }
609 
610  std::unique_ptr<IterationConfig> ConfigJson::load_File(const std::string &fname) {
611  std::ifstream ifs;
612  open_ifstream(ifs, fname, __func__);
613 
614  if (m_verbose) {
615  printf("%s begin reading from file %s.\n", __func__, fname.c_str());
616  }
617 
618  if (!skipws_ifstream(ifs))
619  throw std::runtime_error("empty file");
620 
622  ifs >> j;
623 
624  if (m_verbose) {
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";
627  }
628 
629  IterationConfig *icp = new IterationConfig();
630 
631  from_json(j, *icp);
632 
633  return std::unique_ptr<IterationConfig>(icp);
634  }
635 
636  // ============================================================================
637  // Save each IterationConfig into a separate json file
638  // ============================================================================
639 
641  const std::string &fname_fmt,
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;
645 
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");
648 
649  for (int ii = 0; ii < its_info.size(); ++ii) {
650  const IterationConfig &itconf = its_info[ii];
651 
652  char fname[1024];
653  if (has_pct_d)
654  snprintf(fname, 1024, fname_fmt.c_str(), ii);
655  else
656  snprintf(fname, 1024, fname_fmt.c_str(), TrackBase::algoint_to_cstr(itconf.m_track_algorithm));
657 
658  std::ofstream ofs;
659  open_ofstream(ofs, fname, __func__);
660 
661  if (include_iter_info_preamble) {
662  ofs << "{ \"m_iterations/" << ii << "\": ";
663  }
664 
665  nlohmann::ordered_json j;
666  to_json(j, itconf);
667 
668  ofs << std::setw(1);
669  ofs << j;
670 
671  if (include_iter_info_preamble) {
672  ofs << " }";
673  }
674 
675  ofs << "\n";
676  ofs.close();
677  }
678  }
679 
681  nlohmann::ordered_json j = its_info;
682  std::cout << j.dump(3) << "\n";
683  }
684 
685  // ============================================================================
686  // Tests for ConfigJson stuff
687  // ============================================================================
688 
690  using nlohmann::json;
691 
692  std::string lojz("/m_select_max_dphi");
693 
694  json j = it_cfg;
695  std::cout << j.dump(1) << "\n";
696 
697  std::cout << "Layer 43, m_select_max_dphi = " << j["/m_layer_configs/43/m_select_max_dphi"_json_pointer] << "\n";
698  std::cout << "Patching it to pi ...\n";
699  json p = R"([
700  { "op": "replace", "path": "/m_layer_configs/43/m_select_max_dphi", "value": 3.141 }
701  ])"_json;
702  j = j.patch(p);
703  std::cout << "Layer 43, m_select_max_dphi = " << j["/m_layer_configs/43/m_select_max_dphi"_json_pointer] << "\n";
704 
705  auto &jx = j["/m_layer_configs/60"_json_pointer];
706  // jx["m_select_max_dphi"] = 99.876;
707  json::json_pointer jp(lojz);
708  jx[jp] = 99.876;
709 
710  // try loading it back, see what happens to vector m_layer_configs.
711 
712  from_json(j, it_cfg);
713  printf("Layer 43 : m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
714  it_cfg.m_layer_configs[43].m_select_max_dphi,
715  (int)it_cfg.m_layer_configs.size(),
716  it_cfg.m_n_regions,
717  (int)it_cfg.m_steering_params.size());
718 
719  printf("Layer 60 : m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
720  it_cfg.m_layer_configs[60].m_select_max_dphi,
721  (int)it_cfg.m_layer_configs.size(),
722  it_cfg.m_n_regions,
723  (int)it_cfg.m_steering_params.size());
724 
725  // try accessing something that does not exist
726 
727  // std::cout << "Non-existent path " << j["/m_layer_configs/143/m_select_max_dphi"_json_pointer] << "\n";
728 
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";
733  }
734 
736  ConfigJsonPatcher cjp;
737  cjp.load(it_cfg);
738 
739  std::cout << cjp.dump(1) << "\n";
740 
741  {
742  cjp.cd("/m_layer_configs/43/m_select_max_dphi");
743  std::cout << "Layer 43, m_select_max_dphi = " << cjp.get("") << "\n";
744  std::cout << "Setting it to pi ...\n";
745  cjp.replace("", 3.141);
746  cjp.cd_top();
747  std::cout << "Layer 43, m_select_max_dphi = " << cjp.get("/m_layer_configs/43/m_select_max_dphi") << "\n";
748  }
749  {
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);
752  }
753  try {
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);
756  } catch (std::exception &exc) {
757  std::cout << "Caugth exception: " << exc.what() << "\n";
758  }
759  try {
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);
762  } catch (std::exception &exc) {
763  std::cout << "Caugth exception: " << exc.what() << "\n";
764  }
765  {
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);
769  cjp.cd_top();
770  }
771 
772  // try getting it back into c++, see what happens to vector m_layer_configs.
773 
774  cjp.save(it_cfg);
775 
776  printf("Layer 43: m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
777  it_cfg.m_layer_configs[43].m_select_max_dphi,
778  (int)it_cfg.m_layer_configs.size(),
779  it_cfg.m_n_regions,
780  (int)it_cfg.m_steering_params.size());
781 
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);
785 
786  // try accessing something that does not exist
787 
788  // std::cout << "Non-existent path " << j["/m_layer_configs/143/m_select_max_dphi"_json_pointer] << "\n";
789 
790  auto &j = cjp.get("");
791 
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";
796  }
797 
798 } // namespace mkfit
nlohmann::json * m_current
std::string m_pre_bkfit_filter_name
#define CMS_SA_ALLOW
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)
bool verbose
void to_json(nlohmann::json &nlohmann_json_j, const mkfit::LayerControl &nlohmann_json_t)
static std::mutex mutex
Definition: Proxy.cc:8
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)
assert(be >=bs)
std::function< track_score_cf > track_score_func
Definition: FunctionTypes.h:40
clean_seeds_func m_seed_cleaner
static std::string to_string(const XMLCh *ch)
nlohmann::json json
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
Definition: FunctionTypes.h:28
std::vector< nlohmann::json * > m_json_stack
#define GET_FC
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)
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)
Definition: value.py:1
std::vector< std::string > m_path_stack
void save_Iterations(IterationsInfo &its_info, const std::string &fname_fmt, bool include_iter_info_preamble)
rep
Definition: cuy.py:1189
void test_Patcher(IterationConfig &it_cfg)
ii
Definition: cuy.py:589
void from_json(const nlohmann::json &nlohmann_json_j, mkfit::LayerControl &nlohmann_json_t)
static const char * algoint_to_cstr(int algo)
Definition: Track.cc:331
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)
string fname
main script
std::unique_ptr< nlohmann::json > m_json
void cd_up(const std::string &path="")
float x
ConfigJsonPatcher(bool verbose=false)
track_score_func m_default_track_scorer
std::function< clean_seeds_cf > clean_seeds_func
Definition: FunctionTypes.h:22
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="")
long double T
std::vector< SteeringParams > m_steering_params
std::function< clean_duplicates_cf > clean_duplicates_func
Definition: FunctionTypes.h:31
std::string m_duplicate_cleaner_name
static void register_candidate_filter(const std::string &name, filter_candidates_func func)
#define dprintf(...)
Definition: Debug.h:98
cont
load Luminosity info ##
Definition: generateEDF.py:620
std::function< partition_seeds_cf > partition_seeds_func
Definition: FunctionTypes.h:25
std::string get_abs_path() const