CMS 3D CMS Logo

IterationConfig.cc
Go to the documentation of this file.
4 
5 #include "nlohmann/json.hpp"
6 
7 #include <fstream>
8 #include <regex>
9 #include <iostream>
10 #include <iomanip>
11 
12 // Redefine to also support ordered_json ... we want to keep variable order in JSON save files.
13 #define ITCONF_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \
14  inline void to_json(nlohmann::json &nlohmann_json_j, const Type &nlohmann_json_t) { \
15  NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
16  } \
17  inline void from_json(const nlohmann::json &nlohmann_json_j, Type &nlohmann_json_t) { \
18  NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) \
19  } \
20  inline void to_json(nlohmann::ordered_json &nlohmann_json_j, const Type &nlohmann_json_t) { \
21  NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) \
22  } \
23  inline void from_json(const nlohmann::ordered_json &nlohmann_json_j, Type &nlohmann_json_t) { \
24  NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) \
25  }
26 
27 namespace mkfit {
28 
29  // Begin AUTO code, some members commented out.
30 
32  /* int */ m_layer)
33 
35  /* std::vector<LayerControl> */ m_layer_plan,
36  /* int */ m_region,
37  /* int */ m_fwd_search_pickup,
38  /* int */ m_bkw_fit_last,
39  /* int */ m_bkw_search_pickup
40 
41  )
42 
44  /* float */ m_select_min_dphi,
45  /* float */ m_select_max_dphi,
46  /* float */ m_select_min_dq,
47  /* float */ m_select_max_dq,
48  /* float */ c_dp_sf,
49  /* float */ c_dp_0,
50  /* float */ c_dp_1,
51  /* float */ c_dp_2,
52  /* float */ c_dq_sf,
53  /* float */ c_dq_0,
54  /* float */ c_dq_1,
55  /* float */ c_dq_2,
56  /* float */ c_c2_sf,
57  /* float */ c_c2_0,
58  /* float */ c_c2_1,
59  /* float */ c_c2_2)
60 
62  /* int */ nlayers_per_seed,
63  /* int */ maxCandsPerSeed,
64  /* int */ maxHolesPerCand,
65  /* int */ maxConsecHoles,
66  /* float */ chi2Cut_min,
67  /* float */ chi2CutOverlap,
68  /* float */ pTCutOverlap,
69  /* float */ c_ptthr_hpt,
70  /* float */ c_drmax_bh,
71  /* float */ c_dzmax_bh,
72  /* float */ c_drmax_eh,
73  /* float */ c_dzmax_eh,
74  /* float */ c_drmax_bl,
75  /* float */ c_dzmax_bl,
76  /* float */ c_drmax_el,
77  /* float */ c_dzmax_el,
78  /* int */ minHitsQF,
79  /* float */ fracSharedHits,
80  /* float */ drth_central,
81  /* float */ drth_obarrel,
82  /* float */ drth_forward
83 
84  )
85 
88  /* int */ m_iteration_index,
89  /* int */ m_track_algorithm,
90  /* bool */ m_requires_seed_hit_sorting,
91  /* bool */ m_requires_quality_filter,
92  /* bool */ m_requires_dupclean_tight,
93  /* bool */ m_backward_search,
94  /* bool */ m_backward_drop_seed_hits,
95  /* int */ m_backward_fit_min_hits,
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  // /* function<void(const TrackerInfo&,const TrackVec&,const EventOfHits&,IterationSeedPartition&)> */ m_partition_seeds
103  )
104 
106  /* vector<mkfit::IterationConfig> */ m_iterations)
107 
108  // End AUTO code.
109 
110  // ============================================================================
111  // ConfigJsonPatcher
112  // ============================================================================
113 
115 
117 
119  std::string s;
120  s.reserve(64);
121  for (auto &p : m_path_stack)
122  s += p;
123  return s;
124  }
125 
127  std::string s;
128  s.reserve(128);
129  s = "ConfigJsonPatcher";
130  if (func) {
131  s += "::";
132  s += func;
133  }
134  s += " '";
135  s += get_abs_path();
136  s += "' ";
137  return s;
138  }
139 
140  template <class T>
141  void ConfigJsonPatcher::load(const T &o) {
142  m_json = std::make_unique<nlohmann::json>();
143  *m_json = o;
144  cd_top();
145  }
146  template void ConfigJsonPatcher::load<IterationsInfo>(const IterationsInfo &o);
147  template void ConfigJsonPatcher::load<IterationConfig>(const IterationConfig &o);
148 
149  template <class T>
151  from_json(*m_json, o);
152  }
153  template void ConfigJsonPatcher::save<IterationConfig>(IterationConfig &o);
154 
155  // Must not bork the IterationConfig elements of IterationsInfo ... default
156  // deserializator apparently reinitializes the vectors with defaults c-tors.
157  template <>
158  void ConfigJsonPatcher::save<IterationsInfo>(IterationsInfo &o) {
159  auto &itc_arr = m_json->at("m_iterations");
160  for (int i = 0; i < o.size(); ++i) {
161  from_json(itc_arr[i], o[i]);
162  }
163  }
164 
166  nlohmann::json::json_pointer jp(path);
167  m_json_stack.push_back(m_current);
168  m_path_stack.push_back(path);
169  m_current = &m_current->at(jp);
170  }
171 
173  if (m_json_stack.empty())
174  throw std::runtime_error("JSON stack empty on cd_up");
175 
176  m_current = m_json_stack.back();
177  m_json_stack.pop_back();
178  m_path_stack.pop_back();
179  if (!path.empty())
180  cd(path);
181  }
182 
184  m_current = m_json.get();
185  m_json_stack.clear();
186  m_path_stack.clear();
187  if (!path.empty())
188  cd(path);
189  }
190 
191  template <typename T>
193  nlohmann::json::json_pointer jp(path);
194  m_current->at(jp) = val;
195  }
196  template void ConfigJsonPatcher::replace<int>(const std::string &path, int val);
197  template void ConfigJsonPatcher::replace<float>(const std::string &path, float val);
198  template void ConfigJsonPatcher::replace<double>(const std::string &path, double val);
199 
200  template <typename T>
202  nlohmann::json::json_pointer jp(path);
203  for (int i = first; i <= last; ++i) {
204  m_current->at(i).at(jp) = val;
205  }
206  }
207  template void ConfigJsonPatcher::replace<int>(int first, int last, const std::string &path, int val);
208  template void ConfigJsonPatcher::replace<float>(int first, int last, const std::string &path, float val);
209  template void ConfigJsonPatcher::replace<double>(int first, int last, const std::string &path, double val);
210 
212  nlohmann::json::json_pointer jp(path);
213  return m_current->at(jp);
214  }
215 
217  if (j.is_null())
218  throw std::runtime_error(exc_hdr(__func__) + "null not expected");
219 
220  if (j.is_boolean() || j.is_number() || j.is_string()) {
221  throw std::runtime_error(exc_hdr(__func__) + "value not expected on this parsing level");
222  }
223 
224  int n_replaced = 0;
225 
226  if (j.is_object()) {
227  static const std::regex index_range_re("^\\[(\\d+)..(\\d+)\\]$", std::regex::optimize);
228 
229  for (auto &[key, value] : j.items()) {
230  std::smatch m;
231  std::regex_search(key, m, index_range_re);
232 
233  if (m.size() == 3) {
234  if (!m_current->is_array())
235  throw std::runtime_error(exc_hdr(__func__) + "array range encountered when current json is not an array");
236  int first = std::stoi(m.str(1));
237  int last = std::stoi(m.str(2));
238  for (int i = first; i <= last; ++i) {
239  std::string s("/");
240  s += std::to_string(i);
241  cd(s);
242  if (value.is_array()) {
243  for (auto &el : value)
244  n_replaced += replace(el);
245  } else {
246  n_replaced += replace(value);
247  }
248  cd_up();
249  }
250  } else if (value.is_array() || value.is_object()) {
251  std::string s("/");
252  s += key;
253  cd(s);
254  n_replaced += replace(value);
255  cd_up();
256  } else if (value.is_number() || value.is_boolean() || value.is_string()) {
257  std::string s("/");
258  s += key;
259  nlohmann::json::json_pointer jp(s);
260  if (m_current->at(jp) != value) {
261  if (m_verbose)
262  std::cout << " " << get_abs_path() << s << ": " << m_current->at(jp) << " -> " << value << "\n";
263 
264  m_current->at(jp) = value;
265  ++n_replaced;
266  }
267  } else {
268  throw std::runtime_error(exc_hdr(__func__) + "unexpected value type");
269  }
270  }
271  } else if (j.is_array() && j.empty()) {
272  } else if (j.is_array()) {
273  // Arrays are somewhat tricky.
274  // At the moment all elements are expected to be objects.
275  // This means arrays of basic types are not supported (like layer index arrays).
276  // Should not be too hard to add support for this.
277  // Now, the objects in the array can be of two kinds:
278  // a) Their keys can be json_pointer strings starting with numbers or ranges [i_low..i_high].
279  // b) They can be actual elements of the array. In this case we require the length of
280  // the array to be equal to existing length in the configuration.
281  // It is not allowed for these two kinds to mix.
282 
283  // Determine the kind of array: json_ptr or object
284 
285  static const std::regex index_re("^(?:\\[\\d+..\\d+\\]|\\d+(?:/.*)?)$", std::regex::optimize);
286 
287  bool has_index = false, has_plain = false;
288  for (int i = 0; i < (int)j.size(); ++i) {
289  const nlohmann::json &el = j[i];
290 
291  if (!el.is_object())
292  throw std::runtime_error(exc_hdr(__func__) + "array elements expected to be objects");
293 
294  for (nlohmann::json::const_iterator it = el.begin(); it != el.end(); ++it) {
295  if (std::regex_search(it.key(), index_re)) {
296  has_index = true;
297  if (has_plain)
298  throw std::runtime_error(exc_hdr(__func__) + "indexed array entry following plain one");
299  } else {
300  has_plain = true;
301  if (has_index)
302  throw std::runtime_error(exc_hdr(__func__) + "plain array entry following indexed one");
303  }
304  }
305  }
306  if (has_index) {
307  for (auto &element : j) {
308  n_replaced += replace(element);
309  }
310  } else {
311  if (m_current && !m_current->is_array())
312  throw std::runtime_error(exc_hdr(__func__) + "plain array detected when current is not an array");
313  if (m_current->size() != j.size())
314  throw std::runtime_error(exc_hdr(__func__) + "plain array of different size than at current pos");
315 
316  std::string s;
317  for (int i = 0; i < (int)j.size(); ++i) {
318  s = "/";
319  s += std::to_string(i);
320  cd(s);
321  n_replaced += replace(j[i]);
322  cd_up();
323  }
324  }
325  } else {
326  throw std::runtime_error(exc_hdr(__func__) + "unexpected json type");
327  }
328 
329  return n_replaced;
330  }
331 
333 
334  // ============================================================================
335  // patch_File steering function
336  // ============================================================================
337  /*
338  See example JSON patcher input: "mkFit/config-parse/test.json"
339 
340  The file can contain several valid JSON dumps in sequence.
341 
342  '/' character can be used to descend more than one level at a time.
343 
344  A number can be used to specify an array index. This can be combined with
345  the '/' syntax.
346 
347  "[first,last]" key (as string) can be used to denote a range of array
348  elements. Such a key must not be combined with a '/' syntax.
349 */
350 
351  namespace {
352  // Open file for writing, throw exception on failure.
353  void open_ofstream(std::ofstream &ofs, const std::string &fname, const char *pfx = nullptr) {
354  ofs.open(fname, std::ofstream::trunc);
355  if (!ofs) {
356  char m[2048];
357  snprintf(m, 2048, "%s%sError opening %s for write: %m", pfx ? pfx : "", pfx ? " " : "", fname.c_str());
358  throw std::runtime_error(m);
359  }
360  }
361 
362  // Open file for reading, throw exception on failure.
363  void open_ifstream(std::ifstream &ifs, const std::string &fname, const char *pfx = nullptr) {
364  ifs.open(fname);
365  if (!ifs) {
366  char m[2048];
367  snprintf(m, 2048, "%s%sError opening %s for read: %m", pfx ? pfx : "", pfx ? " " : "", fname.c_str());
368  throw std::runtime_error(m);
369  }
370  }
371 
372  // Skip white-space, return true if more characters are available, false if eof.
373  bool skipws_ifstream(std::ifstream &ifs) {
374  while (std::isspace(ifs.peek()))
375  ifs.get();
376  return !ifs.eof();
377  }
378  } // namespace
379 
381  const std::vector<std::string> &fnames,
384  cjp.load(its_info);
385 
387 
388  for (auto &fname : fnames) {
389  std::ifstream ifs;
390  open_ifstream(ifs, fname, __func__);
391 
392  if (m_verbose) {
393  printf("%s begin reading from file %s.\n", __func__, fname.c_str());
394  }
395 
396  int n_read = 0, n_tot_replaced = 0;
397  while (skipws_ifstream(ifs)) {
399  ifs >> j;
400  ++n_read;
401 
402  if (m_verbose) {
403  std::cout << " Read JSON entity " << n_read << " -- applying patch:\n";
404  // std::cout << j.dump(3) << "\n";
405  }
406 
407  int n_replaced = cjp.replace(j);
408 
409  if (m_verbose) {
410  std::cout << " Replaced " << n_replaced << " entries.\n";
411  }
412  cjp.cd_top();
413  n_tot_replaced += n_replaced;
414  }
415 
416  if (m_verbose) {
417  printf("%s read %d JSON entities from file %s, replaced %d parameters.\n",
418  __func__,
419  n_read,
420  fname.c_str(),
421  n_tot_replaced);
422  }
423 
424  ifs.close();
425 
426  rep.inc_counts(1, n_read, n_tot_replaced);
427  }
428 
429  if (rep.n_replacements > 0) {
430  cjp.save(its_info);
431  }
432 
433  if (report)
434  report->inc_counts(rep);
435  }
436 
437  std::unique_ptr<IterationConfig> ConfigJson::patchLoad_File(const IterationsInfo &its_info,
438  const std::string &fname,
441 
442  std::ifstream ifs;
443  open_ifstream(ifs, fname, __func__);
444 
445  if (m_verbose) {
446  printf("%s begin reading from file %s.\n", __func__, fname.c_str());
447  }
448 
449  if (!skipws_ifstream(ifs))
450  throw std::runtime_error("empty file");
451 
453  ifs >> j;
454  int track_algo = j["m_track_algorithm"];
455 
456  int iii = -1;
457  for (int i = 0; i < its_info.size(); ++i) {
458  if (its_info[i].m_track_algorithm == track_algo) {
459  iii = i;
460  break;
461  }
462  }
463  if (iii == -1)
464  throw std::runtime_error("matching IterationConfig not found");
465 
466  if (m_verbose) {
467  std::cout << " Read JSON entity, Iteration index is " << iii << " -- cloning and applying JSON patch:\n";
468  }
469 
470  IterationConfig *icp = new IterationConfig(its_info[iii]);
471  IterationConfig &ic = *icp;
472 
474  cjp.load(ic);
475 
476  int n_replaced = cjp.replace(j);
477 
478  cjp.cd_top();
479 
480  if (m_verbose) {
481  printf("%s read 1 JSON entity from file %s, replaced %d parameters.\n", __func__, fname.c_str(), n_replaced);
482  }
483 
484  ifs.close();
485 
486  rep.inc_counts(1, 1, n_replaced);
487 
488  if (rep.n_replacements > 0) {
489  cjp.save(ic);
490  }
491 
492  if (report)
493  report->inc_counts(rep);
494 
495  return std::unique_ptr<IterationConfig>(icp);
496  }
497 
498  std::unique_ptr<IterationConfig> ConfigJson::load_File(const std::string &fname) {
499  std::ifstream ifs;
500  open_ifstream(ifs, fname, __func__);
501 
502  if (m_verbose) {
503  printf("%s begin reading from file %s.\n", __func__, fname.c_str());
504  }
505 
506  if (!skipws_ifstream(ifs))
507  throw std::runtime_error("empty file");
508 
510  ifs >> j;
511 
512  if (m_verbose) {
513  std::cout << " Read JSON entity, iteration index is " << j["m_iteration_index"] << ", track algorithm is "
514  << j["m_track_algorithm"] << ". Instantiating IterationConfig object and over-laying it with JSON.\n";
515  }
516 
517  IterationConfig *icp = new IterationConfig();
518 
519  from_json(j, *icp);
520 
521  return std::unique_ptr<IterationConfig>(icp);
522  }
523 
524  // ============================================================================
525  // Save each IterationConfig into a separate json file
526  // ============================================================================
527 
529  const std::string &fname_fmt,
530  bool include_iter_info_preamble) {
531  bool has_pct_d = fname_fmt.find("%d") != std::string::npos;
532  bool has_pct_s = fname_fmt.find("%s") != std::string::npos;
533 
534  assert((has_pct_d || has_pct_s) && "JSON save filename-format must include a %d or %s substring");
535  assert(!(has_pct_d && has_pct_s) && "JSON save filename-format must include only one of %d or %s substrings");
536 
537  for (int ii = 0; ii < its_info.size(); ++ii) {
538  const IterationConfig &itconf = its_info[ii];
539 
540  char fname[1024];
541  if (has_pct_d)
542  snprintf(fname, 1024, fname_fmt.c_str(), ii);
543  else
544  snprintf(fname, 1024, fname_fmt.c_str(), TrackBase::algoint_to_cstr(itconf.m_track_algorithm));
545 
546  std::ofstream ofs;
547  open_ofstream(ofs, fname, __func__);
548 
549  if (include_iter_info_preamble) {
550  ofs << "{ \"m_iterations/" << ii << "\": ";
551  }
552 
553  nlohmann::ordered_json j;
554  to_json(j, itconf);
555 
556  ofs << std::setw(1);
557  ofs << j;
558 
559  if (include_iter_info_preamble) {
560  ofs << " }";
561  }
562 
563  ofs << "\n";
564  ofs.close();
565  }
566  }
567 
569  nlohmann::ordered_json j = its_info;
570  std::cout << j.dump(3) << "\n";
571  }
572 
573  // ============================================================================
574  // Tests for ConfigJson stuff
575  // ============================================================================
576 
578  using nlohmann::json;
579 
580  std::string lojz("/m_select_max_dphi");
581 
582  json j = it_cfg;
583  std::cout << j.dump(1) << "\n";
584 
585  std::cout << "Layer 43, m_select_max_dphi = " << j["/m_layer_configs/43/m_select_max_dphi"_json_pointer] << "\n";
586  std::cout << "Patching it to pi ...\n";
587  json p = R"([
588  { "op": "replace", "path": "/m_layer_configs/43/m_select_max_dphi", "value": 3.141 }
589  ])"_json;
590  j = j.patch(p);
591  std::cout << "Layer 43, m_select_max_dphi = " << j["/m_layer_configs/43/m_select_max_dphi"_json_pointer] << "\n";
592 
593  auto &jx = j["/m_layer_configs/60"_json_pointer];
594  // jx["m_select_max_dphi"] = 99.876;
595  json::json_pointer jp(lojz);
596  jx[jp] = 99.876;
597 
598  // try loading it back, see what happens to vector m_layer_configs.
599 
600  from_json(j, it_cfg);
601  printf("Layer 43 : m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
602  it_cfg.m_layer_configs[43].m_select_max_dphi,
603  (int)it_cfg.m_layer_configs.size(),
604  it_cfg.m_n_regions,
605  (int)it_cfg.m_steering_params.size());
606 
607  printf("Layer 60 : m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
608  it_cfg.m_layer_configs[60].m_select_max_dphi,
609  (int)it_cfg.m_layer_configs.size(),
610  it_cfg.m_n_regions,
611  (int)it_cfg.m_steering_params.size());
612 
613  // try accessing something that does not exist
614 
615  // std::cout << "Non-existent path " << j["/m_layer_configs/143/m_select_max_dphi"_json_pointer] << "\n";
616 
617  auto &x = j["/m_layer_configs"_json_pointer];
618  std::cout << "Typename /m_layer_configs " << x.type_name() << "\n";
619  auto &y = j["/m_layer_configs/143"_json_pointer];
620  std::cout << "Typename /m_layer_configs/143 " << y.type_name() << ", is_null=" << y.is_null() << "\n";
621  }
622 
624  ConfigJsonPatcher cjp;
625  cjp.load(it_cfg);
626 
627  std::cout << cjp.dump(1) << "\n";
628 
629  {
630  cjp.cd("/m_layer_configs/43/m_select_max_dphi");
631  std::cout << "Layer 43, m_select_max_dphi = " << cjp.get("") << "\n";
632  std::cout << "Setting it to pi ...\n";
633  cjp.replace("", 3.141);
634  cjp.cd_top();
635  std::cout << "Layer 43, m_select_max_dphi = " << cjp.get("/m_layer_configs/43/m_select_max_dphi") << "\n";
636  }
637  {
638  std::cout << "Replacing layer 60 m_select_max_dphi with full path\n";
639  cjp.replace("/m_layer_configs/60/m_select_max_dphi", 99.876);
640  }
641  try {
642  std::cout << "Trying to replace an non-existent array entry\n";
643  cjp.replace("/m_layer_configs/1460/m_select_max_dphi", 666.666);
644  } catch (std::exception &exc) {
645  std::cout << "Caugth exception: " << exc.what() << "\n";
646  }
647  try {
648  std::cout << "Trying to replace an non-existent object entry\n";
649  cjp.replace("/m_layer_configs/1/moo_select_max_dphi", 666.666);
650  } catch (std::exception &exc) {
651  std::cout << "Caugth exception: " << exc.what() << "\n";
652  }
653  {
654  std::cout << "Replacing m_select_max_dphi on layers 1 to 3 to 7.7\n";
655  cjp.cd("/m_layer_configs");
656  cjp.replace(1, 3, "/m_select_max_dphi", 7.7);
657  cjp.cd_top();
658  }
659 
660  // try getting it back into c++, see what happens to vector m_layer_configs.
661 
662  cjp.save(it_cfg);
663 
664  printf("Layer 43: m_select_max_dphi = %f, size_of_layer_vec=%d, m_n_regions=%d, size_of_steering_params=%d\n",
665  it_cfg.m_layer_configs[43].m_select_max_dphi,
666  (int)it_cfg.m_layer_configs.size(),
667  it_cfg.m_n_regions,
668  (int)it_cfg.m_steering_params.size());
669 
670  printf("Layer 60: m_select_max_dphi = %f\n", it_cfg.m_layer_configs[60].m_select_max_dphi);
671  for (int i = 0; i < 5; ++i)
672  printf("Layer %2d: m_select_max_dphi = %f\n", i, it_cfg.m_layer_configs[i].m_select_max_dphi);
673 
674  // try accessing something that does not exist
675 
676  // std::cout << "Non-existent path " << j["/m_layer_configs/143/m_select_max_dphi"_json_pointer] << "\n";
677 
678  auto &j = cjp.get("");
679 
680  auto &x = j["/m_layer_configs"_json_pointer];
681  std::cout << "Typename /m_layer_configs " << x.type_name() << "\n";
682  auto &y = j["/m_layer_configs/143"_json_pointer];
683  std::cout << "Typename /m_layer_configs/143 " << y.type_name() << ", is_null=" << y.is_null() << "\n";
684  }
685 
686 } // namespace mkfit
nlohmann::json * m_current
nlohmann::json json
bool verbose
void to_json(nlohmann::json &nlohmann_json_j, const mkfit::LayerControl &nlohmann_json_t)
std::string to_string(const V &value)
Definition: OMSAccess.h:71
std::string dump(int indent=2)
assert(be >=bs)
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
std::vector< IterationLayerConfig > m_layer_configs
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)
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
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
void cd_top(const std::string &path="")
long double T
std::vector< SteeringParams > m_steering_params
std::string get_abs_path() const