callbacks.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. /******************************************************************************
  2. *
  3. * Copyright (C) 2020-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. #ifndef LIBMCELL_API_CALLBACKS_H_
  12. #define LIBMCELL_API_CALLBACKS_H_
  13. #include <functional>
  14. #ifdef _WIN64
  15. // fix for _hypot compilation issue
  16. #define _hypot hypot
  17. #include <cmath>
  18. #endif
  19. #ifdef _MSC_VER
  20. #undef HAVE_UNISTD_H
  21. #undef HAVE_SYS_TIME_H
  22. #endif
  23. #include "pybind11/include/pybind11/pybind11.h"
  24. #include "api/api_common.h"
  25. #include "defines.h"
  26. #include "bng/bng_defines.h"
  27. namespace MCell {
  28. namespace API {
  29. class Model;
  30. class MolWallHitInfo;
  31. class ReactionInfo;
  32. typedef std::function<void(std::shared_ptr<API::MolWallHitInfo>, pybind11::object)>
  33. mol_wall_hit_callback_function_t;
  34. typedef std::function<bool(std::shared_ptr<API::ReactionInfo>, pybind11::object)>
  35. rxn_callback_function_t;
  36. struct RxnCallbackInfo {
  37. RxnCallbackInfo() :
  38. callback_function(nullptr),
  39. rxn_rule_id(BNG::RXN_RULE_ID_INVALID) {
  40. }
  41. RxnCallbackInfo(
  42. const rxn_callback_function_t callback_function_,
  43. const py::object context_,
  44. const BNG::rxn_rule_id_t rxn_rule_id_) :
  45. callback_function(callback_function_),
  46. context(context_),
  47. rxn_rule_id(rxn_rule_id_) {
  48. }
  49. rxn_callback_function_t callback_function;
  50. py::object context;
  51. BNG::rxn_rule_id_t rxn_rule_id;
  52. };
  53. struct MolWallHitCallbackInfo {
  54. MolWallHitCallbackInfo() :
  55. callback_function(nullptr),
  56. geometry_object_id(GEOMETRY_OBJECT_ID_INVALID),
  57. species_id(BNG::SPECIES_ID_INVALID) {
  58. }
  59. MolWallHitCallbackInfo(
  60. const mol_wall_hit_callback_function_t callback_function_,
  61. const py::object context_,
  62. const geometry_object_id_t geometry_object_id_,
  63. const BNG::species_id_t species_id_) :
  64. callback_function(callback_function_),
  65. context(context_),
  66. geometry_object_id(geometry_object_id_),
  67. species_id(species_id_) {
  68. }
  69. mol_wall_hit_callback_function_t callback_function;
  70. py::object context;
  71. geometry_object_id_t geometry_object_id; // GEOMETRY_OBJECT_ID_INVALID - any object may be hit
  72. species_id_t species_id; // SPECIES_ID_INVALID - any species may be hit
  73. };
  74. // not generated
  75. class Callbacks {
  76. public:
  77. // model_ is nullptr in MDL mode
  78. Callbacks(Model* model_);
  79. Model* model;
  80. // -------------------- mol-wall hit callbacks --------------------
  81. void register_mol_wall_hit_callback(
  82. const mol_wall_hit_callback_function_t func,
  83. py::object context,
  84. const geometry_object_id_t geometry_object_id,
  85. const species_id_t species_id);
  86. bool needs_callback_for_mol_wall_hit(
  87. const geometry_object_id_t geometry_object_id,
  88. const species_id_t species_id) const {
  89. if (mol_wall_hit_callbacks.empty()) {
  90. return false;
  91. }
  92. auto it_specific_geom_obj = mol_wall_hit_callbacks.find(geometry_object_id);
  93. if (it_specific_geom_obj != mol_wall_hit_callbacks.end() &&
  94. needs_callback_for_mol_wall_hit(it_specific_geom_obj->second, species_id)) {
  95. return true;
  96. }
  97. auto it_any_geom_obj = mol_wall_hit_callbacks.find(GEOMETRY_OBJECT_ID_INVALID);
  98. if (it_any_geom_obj != mol_wall_hit_callbacks.end() &&
  99. needs_callback_for_mol_wall_hit(it_any_geom_obj->second, species_id)) {
  100. return true;
  101. }
  102. // no match
  103. return false;
  104. }
  105. void do_mol_wall_hit_callbacks(std::shared_ptr<MolWallHitInfo> info);
  106. // -------------------- reaction callbacks --------------------
  107. void register_rxn_callback(
  108. const rxn_callback_function_t func,
  109. py::object context,
  110. const BNG::rxn_rule_id_t rxn_rule_id
  111. );
  112. bool needs_rxn_callback(
  113. const BNG::rxn_rule_id_t rxn_rule_id) const {
  114. if (rxn_callbacks.empty()) {
  115. return false;
  116. }
  117. else {
  118. return rxn_callbacks.count(rxn_rule_id) != 0;
  119. }
  120. }
  121. // returns true if reaction should be cancelled
  122. bool do_rxn_callback(std::shared_ptr<ReactionInfo> info);
  123. private:
  124. std::map<BNG::rxn_rule_id_t, RxnCallbackInfo> rxn_callbacks;
  125. typedef std::map<BNG::species_id_t, MolWallHitCallbackInfo> SpeciesMolWallHitCallbackInfoMap;
  126. std::map<geometry_object_id_t, SpeciesMolWallHitCallbackInfoMap> mol_wall_hit_callbacks;
  127. bool needs_callback_for_mol_wall_hit(
  128. const SpeciesMolWallHitCallbackInfoMap& species_info_map,
  129. const BNG::species_id_t species_id) const {
  130. if (species_info_map.count(species_id) != 0) {
  131. return true;
  132. }
  133. if (species_info_map.count(BNG::SPECIES_ID_INVALID) != 0) {
  134. return true;
  135. }
  136. return false;
  137. }
  138. void do_mol_wall_hit_callback_for_specific_and_any_species(
  139. std::shared_ptr<MolWallHitInfo> info,
  140. const BNG::species_id_t specific_species_id,
  141. const SpeciesMolWallHitCallbackInfoMap& species_map);
  142. void do_individual_mol_wall_hit_callback(
  143. std::shared_ptr<MolWallHitInfo> info, MolWallHitCallbackInfo callback_function_and_context);
  144. };
  145. } /* namespace API */
  146. } /* namespace MCell */
  147. #endif /* LIBMCELL_API_CALLBACKS_H_ */