gen_reaction_info.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  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_reaction_info.h"
  15. #include "api/reaction_info.h"
  16. #include "api/geometry_object.h"
  17. #include "api/reaction_rule.h"
  18. namespace MCell {
  19. namespace API {
  20. std::shared_ptr<ReactionInfo> GenReactionInfo::copy_reaction_info() const {
  21. std::shared_ptr<ReactionInfo> res = std::make_shared<ReactionInfo>(DefaultCtorArgType());
  22. res->type = type;
  23. res->reactant_ids = reactant_ids;
  24. res->product_ids = product_ids;
  25. res->reaction_rule = reaction_rule;
  26. res->time = time;
  27. res->pos3d = pos3d;
  28. res->geometry_object = geometry_object;
  29. res->wall_index = wall_index;
  30. res->pos2d = pos2d;
  31. return res;
  32. }
  33. std::shared_ptr<ReactionInfo> GenReactionInfo::deepcopy_reaction_info(py::dict) const {
  34. std::shared_ptr<ReactionInfo> res = std::make_shared<ReactionInfo>(DefaultCtorArgType());
  35. res->type = type;
  36. res->reactant_ids = reactant_ids;
  37. res->product_ids = product_ids;
  38. res->reaction_rule = is_set(reaction_rule) ? reaction_rule->deepcopy_reaction_rule() : nullptr;
  39. res->time = time;
  40. res->pos3d = pos3d;
  41. res->geometry_object = is_set(geometry_object) ? geometry_object->deepcopy_geometry_object() : nullptr;
  42. res->wall_index = wall_index;
  43. res->pos2d = pos2d;
  44. return res;
  45. }
  46. bool GenReactionInfo::__eq__(const ReactionInfo& other) const {
  47. return
  48. type == other.type &&
  49. reactant_ids == other.reactant_ids &&
  50. product_ids == other.product_ids &&
  51. (
  52. (is_set(reaction_rule)) ?
  53. (is_set(other.reaction_rule) ?
  54. (reaction_rule->__eq__(*other.reaction_rule)) :
  55. false
  56. ) :
  57. (is_set(other.reaction_rule) ?
  58. false :
  59. true
  60. )
  61. ) &&
  62. time == other.time &&
  63. pos3d == other.pos3d &&
  64. (
  65. (is_set(geometry_object)) ?
  66. (is_set(other.geometry_object) ?
  67. (geometry_object->__eq__(*other.geometry_object)) :
  68. false
  69. ) :
  70. (is_set(other.geometry_object) ?
  71. false :
  72. true
  73. )
  74. ) &&
  75. wall_index == other.wall_index &&
  76. pos2d == other.pos2d;
  77. }
  78. bool GenReactionInfo::eq_nonarray_attributes(const ReactionInfo& other, const bool ignore_name) const {
  79. return
  80. type == other.type &&
  81. true /*reactant_ids*/ &&
  82. true /*product_ids*/ &&
  83. (
  84. (is_set(reaction_rule)) ?
  85. (is_set(other.reaction_rule) ?
  86. (reaction_rule->__eq__(*other.reaction_rule)) :
  87. false
  88. ) :
  89. (is_set(other.reaction_rule) ?
  90. false :
  91. true
  92. )
  93. ) &&
  94. time == other.time &&
  95. true /*pos3d*/ &&
  96. (
  97. (is_set(geometry_object)) ?
  98. (is_set(other.geometry_object) ?
  99. (geometry_object->__eq__(*other.geometry_object)) :
  100. false
  101. ) :
  102. (is_set(other.geometry_object) ?
  103. false :
  104. true
  105. )
  106. ) &&
  107. wall_index == other.wall_index &&
  108. true /*pos2d*/;
  109. }
  110. std::string GenReactionInfo::to_str(const bool all_details, const std::string ind) const {
  111. std::stringstream ss;
  112. ss << "ReactionInfo" << ": " <<
  113. "type=" << type << ", " <<
  114. "reactant_ids=" << vec_nonptr_to_str(reactant_ids, all_details, ind + " ") << ", " <<
  115. "product_ids=" << vec_nonptr_to_str(product_ids, all_details, ind + " ") << ", " <<
  116. "\n" << ind + " " << "reaction_rule=" << "(" << ((reaction_rule != nullptr) ? reaction_rule->to_str(all_details, ind + " ") : "null" ) << ")" << ", " << "\n" << ind + " " <<
  117. "time=" << time << ", " <<
  118. "pos3d=" << vec_nonptr_to_str(pos3d, all_details, ind + " ") << ", " <<
  119. "\n" << ind + " " << "geometry_object=" << "(" << ((geometry_object != nullptr) ? geometry_object->to_str(all_details, ind + " ") : "null" ) << ")" << ", " << "\n" << ind + " " <<
  120. "wall_index=" << wall_index << ", " <<
  121. "pos2d=" << vec_nonptr_to_str(pos2d, all_details, ind + " ");
  122. return ss.str();
  123. }
  124. py::class_<ReactionInfo> define_pybinding_ReactionInfo(py::module& m) {
  125. return py::class_<ReactionInfo, std::shared_ptr<ReactionInfo>>(m, "ReactionInfo", "Data structure passed to a reaction callback registered with \nModel.register_reaction_callback.\n")
  126. .def(
  127. py::init<
  128. >()
  129. )
  130. .def("__copy__", &ReactionInfo::copy_reaction_info)
  131. .def("__deepcopy__", &ReactionInfo::deepcopy_reaction_info, py::arg("memo"))
  132. .def("__str__", &ReactionInfo::to_str, py::arg("all_details") = false, py::arg("ind") = std::string(""))
  133. .def("__eq__", &ReactionInfo::__eq__, py::arg("other"))
  134. .def("dump", &ReactionInfo::dump)
  135. .def_property("type", &ReactionInfo::get_type, &ReactionInfo::set_type, "Specifies whether the reaction is unimolecular or bimolecular and\nalso provides information on reactant types. \n")
  136. .def_property("reactant_ids", &ReactionInfo::get_reactant_ids, &ReactionInfo::set_reactant_ids, py::return_value_policy::reference, "IDs of the reacting molecules, contains 1 ID for a unimolecular or a molecule+surface class reaction, \n2 IDs for a bimolecular reaction.\nFor a bimolecular reaction, the first ID is always the molecule that diffused and the second one \nis the molecule that was hit.\nIDs can be used to obtain the location of the molecules. The position of the first molecule obtained through \nmodel.get_molecule() is the position of the diffusing molecule before the collision.\nAll the reactants are removed after return from this callback, unless they are kept by the reaction such as A in A + B -> A + C. \n")
  137. .def_property("product_ids", &ReactionInfo::get_product_ids, &ReactionInfo::set_product_ids, py::return_value_policy::reference, "IDs of reaction product molecules. They already exist in the simulated system together with reactants; however reactants \nwill be removed after return from this callback. \n")
  138. .def_property("reaction_rule", &ReactionInfo::get_reaction_rule, &ReactionInfo::set_reaction_rule, "Reaction rule of the reaction that occured.")
  139. .def_property("time", &ReactionInfo::get_time, &ReactionInfo::set_time, "Time of the reaction.")
  140. .def_property("pos3d", &ReactionInfo::get_pos3d, &ReactionInfo::set_pos3d, py::return_value_policy::reference, "Specifies where reaction occurred in the 3d space, the specific meaning depends on the reaction type:\n- unimolecular reaction - position of the reacting molecule,\n- volume-volume or surface-surface reaction - position of the first reactant,\n- volume-surface reaction - position where the volume molecule hit the wall with the surface molecule.\n")
  141. .def_property("geometry_object", &ReactionInfo::get_geometry_object, &ReactionInfo::set_geometry_object, "The object on whose surface where the reaction occurred.\nSet only for surface reactions or reactions with surface classes.\n")
  142. .def_property("wall_index", &ReactionInfo::get_wall_index, &ReactionInfo::set_wall_index, "Set only for surface reactions or reactions with surface classes.\nIndex of wall belonging to the geometry_object where the reaction occured, \ni.e. wall where a volume molecule hit the surface molecule or\nwall where the diffusing surface reactant reacted.\n")
  143. .def_property("pos2d", &ReactionInfo::get_pos2d, &ReactionInfo::set_pos2d, py::return_value_policy::reference, "Set only for surface reactions or reactions with surface classes.\nSpecifies where reaction occurred in the 2d UV coordinates defined by the wall where the reaction occured, \nthe rspecific meaning depends on the reaction type:\n- unimolecular reaction - position of the reacting molecule,\n- volume-surface and surface-surface reaction - position of the second reactant.\n \n ")
  144. ;
  145. }
  146. } // namespace API
  147. } // namespace MCell