123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- /******************************************************************************
- *
- * Copyright (C) 2020 by
- * The Salk Institute for Biological Studies
- *
- * Use of this source code is governed by an MIT-style
- * license that can be found in the LICENSE file or at
- * https://opensource.org/licenses/MIT.
- *
- ******************************************************************************/
- #include <fstream>
- #include <regex>
- #include "api/python_export_utils.h"
- #include "api/python_export_constants.h"
- namespace MCell {
- namespace API {
- using namespace std;
- bool PythonExportContext::already_exported(const BaseDataClass* obj) const {
- return exported_objects.count(obj) != 0;
- }
- std::string PythonExportContext::get_exported_name(const BaseDataClass* obj) const {
- assert(already_exported(obj));
- return exported_objects.find(obj)->second;
- }
- void PythonExportContext::add_exported(const BaseDataClass* obj, const std::string& name) {
- assert(!already_exported(obj));
- exported_objects[obj] = name;
- }
- uint PythonExportContext::postinc_counter(const std::string& underscored_class_name) {
- uint res;
- auto it = counters.find(underscored_class_name);
- if (it != counters.end()) {
- res = it->second;
- it->second++;
- }
- else {
- res = 0;
- counters[underscored_class_name] = 1;
- }
- return res;
- }
- std::string fix_id(const std::string& str) {
- std::string res;
- for (char c: str) {
- if (c == '+') {
- res += "_plus_";
- }
- else if (c == '-') {
- res += "_minus_";
- }
- else if (c == '*') {
- res += "_mul_";
- }
- else if (c == '/') {
- res += "_div_";
- }
- else if (c == '?') {
- res += "_anybond_";
- }
- else if (c == '!') {
- res += "_bond_";
- }
- else if (c == '(') {
- res += "_ps_";
- }
- else if (c == ')') {
- res += "_pe_";
- }
- else if (
- c == ' ' || c == '.' || c == '_' ||
- c == ',' || c == '~') {
- res += "_";
- }
- else if (isalnum(c)) {
- res += c;
- }
- // ignoring the rest of the characters
- }
- return res;
- }
- string get_filename(const string& output_files_prefix, const string file_suffix, const char* ext) {
- if (output_files_prefix == "" || output_files_prefix.back() == '/' || output_files_prefix.back() == '\\') {
- return output_files_prefix + file_suffix + ext;
- }
- else {
- return output_files_prefix + "_" + file_suffix + ext;
- }
- }
- void open_and_check_file_w_prefix(
- const string& output_files_prefix, const string file_suffix, ofstream& out,
- const bool for_append, const bool bngl) {
- string file_name = get_filename(output_files_prefix, file_suffix, (bngl) ? BNGL_EXT : PY_EXT);
- if (for_append) {
- cout << "Appending to " + file_name + ".\n";
- out.open(file_name, ios::app);
- }
- else {
- cout << "Generating file " + file_name + ".\n";
- out.open(file_name);
- }
- out.precision(FLOAT_OUT_PRECISION);
- if (!out.is_open()) {
- throw ConversionError("Could not open file '" + file_name + "' for writing.");
- }
- }
- std::string get_description(const Json::Value& value) {
- if (value.isMember(KEY_DESCRIPTION)) {
- return value[KEY_DESCRIPTION].asString();
- }
- else {
- return "";
- }
- }
- void gen_description(std::ostream& out, const std::string desc, const std::string ind) {
- if (desc != "") {
- out << ind << "# " << desc << "\n";
- }
- }
- void gen_description(std::ostream& out, Json::Value& value, const std::string ind) {
- if (value.isMember(KEY_DESCRIPTION)) {
- string desc = value[KEY_DESCRIPTION].asString();
- if (desc != "") {
- out << ind << "# " << desc << "\n";
- }
- }
- }
- void gen_ctor_call(std::ostream& out, std::string name, std::string class_name, bool has_params) {
- if (name != "") {
- out << make_id(name) << " = " << MDOT << class_name;
- }
- else {
- out << MDOT << class_name;
- }
- if (has_params) {
- out << "(\n";
- }
- else {
- out << "()\n";
- }
- }
- // replaces '.' with '_' and does potentially other conversions
- std::string make_id(const std::string& s) {
- string res = s;
- // do not do changes if the ID starts with 'm.' -> constant from
- // the mcell module ID that cannot have dots that we need to replace in it anyway
- if (res.size() <= 2 || (res.size() > 2 && res.substr(0, strlen(MDOT)) != MDOT)) {
- res = fix_id(res);
- }
- return res;
- }
- string fix_param_id(const std::string& str) {
- assert(str.size() > 0);
- if (str[0] == '_') {
- // underscore denotes private variables in Python
- return "und" + str;
- }
- else {
- return str;
- }
- }
- void gen_param_expr(std::ostream& out, std::string name, const std::string& value, bool comma) {
- std::string python_expr;
- // replace operator ^ with operator ** and '_' at the beginning with 'und_'
- python_expr = fix_param_id(regex_replace(value, regex("\\^"), "**"));
- out << IND << name << " = " << python_expr << (comma?",":"") << "\n";
- }
- } // namespace API
- } // namespace MCell
|