python_export_utils.h 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  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_PYTHON_EXPORT_UTILS_H_
  12. #define LIBMCELL_API_PYTHON_EXPORT_UTILS_H_
  13. #include <exception>
  14. #include <string>
  15. #include <vector>
  16. #include "defines.h"
  17. #include "api/python_export_constants.h"
  18. #include "json/json.h"
  19. namespace MCell {
  20. namespace API {
  21. class BaseDataClass;
  22. // class used to hold data when exporting objects to Python, e.g. for checkpointing
  23. class PythonExportContext {
  24. public:
  25. bool already_exported(const BaseDataClass* obj) const;
  26. std::string get_exported_name(const BaseDataClass* obj) const;
  27. void add_exported(const BaseDataClass* obj, const std::string& name);
  28. // returns current counter value (starts at 0) and increments counter for the current
  29. // class
  30. uint postinc_counter(const std::string& underscored_class_name);
  31. private:
  32. std::map<const BaseDataClass*, std::string> exported_objects;
  33. std::map<std::string, uint> counters;
  34. };
  35. typedef std::invalid_argument ConversionError;
  36. // replace all characters that cannot be present in an identifier
  37. std::string fix_id(const std::string& str);
  38. std::string get_filename(const std::string& output_files_prefix, const std::string file_suffix, const char* ext);
  39. void open_and_check_file_w_prefix(
  40. const std::string& output_files_prefix, const std::string file_suffix, std::ofstream& out,
  41. const bool for_append = false, const bool bngl = false);
  42. std::string make_id(const std::string& s);
  43. std::string fix_param_id(const std::string& str);
  44. static std::string make_section_comment(const std::string text) {
  45. return BLOCK_BEGIN1 + text + BLOCK_BEGIN2 + "\n";
  46. }
  47. static std::string make_start_block_comment(const std::string text) {
  48. return BLOCK_BEGIN1 + text + BLOCK_BEGIN2;
  49. }
  50. static std::string make_end_block_comment(const std::string text) {
  51. return BLOCK_END1 + text + BLOCK_END2 + "\n";
  52. }
  53. static std::string make_enum_value(const std::string enum_name, const std::string value) {
  54. return MDOT + enum_name + "." + value;
  55. }
  56. static void gen_comma(std::ostream& out, Json::Value::ArrayIndex index, Json::Value& array) {
  57. if (index + 1 != array.size()) {
  58. out << ", ";
  59. }
  60. }
  61. template<typename T>
  62. static void gen_comma(std::ostream& out, size_t index, const std::vector<T>& array) {
  63. if (index + 1 != array.size()) {
  64. out << ", ";
  65. }
  66. }
  67. template<typename T>
  68. void print_comma(std::ostream& out, size_t index, const std::vector<T>& array) {
  69. if (index + 1 != array.size()) {
  70. out << ", ";
  71. }
  72. }
  73. // may return an empty string
  74. std::string get_description(const Json::Value& value);
  75. void gen_description(std::ostream& out, const std::string desc, const std::string ind = "");
  76. void gen_description(std::ostream& out, Json::Value& value, const std::string ind = "");
  77. // name might be empty
  78. void gen_ctor_call(std::ostream& out, std::string name, std::string class_name, bool has_params = true);
  79. static void gen_method_call(
  80. std::ostream& out, std::string obj, std::string method,
  81. std::string param1 = "", std::string param2 = "", std::string param3 = "") {
  82. out << obj << "." << method << "(" << param1;
  83. if (param2 != "" || param3 != "") {
  84. out << ", " << param2;
  85. }
  86. if (param3 != "") {
  87. out << ", " << param3;
  88. }
  89. out << ")\n";
  90. }
  91. template<typename T>
  92. static void gen_param(std::ostream& out, std::string name, T value, bool comma) {
  93. out << IND << name << " = " << value << (comma?",":"") << "\n";
  94. }
  95. template<>
  96. void gen_param(std::ostream& out, std::string name, Json::Value& value, bool comma) {
  97. out << IND << name << " = '" << value.asString() << "'" << (comma?",":"") << "\n";
  98. }
  99. template<>
  100. void gen_param(std::ostream& out, std::string name, std::string value, bool comma) {
  101. out << IND << name << " = '" << value << "'" << (comma?",":"") << "\n";
  102. }
  103. template<>
  104. void gen_param(std::ostream& out, std::string name, const char* const value, bool comma) {
  105. out << IND << name << " = '" << value << "'" << (comma?",":"") << "\n";
  106. }
  107. template<>
  108. void gen_param(std::ostream& out, std::string name, int value, bool comma) {
  109. out << IND << name << " = " << value << (comma?",":"") << "\n";
  110. }
  111. template<>
  112. void gen_param(std::ostream& out, std::string name, double value, bool comma) {
  113. out << IND << name << " = " << value << (comma?",":"") << "\n";
  114. }
  115. template<>
  116. void gen_param(std::ostream& out, std::string name, bool value, bool comma) {
  117. out << IND << name << " = " << (value ? "True" : "False") << (comma?",":"") << "\n";
  118. }
  119. static void gen_param_id(std::ostream& out, std::string name, std::string id, bool comma) {
  120. out << IND << name << " = " << make_id(id) << (comma?",":"") << "\n";
  121. }
  122. static void gen_param_id(std::ostream& out, std::string name, Json::Value& id, bool comma) {
  123. out << IND << name << " = " << make_id(id.asString()) << (comma?",":"") << "\n";
  124. }
  125. void gen_param_expr(std::ostream& out, std::string name, const std::string& value, bool comma);
  126. // this should be used when printing out floating point values (doubles)
  127. static void gen_param_expr(std::ostream& out, std::string name, Json::Value& value, bool comma) {
  128. gen_param_expr(out, name, value.asString(), comma);
  129. }
  130. static void gen_param_enum(std::ostream& out, std::string name, std::string enum_name, std::string enum_value, bool comma) {
  131. out << IND << name << " = " << make_enum_value(enum_name, enum_value) << (comma?",":"") << "\n";
  132. }
  133. static void gen_param_list(std::ostream& out, std::string name, const std::vector<std::string>& values, bool comma, bool as_strings = false) {
  134. std::string q = (as_strings) ? "'" : "";
  135. out << IND << name << " = [";
  136. for (size_t i = 0; i < values.size(); i++) {
  137. out << q << values[i] << q;
  138. gen_comma(out, i , values);
  139. }
  140. out << "]" << (comma?",":"") << "\n";
  141. }
  142. static void gen_param_list_3_floats(std::ostream& out, std::string name, Json::Value& x, Json::Value& y, Json::Value& z, bool comma) {
  143. out << IND <<
  144. name << " = " <<
  145. "(" << x.asString() << ", " << y.asString() << ", " << z.asString() << ")" << (comma?",":"") << "\n";
  146. }
  147. template<typename T>
  148. static void gen_assign(std::ostream& out, std::string var_name, T value) {
  149. out << var_name << " = " << value << "\n";
  150. }
  151. template<typename T>
  152. static void gen_assign(std::ostream& out, std::string obj_name, std::string field_name1, T value) {
  153. out << obj_name << "." << field_name1 << " = " << value << "\n";
  154. }
  155. template<>
  156. void gen_assign(std::ostream& out, std::string obj_name, std::string field_name1, bool value) {
  157. out << obj_name << "." << field_name1 << " = " << (value ? "True" : "False") << "\n";
  158. }
  159. static void gen_assign_str(std::ostream& out, std::string obj_name, std::string field_name1, std::string value) {
  160. out << obj_name << "." << field_name1 << " = '" << value << "'\n";
  161. }
  162. template<typename T>
  163. static void gen_assign(std::ostream& out, std::string obj_name, std::string field_name1, std::string field_name2, T value) {
  164. out << obj_name << "." << field_name1 << "." << field_name2 << " = " << value << "\n";
  165. }
  166. // for some reason the template above casts double to int..
  167. template<>
  168. void gen_assign(std::ostream& out, std::string obj_name, std::string field_name1, std::string field_name2, double value) {
  169. out << obj_name << "." << field_name1 << "." << field_name2 << " = " << value << "\n";
  170. }
  171. template<>
  172. void gen_assign(std::ostream& out, std::string obj_name, std::string field_name1, std::string field_name2, float value) {
  173. out << obj_name << "." << field_name1 << "." << field_name2 << " = " << value << "\n";
  174. }
  175. template<>
  176. void gen_assign(std::ostream& out, std::string obj_name, std::string field_name1, std::string field_name2, bool value) {
  177. out << obj_name << "." << field_name1 << "." << field_name2 << " = " << (value ? "True" : "False") << "\n";
  178. }
  179. static void gen_assign_vec3(
  180. std::ostream& out, std::string obj_name, std::string field_name1, std::string field_name2,
  181. double x, double y, double z) {
  182. out << obj_name << "." << field_name1 << "." << field_name2 << " = [" << x << ", " << y << ", " << z << "]\n";
  183. }
  184. static void gen_assign_vec3(
  185. std::ostream& out, std::string obj_name, std::string field_name1, std::string field_name2,
  186. float x, float y, float z) {
  187. out << obj_name << "." << field_name1 << "." << field_name2 << " = [" << x << ", " << y << ", " << z << "]\n";
  188. }
  189. } // namespace API
  190. } // namespace MCell
  191. #endif /* LIBMCELL_API_PYTHON_EXPORT_UTILS_H_ */