gen_observables.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2021 by
  4. * The Salk Institute for Biological Studies
  5. *
  6. * Use of this source code is governed by an MIT-style
  7. * license that can be found in the LICENSE file or at
  8. * https://opensource.org/licenses/MIT.
  9. *
  10. ******************************************************************************/
  11. #include <sstream>
  12. #include "api/pybind11_stl_include.h"
  13. #include "api/python_export_utils.h"
  14. #include "gen_observables.h"
  15. #include "api/observables.h"
  16. #include "api/count.h"
  17. #include "api/viz_output.h"
  18. namespace MCell {
  19. namespace API {
  20. std::shared_ptr<Observables> GenObservables::copy_observables() const {
  21. std::shared_ptr<Observables> res = std::make_shared<Observables>(DefaultCtorArgType());
  22. res->viz_outputs = viz_outputs;
  23. res->counts = counts;
  24. return res;
  25. }
  26. std::shared_ptr<Observables> GenObservables::deepcopy_observables(py::dict) const {
  27. std::shared_ptr<Observables> res = std::make_shared<Observables>(DefaultCtorArgType());
  28. for (const auto& item: viz_outputs) {
  29. res->viz_outputs.push_back((is_set(item)) ? item->deepcopy_viz_output() : nullptr);
  30. }
  31. for (const auto& item: counts) {
  32. res->counts.push_back((is_set(item)) ? item->deepcopy_count() : nullptr);
  33. }
  34. return res;
  35. }
  36. bool GenObservables::__eq__(const Observables& other) const {
  37. return
  38. vec_ptr_eq(viz_outputs, other.viz_outputs) &&
  39. vec_ptr_eq(counts, other.counts);
  40. }
  41. bool GenObservables::eq_nonarray_attributes(const Observables& other, const bool ignore_name) const {
  42. return
  43. true /*viz_outputs*/ &&
  44. true /*counts*/;
  45. }
  46. std::string GenObservables::to_str(const bool all_details, const std::string ind) const {
  47. std::stringstream ss;
  48. ss << "Observables" << ": " <<
  49. "\n" << ind + " " << "viz_outputs=" << vec_ptr_to_str(viz_outputs, all_details, ind + " ") << ", " << "\n" << ind + " " <<
  50. "counts=" << vec_ptr_to_str(counts, all_details, ind + " ");
  51. return ss.str();
  52. }
  53. py::class_<Observables> define_pybinding_Observables(py::module& m) {
  54. return py::class_<Observables, std::shared_ptr<Observables>>(m, "Observables", "Container used to hold observables-related model data. \nObservables are the measured values of the system. \nThis class also includes information on visualization of simulation.\n")
  55. .def(
  56. py::init<
  57. const std::vector<std::shared_ptr<VizOutput>>,
  58. const std::vector<std::shared_ptr<Count>>
  59. >(),
  60. py::arg("viz_outputs") = std::vector<std::shared_ptr<VizOutput>>(),
  61. py::arg("counts") = std::vector<std::shared_ptr<Count>>()
  62. )
  63. .def("__copy__", &Observables::copy_observables)
  64. .def("__deepcopy__", &Observables::deepcopy_observables, py::arg("memo"))
  65. .def("__str__", &Observables::to_str, py::arg("all_details") = false, py::arg("ind") = std::string(""))
  66. .def("__eq__", &Observables::__eq__, py::arg("other"))
  67. .def("add_viz_output", &Observables::add_viz_output, py::arg("viz_output"), "Adds a reference to the viz_output object to the list of visualization output specifications.\n- viz_output\n")
  68. .def("add_count", &Observables::add_count, py::arg("count"), "Adds a reference to the count object to the list of count specifications.\n- count\n")
  69. .def("find_count", &Observables::find_count, py::arg("name"), "Finds a count object by its name, returns None if no such count is present.\n- name\n")
  70. .def("load_bngl_observables", &Observables::load_bngl_observables, py::arg("file_name"), py::arg("observables_path_or_file") = STR_UNSET, py::arg("parameter_overrides") = std::map<std::string, double>(), py::arg("observables_output_format") = CountOutputFormat::AUTOMATIC_FROM_EXTENSION, "Loads section observables from a BNGL file and creates Count objects according to it.\nAll elementary molecule types used in the seed species section must be defined in subsystem.\n\n- file_name: Path to the BNGL file.\n\n- observables_path_or_file: Directory prefix or file name where observable values will be stored.\nIf a directory such as './react_data/seed_' + str(SEED).zfill(5) + '/' or an empty \nstring/unset is used, each observable gets its own file and the output file format for created Count \nobjects is CountOutputFormat.DAT.\nWhen not set, this path is used: './react_data/seed_' + str(model.config.seed).zfill(5) + '/'.\nIf a file has a .gdat extension such as \n'./react_data/seed_' + str(SEED).zfill(5) + '/counts.gdat', all observable are stored in this \nfile and the output file format for created Count objects is CountOutputFormat.GDAT.\nMust not be empty when observables_output_format is explicitly set to CountOutputFormat.GDAT.\n\n\n- parameter_overrides: For each key k in the parameter_overrides, if it is defined in the BNGL's parameters section,\nits value is ignored and instead value parameter_overrides[k] is used.\n\n\n- observables_output_format: Selection of output format. Default setting uses automatic detection\nbased on contents of the 'observables_path_or_file' attribute.\n \n\n\n")
  71. .def("dump", &Observables::dump)
  72. .def_property("viz_outputs", &Observables::get_viz_outputs, &Observables::set_viz_outputs, py::return_value_policy::reference, "List of visualization outputs to be included in the model.\nThere is usually just one VizOutput object. \n")
  73. .def_property("counts", &Observables::get_counts, &Observables::set_counts, py::return_value_policy::reference, "List of counts to be included in the model.\n")
  74. ;
  75. }
  76. std::string GenObservables::export_to_python(std::ostream& out, PythonExportContext& ctx) {
  77. std::string exported_name = "observables";
  78. bool str_export = export_as_string_without_newlines();
  79. std::string nl = "";
  80. std::string ind = " ";
  81. std::stringstream ss;
  82. if (!str_export) {
  83. nl = "\n";
  84. ind = " ";
  85. ss << exported_name << " = ";
  86. }
  87. ss << "m.Observables(" << nl;
  88. if (viz_outputs != std::vector<std::shared_ptr<VizOutput>>() && !skip_vectors_export()) {
  89. ss << ind << "viz_outputs = " << export_vec_viz_outputs(out, ctx, exported_name) << "," << nl;
  90. }
  91. if (counts != std::vector<std::shared_ptr<Count>>() && !skip_vectors_export()) {
  92. ss << ind << "counts = " << export_vec_counts(out, ctx, exported_name) << "," << nl;
  93. }
  94. ss << ")" << nl << nl;
  95. if (!str_export) {
  96. out << ss.str();
  97. return exported_name;
  98. }
  99. else {
  100. return ss.str();
  101. }
  102. }
  103. std::string GenObservables::export_vec_viz_outputs(std::ostream& out, PythonExportContext& ctx, const std::string& parent_name) {
  104. // prints vector into 'out' and returns name of the generated list
  105. std::stringstream ss;
  106. std::string exported_name;
  107. if (parent_name != ""){
  108. exported_name = parent_name+ "_viz_outputs";
  109. }
  110. else {
  111. exported_name = "viz_outputs";
  112. }
  113. ss << exported_name << " = [\n";
  114. for (size_t i = 0; i < viz_outputs.size(); i++) {
  115. const auto& item = viz_outputs[i];
  116. if (i == 0) {
  117. ss << " ";
  118. }
  119. else if (i % 16 == 0) {
  120. ss << "\n ";
  121. }
  122. if (!item->skip_python_export()) {
  123. std::string name = item->export_to_python(out, ctx);
  124. ss << name << ", ";
  125. }
  126. }
  127. ss << "\n]\n\n";
  128. out << ss.str();
  129. return exported_name;
  130. }
  131. std::string GenObservables::export_vec_counts(std::ostream& out, PythonExportContext& ctx, const std::string& parent_name) {
  132. // prints vector into 'out' and returns name of the generated list
  133. std::stringstream ss;
  134. std::string exported_name;
  135. if (parent_name != ""){
  136. exported_name = parent_name+ "_counts";
  137. }
  138. else {
  139. exported_name = "counts";
  140. }
  141. ss << exported_name << " = [\n";
  142. for (size_t i = 0; i < counts.size(); i++) {
  143. const auto& item = counts[i];
  144. if (i == 0) {
  145. ss << " ";
  146. }
  147. else if (i % 16 == 0) {
  148. ss << "\n ";
  149. }
  150. if (!item->skip_python_export()) {
  151. std::string name = item->export_to_python(out, ctx);
  152. ss << name << ", ";
  153. }
  154. }
  155. ss << "\n]\n\n";
  156. out << ss.str();
  157. return exported_name;
  158. }
  159. } // namespace API
  160. } // namespace MCell