api_common.h 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  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. #ifndef LIBMCELL_API_COMMON_H
  12. #define LIBMCELL_API_COMMON_H
  13. #ifdef _MSC_VER
  14. #undef HAVE_UNISTD_H
  15. #undef HAVE_SYS_TIME_H
  16. #endif
  17. #ifdef _WIN64
  18. // fix for _hypot compilation issue
  19. #define _hypot hypot
  20. #include <cmath>
  21. #endif
  22. #include "pybind11/include/pybind11/pybind11.h" // make sure we won't include the system header
  23. #include "pybind11/include/pybind11/functional.h"
  24. #include "pybind11/include/pybind11/stl_bind.h"
  25. namespace py = pybind11;
  26. // must be included before any usage of std::vector in API
  27. #include "generated/gen_vectors_make_opaque.h"
  28. #include <ostream>
  29. #include <sstream>
  30. #include <exception>
  31. #include <string>
  32. #include <memory>
  33. #include <functional>
  34. namespace MCell {
  35. namespace API {
  36. // workaround for weird MSVC behavior, this has to be defined first before anything else is included
  37. // TODO: can we move this below?
  38. // auxiliary method to simply convert to std::string for when concatenating string
  39. static std::string S(const char* s) {
  40. return std::string(s);
  41. }
  42. const std::string STR_UNSET = "unset";
  43. // Raised when an operation or function receives an argument that has the
  44. // right type but an inappropriate value, and the situation is not described
  45. // by a more precise exception such as IndexError.
  46. typedef std::invalid_argument ValueError; // using naming from Python
  47. // Raised when an error is detected that doesn’t fall in any of the other categories.
  48. // The associated value is a string indicating what precisely went wrong.
  49. typedef std::logic_error RuntimeError; // e.g. not defined?
  50. // forward declarations for PYBIND11_MAKE_OPAQUE
  51. class Component;
  52. }
  53. }
  54. #include "defines.h"
  55. #include "generated/gen_constants.h"
  56. #include "generated/gen_names.h"
  57. namespace MCell {
  58. namespace API {
  59. class Species;
  60. typedef std::map<species_id_t, std::shared_ptr<Species>> IdSpeciesMap;
  61. class GeometryObject;
  62. typedef std::map<geometry_object_id_t, std::shared_ptr<GeometryObject>> IdGeometryObjectMap;
  63. const Vec3 VEC3_UNSET(POS_INVALID);
  64. const Vec2 VEC2_UNSET(POS_INVALID);
  65. const void* const PTR_UNSET = nullptr;
  66. const std::string INTROSPECTED_OBJECT = "introspected object";
  67. // specialization for each type
  68. static inline bool is_set(const double a) {
  69. return a != FLT_UNSET;
  70. }
  71. static inline bool is_set(const int a) {
  72. return a != INT_UNSET;
  73. }
  74. static inline bool is_set(const uint64_t a) {
  75. return true; // all values are valid
  76. }
  77. static inline bool is_set(const Vec3& a) {
  78. return a != VEC3_UNSET;
  79. }
  80. static inline bool is_set(const Vec2& a) {
  81. return a != VEC2_UNSET;
  82. }
  83. static inline bool is_set(const void* a) {
  84. return a != PTR_UNSET;
  85. }
  86. static inline bool is_set(const std::string& a) {
  87. return a != STR_UNSET && a != "";
  88. }
  89. static inline bool is_set(const Orientation& a) {
  90. return a != Orientation::NOT_SET;
  91. }
  92. static inline bool is_set(const SurfacePropertyType& a) {
  93. return a != SurfacePropertyType::UNSET;
  94. }
  95. template<typename T>
  96. static inline bool is_set(const std::shared_ptr<T>& a) {
  97. return a.use_count() != 0;
  98. }
  99. template<typename T>
  100. static inline bool is_set(const std::vector<T>& a) {
  101. return !a.empty();
  102. }
  103. template<typename T1, typename T2>
  104. int get_num_set(const T1& v1, const T2& v2) {
  105. int res = 0;
  106. if (is_set(v1)) {
  107. res++;
  108. }
  109. if (is_set(v2)) {
  110. res++;
  111. }
  112. return res;
  113. }
  114. template<typename T1, typename T2, typename T3>
  115. uint get_num_set(const T1& v1, const T2& v2, const T3& v3) {
  116. int res = get_num_set(v1, v2);
  117. if (is_set(v3)) {
  118. res++;
  119. }
  120. return res;
  121. }
  122. template<typename T1, typename T2, typename T3, typename T4>
  123. uint get_num_set(const T1& v1, const T2& v2, const T3& v3, const T4& v4) {
  124. int res = get_num_set(v1, v2, v3);
  125. if (is_set(v4)) {
  126. res++;
  127. }
  128. return res;
  129. }
  130. template<typename T1, typename T2, typename T3, typename T4, typename T5>
  131. uint get_num_set(const T1& v1, const T2& v2, const T3& v3, const T4& v4, const T5& v5) {
  132. int res = get_num_set(v1, v2, v3, v4);
  133. if (is_set(v5)) {
  134. res++;
  135. }
  136. return res;
  137. }
  138. // NOTE: for some reason a definition in defines.h is not found, although it works fine for Vec3
  139. static inline std::ostream & operator<<(std::ostream &out, const IVec3& a) {
  140. out << "(" << a.x << ", " << a.y << ", " << a.z << ")";
  141. return out;
  142. }
  143. template<typename T>
  144. static inline std::string vec_ptr_to_str(
  145. const std::vector<T>& arr, const bool all_details=false, const std::string ind="") {
  146. std::stringstream ss;
  147. ss << "[\n";
  148. for (size_t i = 0; i < arr.size(); i++) {
  149. ss << ind << " " << i << ":(" << arr[i]->to_str(all_details, ind) << ")";
  150. if (i + 1 != arr.size()) {
  151. ss << ", ";
  152. }
  153. ss << "\n";
  154. }
  155. ss << ind << "]";
  156. return ss.str();
  157. }
  158. template<typename T>
  159. static inline std::string vec_nonptr_to_str(
  160. const std::vector<T>& arr, const bool all_details=false, const std::string ind="") {
  161. std::stringstream ss;
  162. ss << "[";
  163. for (size_t i = 0; i < arr.size(); i++) {
  164. ss << i << ":" << arr[i];
  165. if (i + 1 != arr.size()) {
  166. ss << ", ";
  167. }
  168. }
  169. ss << "]";
  170. return ss.str();
  171. }
  172. template<typename T>
  173. static inline std::string vec_nonptr_to_str(
  174. const std::vector<std::vector<T>>& arr, const bool all_details=false, const std::string ind="") {
  175. std::stringstream ss;
  176. ss << "[";
  177. for (size_t i = 0; i < arr.size(); i++) {
  178. ss << i << ":" << vec_nonptr_to_str(arr[i], all_details, ind + " ");
  179. if (i + 1 != arr.size()) {
  180. ss << ", ";
  181. }
  182. }
  183. ss << "]";
  184. return ss.str();
  185. }
  186. template<typename T>
  187. static inline bool vec_ptr_eq(const std::vector<std::shared_ptr<T>>& vec1, const std::vector<std::shared_ptr<T>>& vec2) {
  188. if (vec1.size() != vec2.size()) {
  189. return false;
  190. }
  191. for (size_t i = 0; i < vec1.size(); i++) {
  192. if (!vec1[i]->__eq__(*vec2[i])) {
  193. return false;
  194. }
  195. }
  196. return true;
  197. }
  198. template<typename T>
  199. static inline void vec_set_initialized(const std::vector<std::shared_ptr<T>>& vec) {
  200. for (const std::shared_ptr<T>& item: vec) {
  201. item->set_initialized();
  202. }
  203. }
  204. // find item with name in a vector, returns shared null if not found
  205. template<typename T>
  206. static inline std::shared_ptr<T> vec_find_by_name(
  207. const std::vector<std::shared_ptr<T>>& vec, const std::string& name) {
  208. for (auto& item: vec) {
  209. if (item->name == name) {
  210. return item;
  211. }
  212. }
  213. return std::shared_ptr<T>(nullptr);
  214. }
  215. // we need to distinguish generated ctors that have all default arguments
  216. // such as Count(...) from internal default ctors required e.g. for object copy,
  217. // for this reason we introduce this special type
  218. struct DefaultCtorArgType {
  219. DefaultCtorArgType() :
  220. unused(0) {
  221. }
  222. int unused;
  223. };
  224. } // namespace API
  225. } // namespace MCell
  226. #endif // LIBMCELL_API_COMMON_H