bindings.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2020 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 "mcell.h"
  12. #include "generated/gen_component_type.h"
  13. #include "generated/gen_component.h"
  14. #include "generated/gen_elementary_molecule_type.h"
  15. #include "generated/gen_elementary_molecule.h"
  16. #include "generated/gen_species.h"
  17. #include "generated/gen_surface_class.h"
  18. #include "generated/gen_reaction_rule.h"
  19. #include "generated/gen_subsystem.h"
  20. #include "generated/gen_color.h"
  21. #include "generated/gen_region.h"
  22. #include "generated/gen_initial_surface_release.h"
  23. #include "generated/gen_surface_region.h"
  24. #include "generated/gen_geometry_object.h"
  25. #include "generated/gen_release_pattern.h"
  26. #include "generated/gen_molecule_release_info.h"
  27. #include "generated/gen_release_site.h"
  28. #include "generated/gen_instantiation.h"
  29. #include "generated/gen_count_term.h"
  30. #include "generated/gen_count.h"
  31. #include "generated/gen_viz_output.h"
  32. #include "generated/gen_observables.h"
  33. #include "generated/gen_config.h"
  34. #include "generated/gen_notifications.h"
  35. #include "generated/gen_warnings.h"
  36. #include "generated/gen_model.h"
  37. #include "generated/gen_region.h"
  38. #include "generated/gen_molecule.h"
  39. #include "generated/gen_wall.h"
  40. #include "generated/gen_introspection.h"
  41. #include "generated/gen_mol_wall_hit_info.h"
  42. #include "generated/gen_wall_wall_hit_info.h"
  43. #include "generated/gen_reaction_info.h"
  44. #include "generated/gen_chkpt_vol_mol.h"
  45. #include "generated/gen_chkpt_surf_mol.h"
  46. #include "generated/gen_rng_state.h"
  47. #include "generated/gen_bngl_utils.h"
  48. #include "generated/gen_geometry_utils.h"
  49. #include "generated/gen_run_utils.h"
  50. #include "generated/gen_data_utils.h"
  51. #include "generated/gen_constants.h"
  52. #include "world.h"
  53. #include "version.h"
  54. #if __cplusplus < 201402L && !defined(_MSC_VER)
  55. #error "Pybind11 overload requires at least C++14"
  56. #endif
  57. #ifndef PYBIND11_OVERLOAD_CAST
  58. #error "PYBIND11_OVERLOAD_CAST must be defined"
  59. #endif
  60. #include "pybind11_stl_include.h"
  61. namespace MCell {
  62. namespace API {
  63. // defined in gen_vectors_bind.cpp
  64. void gen_vectors_bind(py::module& m);
  65. void define_pybinding_Vec3(py::module& m) {
  66. py::class_<MCell::Vec3>(m, "Vec3")
  67. .def(
  68. py::init<>()
  69. )
  70. .def(
  71. py::init<const double>(),
  72. py::arg("xyz")
  73. )
  74. .def(
  75. py::init<const double, const double, const double>(),
  76. py::arg("x"), py::arg("y"), py::arg("z")
  77. )
  78. .def("__add__", [](const Vec3& a, const Vec3& b) { return Vec3(a + b); } )
  79. .def("__sub__", [](const Vec3& a, const Vec3& b) { return Vec3(a - b); } )
  80. .def("__mul__", [](const Vec3& a, const Vec3& b) { return Vec3(a * b); } )
  81. .def("__truediv__", [](const Vec3& a, const Vec3& b) { return Vec3(a / b); } )
  82. .def("__eq__", [](const Vec3& a, const Vec3& b) { return a == b; } )
  83. .def("__str__", [](const Vec3& a)
  84. { return "(" + std::to_string(a.x) + ", " + std::to_string(a.y) + ", " + std::to_string(a.z) + ")"; } )
  85. .def("__repr__", [](const Vec3& a)
  86. { return "(" + std::to_string(a.x) + ", " + std::to_string(a.y) + ", " + std::to_string(a.z) + ")"; } )
  87. .def("to_list", [](const Vec3& a) { return py::cast(std::vector<double>{a.x, a.y, a.z}); } )
  88. .def_readwrite("x", &Vec3::x)
  89. .def_readwrite("y", &Vec3::y)
  90. .def_readwrite("z", &Vec3::z)
  91. ;
  92. }
  93. void define_pybinding_Vec2(py::module& m) {
  94. py::class_<MCell::Vec2>(m, "Vec2")
  95. .def(
  96. py::init<>()
  97. )
  98. .def(
  99. py::init<const double>(),
  100. py::arg("xy")
  101. )
  102. .def(
  103. py::init<const double, const double>(),
  104. py::arg("x"), py::arg("y")
  105. )
  106. .def("__add__", [](const Vec2& a, const Vec2& b) { return Vec2(a + b); } )
  107. .def("__sub__", [](const Vec2& a, const Vec2& b) { return Vec2(a - b); } )
  108. .def("__mul__", [](const Vec2& a, const Vec2& b) { return Vec2(a * b); } )
  109. .def("__truediv__", [](const Vec2& a, const Vec2& b) { return Vec2(a / b); } )
  110. .def("__eq__", [](const Vec2& a, const Vec2& b) { return a == b; } )
  111. .def("__str__", [](const Vec2& a)
  112. { return "(" + std::to_string(a.x) + ", " + std::to_string(a.y) + ")"; } )
  113. .def("__repr__", [](const Vec2& a)
  114. { return "(" + std::to_string(a.x) + ", " + std::to_string(a.y) + ")"; } )
  115. .def("to_list", [](const Vec2& a) { return std::vector<double>{a.x, a.y}; } )
  116. .def_readwrite("x", &Vec2::x)
  117. .def_readwrite("y", &Vec2::y)
  118. .def_readwrite("u", &Vec2::u)
  119. .def_readwrite("v", &Vec2::v)
  120. ;
  121. }
  122. void define_pybinding_IVec3(py::module& m) {
  123. py::class_<MCell::IVec3>(m, "IVec3")
  124. .def(
  125. py::init<>()
  126. )
  127. .def(
  128. py::init<const double>(),
  129. py::arg("xyz")
  130. )
  131. .def(
  132. py::init<const int, const int, const int>(),
  133. py::arg("x"), py::arg("y"), py::arg("z")
  134. )
  135. // FIXME: enabling these operator breaks debug build for unknown reason,
  136. // release is build ok, one of tests to reproduce:
  137. // mdl_data_model_pymcell4/tests/mdl/0051_largest_partition_size
  138. // reenable parts of testing in mcell_tests/tests/pymcell4_positive/0050_vec_operators
  139. // once fixed
  140. /*.def(
  141. py::init<const double, const double, const double>(),
  142. py::arg("x"), py::arg("y"), py::arg("z")
  143. )
  144. .def("__add__", [](const IVec3& a, const IVec3& b) { return IVec3(a + b); } )
  145. .def("__sub__", [](const IVec3& a, const IVec3& b) { return IVec3(a - b); } )
  146. .def("__mul__", [](const IVec3& a, const IVec3& b) { return IVec3(a * b); } )
  147. .def("__truediv__", [](const IVec3& a, const IVec3& b) { return IVec3(a / b); } )
  148. .def("__eq__", [](const IVec3& a, const IVec3& b) { return a == b; } )
  149. */
  150. .def_readwrite("x", &IVec3::x)
  151. .def_readwrite("y", &IVec3::y)
  152. .def_readwrite("z", &IVec3::z)
  153. ;
  154. }
  155. // all define_binding_* functions are called here
  156. PYBIND11_MODULE(mcell, m) {
  157. // version
  158. m.attr("__version__") = py::str(MCELL_VERSION);
  159. // bindings of custom vector types
  160. gen_vectors_bind(m);
  161. // some classes use enums, must be defined first
  162. define_pybinding_enums(m);
  163. define_pybinding_Vec3(m);
  164. define_pybinding_Vec2(m);
  165. define_pybinding_IVec3(m);
  166. define_pybinding_ComponentType(m);
  167. define_pybinding_Component(m);
  168. define_pybinding_ElementaryMoleculeType(m);
  169. define_pybinding_ElementaryMolecule(m);
  170. define_pybinding_Complex(m);
  171. define_pybinding_Species(m);
  172. define_pybinding_SurfaceProperty(m);
  173. define_pybinding_SurfaceClass(m);
  174. define_pybinding_ReactionRule(m);
  175. define_pybinding_Subsystem(m);
  176. define_pybinding_ReleasePattern(m);
  177. define_pybinding_MoleculeReleaseInfo(m);
  178. define_pybinding_ReleaseSite(m);
  179. define_pybinding_Color(m);
  180. define_pybinding_Region(m);
  181. define_pybinding_InitialSurfaceRelease(m);
  182. define_pybinding_SurfaceRegion(m);
  183. define_pybinding_GeometryObject(m);
  184. define_pybinding_Instantiation(m);
  185. define_pybinding_CountTerm(m);
  186. define_pybinding_Count(m);
  187. define_pybinding_VizOutput(m);
  188. define_pybinding_Observables(m);
  189. define_pybinding_Config(m);
  190. define_pybinding_Notifications(m);
  191. define_pybinding_Warnings(m);
  192. define_pybinding_Model(m);
  193. define_pybinding_Molecule(m);
  194. define_pybinding_Wall(m);
  195. define_pybinding_WallWallHitInfo(m);
  196. define_pybinding_MolWallHitInfo(m);
  197. define_pybinding_ReactionInfo(m);
  198. define_pybinding_BaseChkptMol(m);
  199. define_pybinding_ChkptVolMol(m);
  200. define_pybinding_ChkptSurfMol(m);
  201. define_pybinding_RngState(m);
  202. // constants may reference existing types, must be "bound" later
  203. define_pybinding_constants(m);
  204. define_pybinding_bngl_utils(m);
  205. define_pybinding_geometry_utils(m);
  206. define_pybinding_run_utils(m);
  207. define_pybinding_data_utils(m);
  208. }
  209. void check_ctrl_c(const double current_time, World* world) {
  210. // make sure to re-acquire lock, PyErr_CheckSignals segfaults otherwise
  211. py::gil_scoped_acquire acquire;
  212. if (PyErr_CheckSignals() != 0) {
  213. std::cout << "Caught Ctrl-C signal in iteration " << current_time << ".\n";
  214. std::cout << "Flushing buffers.\n";
  215. release_assert(world != nullptr);
  216. world->flush_and_close_buffers();
  217. throw py::error_already_set();
  218. }
  219. }
  220. } // API
  221. } // MCell