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