From 6350c9aab48b1b523ed575503ecad7929441a73b Mon Sep 17 00:00:00 2001 From: Thomas-Otavio Peulen Date: Thu, 26 Oct 2023 09:19:21 +0200 Subject: [PATCH] Develop (#2) * Build osx and win * Relax test * Bump version * Bump version * Remove mongo dependency IMP should not depend on libmonogo (moved to chinet repo) * Remove mongo dependency IMP should not depend on libmonogo (moved to chinet repo) --------- Co-authored-by: tpeulen --- .gitlab-ci.yml | 34 +- CMakeLists.txt | 6 +- Setup.cmake | 6 - conda-recipe/build.sh | 7 - conda-recipe/meta.yaml | 6 +- docker/Dockerfile | 12 + include/CnMongoObject.h | 527 -------------------------- include/CnNode.h | 77 ---- include/CnNodeCallback.h | 38 -- include/CnPort.h | 269 ------------- include/internal/Functions.h | 28 +- include/internal/json.h | 4 +- pyext/CnMongoObject.i | 33 -- pyext/CnNode.i | 229 ------------ pyext/CnPort.i | 76 ---- pyext/src/__init__.py | 2 +- pyext/src/spectroscopy/decay.py | 2 +- pyext/swig.i-in | 33 +- src/CnMongoObject.cpp | 645 -------------------------------- src/CnNode.cpp | 224 ----------- src/CnNodeCallback.cpp | 144 ------- src/CnPort.cpp | 249 ------------ src/Functions.cpp | 22 -- test/broken/test_bff_Session.py | 4 +- test/test_AVNetworkRestraint.py | 4 +- test/test_CnMongoObject.py | 109 ------ test/test_CnNode.py | 510 ------------------------- test/test_CnPort.py | 240 ------------ tools | 2 +- 29 files changed, 76 insertions(+), 3466 deletions(-) create mode 100644 docker/Dockerfile delete mode 100644 include/CnMongoObject.h delete mode 100644 include/CnNode.h delete mode 100644 include/CnNodeCallback.h delete mode 100644 include/CnPort.h delete mode 100644 pyext/CnMongoObject.i delete mode 100644 pyext/CnNode.i delete mode 100644 pyext/CnPort.i delete mode 100644 src/CnMongoObject.cpp delete mode 100644 src/CnNode.cpp delete mode 100644 src/CnNodeCallback.cpp delete mode 100644 src/CnPort.cpp delete mode 100644 test/test_CnMongoObject.py delete mode 100644 test/test_CnNode.py delete mode 100644 test/test_CnPort.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6e419dc..610e2f3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,23 +42,23 @@ build:lnx_x86: # tags: # - aarch64 -#build:osx: -# <<: *build_posix -# tags: -# - osx -# before_script: -# - git submodule foreach git pull -# -#build:windows: -# <<: *build -## image: mambaforge:vs16 -# tags: -# - win -# script: -# - cmd.exe -# - conda activate base -# - cd tools && git pull --force && cd.. -# - .\tools\build.bat +build:osx: + <<: *build_posix + tags: + - osx + before_script: + - git submodule foreach git pull + +build:windows: + <<: *build +# image: mambaforge:vs16 + tags: + - win + script: + - cmd.exe + - conda activate base + - cd tools && git pull --force && cd.. + - .\tools\build.bat test:linux: stage: test diff --git a/CMakeLists.txt b/CMakeLists.txt index 38fff6b..7e0a9dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,7 +29,6 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/tools) SET(SWIG_EXECUTABLE swig CACHE STRING "Swig program") - IF(APPLE) FIND_PACKAGE(Threads) @@ -72,6 +71,11 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) imp_build_module(${CMAKE_SOURCE_DIR} bff) +# # libmongoc +# ########################### +# FIND_PACKAGE (mongoc-1.0 1.7 REQUIRED) +# LINK_LIBRARIES (mongo::mongoc_shared) + else() INCLUDE(ModuleBuild.cmake) endif() diff --git a/Setup.cmake b/Setup.cmake index 716c811..8861bd3 100644 --- a/Setup.cmake +++ b/Setup.cmake @@ -1,9 +1,3 @@ - -# libmongoc -########################### -FIND_PACKAGE (mongoc-1.0 1.7 REQUIRED) -LINK_LIBRARIES (mongo::mongoc_shared) - # SIMD ########################### IF(NOT APPLE) diff --git a/conda-recipe/build.sh b/conda-recipe/build.sh index cc79ddf..64454cd 100644 --- a/conda-recipe/build.sh +++ b/conda-recipe/build.sh @@ -1,10 +1,4 @@ #!/bin/bash -git submodule update --recursive --init --remote -cd doc -mkdir -p _build/html/stable/api -doxygen -$PYTHON ../tools/doxy2swig.py _build/xml/index.xml ../pyext/documentation.i -cd .. mkdir build cd build @@ -14,4 +8,3 @@ ninja install -k 0 -j 4 # Copy examples mkdir $PREFIX/share/doc/IMP/examples/bff cp -r ../examples/* $PREFIX/share/doc/IMP/examples/bff - diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 416dc4b..c4a69d8 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -1,4 +1,4 @@ -{% set version = "0.10.0" %} +{% set version = "0.14.0" %} package: name: imp.bff @@ -32,14 +32,14 @@ requirements: - cereal - mpir # [win] - msmpi # [win] - - libmongoc +# - libmongoc - imp run: - {{ pin_compatible('numpy') }} - python - {{ pin_compatible('imp', max_pin='x.x') }} - boost-cpp - - libmongoc +# - libmongoc - pandas - mdtraj - tqdm diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..d60b153 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,12 @@ +FROM ubuntu:22.04 +LABEL authors="tpeulen" + +RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y tzdata +RUN apt install -y vim build-essential git cmake net-tools gdb clang + +RUN DEBIAN_FRONTEND="noninteractive" apt-get update \ + && apt-get install -y ninja-build \ + && apt-get clean + +WORKDIR /work +#ENTRYPOINT ["top", "-b"] \ No newline at end of file diff --git a/include/CnMongoObject.h b/include/CnMongoObject.h deleted file mode 100644 index cf1d32a..0000000 --- a/include/CnMongoObject.h +++ /dev/null @@ -1,527 +0,0 @@ -#ifndef IMPBFF_CNMONGOOBJECT_H -#define IMPBFF_CNMONGOOBJECT_H - -#include - -#include // std::cout, std::ios -#include // std::ostringstream -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -using json = nlohmann::json; - - -IMPBFF_BEGIN_NAMESPACE - -class IMPBFFEXPORT CnMongoObject : - public std::enable_shared_from_this -{ - -private: - - mongoc_uri_t *uri; - mongoc_client_t *client; - mongoc_collection_t *collection; - - bool is_connected_to_db_; - bson_error_t error; - - static std::list registered_objects; - -protected: - - std::string object_name; - bson_t document; - std::string uri_string; - std::string db_string; - std::string app_string; - std::string collection_string; - bson_oid_t oid_document; - bson_oid_t oid_precursor; - uint64_t time_of_death; - - // Getter & Setter - //-------------------------------------------------------------------- - - //! The object identification number of CnMongoObject instance - /*! - * get_own_bson_oid() Returns the object's ObjectId value (see: - * https://docs.mongodb.com/manual/reference/bson-types/#objectid) - * - */ - //! \return - bson_oid_t get_bson_oid() - { - return oid_document; - } - - /// The BSON document of CnMongoObject instance - /// \return - virtual bson_t get_bson(); - - /// A BSON document containing CnMongoObject instance BSON document - /// excluding a set of keys - /// \param first is the first key to exclude. - /// \param ... more keys to exclude - /// \return a bson_t document - bson_t get_bson_excluding(const char* first, ...); - - /// Pointer to the BSON document of the CnMongoObject - /// \return - const bson_t* get_document(); - - void set_document(bson_t *doc){ - bson_init(&document); - bson_copy_to(doc, &document); - } - - // Methods - //-------------------------------------------------------------------- - //! Writes a BSON document to the connected MongoDB - /*! - * - * @param doc a pointer to the BSON document that is written to the MongoDB - * @param write_option integer specifying the write mode - 1: replaces the document (no upsert), 2: insert - * the document das a new document, default: updates an existing document. - * - * @return true in case of a successful write. - */ - bool write_to_db(const bson_t &doc, int write_option = 0); - bool read_from_db(); - - template - void create_oid_dict_in_doc(bson_t *doc, std::string key, - const std::map> &mongo_obj_array){ - bson_t child; - bson_append_document_begin(doc, key.c_str(), key.size(), &child); - for(auto &v : mongo_obj_array){ - const bson_oid_t b = v.second->get_bson_oid(); - bson_append_oid(&child, v.first.c_str(), v.first.size(), &b); - } - bson_append_document_end(doc, &child); - } - - template - void create_oid_dict_in_doc( - bson_t *doc, std::string key, - const std::vector< - std::pair> - > &mongo_obj_array){ - bson_t child; - bson_append_document_begin(doc, key.c_str(), key.size(), &child); - for(auto &v : mongo_obj_array){ - const bson_oid_t b = v.second->get_bson_oid(); - bson_append_oid(&child, v.first.c_str(), v.first.size(), &b); - } - bson_append_document_end(doc, &child); - } - - template - void append_number_array(bson_t *doc, std::string key, T &values){ - bson_t child; - bson_append_array_begin(doc, key.c_str(), key.size(), &child); - if( - (std::is_same>::value) || - (std::is_same>::value) - ){ - for(auto &v : values){ - bson_append_int64(&child, "", 0, v); - } - } - else if(std::is_same>::value){ - for(auto &v : values){ - bson_append_double(&child, "", 0, v); - } - } - else if(std::is_same>::value){ - for(auto &v : values){ - bson_append_bool(&child, "", 0, v); - } - } - bson_append_array_end(doc, &child); - } - - template - void create_oid_array_in_doc( - bson_t *doc, - std::string target_field_name, - const std::map> &mongo_obj_array){ - - bson_t child; - bson_append_array_begin( - doc, - target_field_name.c_str(), target_field_name.size(), - &child - ); - for(auto &v : mongo_obj_array){ - const bson_oid_t b = v.second->get_bson_oid(); - bson_append_oid(&child, "", 0, &b); - } - bson_append_array_end(doc, &child); - } - - template - bool create_and_connect_objects_from_oid_doc( - const bson_t *doc, - const char *document_name, - std::map> *target_map){ - bool return_value = true; - bson_iter_t iter; bson_iter_t child; - if (bson_iter_init_find (&iter, doc, document_name) && - BSON_ITER_HOLDS_DOCUMENT (&iter) && - bson_iter_recurse (&iter, &child)) { - while (bson_iter_next (&child)) { - if (BSON_ITER_HOLDS_OID(&child)){ - // read oid - bson_oid_t oid; - bson_oid_copy(bson_iter_oid(&child), &oid); - // create new obj - auto o = new T(); - // connect obj to db - return_value &= connect_object_to_db(o); - // read obj from db -#if IMPBFF_VERBOSE - std::cout << oid_to_string(oid) << std::endl; -#endif - o->read_from_db(oid_to_string(oid)); - std::string key = bson_iter_key(&child); - // add obj to the target map - target_map->insert(std::pair(key, o)); - } - } - } else{ -#if IMPBFF_VERBOSE - std::cerr << "Error: no nodes section in Session" << std::endl; -#endif - return_value &= false; - } - return return_value; - } - - template - bool create_and_connect_objects_from_oid_doc( - const bson_t *doc, - const char *document_name, - std::vector>> *target){ - bool return_value = true; - bson_iter_t iter; bson_iter_t child; - if (bson_iter_init_find (&iter, doc, document_name) && - BSON_ITER_HOLDS_DOCUMENT (&iter) && - bson_iter_recurse (&iter, &child)) { - while (bson_iter_next (&child)) { - if (BSON_ITER_HOLDS_OID(&child)){ - // read oid - bson_oid_t oid; - bson_oid_copy(bson_iter_oid(&child), &oid); - // create new obj - auto o = new T(); - // connect obj to db - return_value &= connect_object_to_db(o); - // read obj from db - #if IMPBFF_VERBOSE - std::cout << oid_to_string(oid) << std::endl; - #endif - o->read_from_db(oid_to_string(oid)); - std::string key = bson_iter_key(&child); - // add obj to the target - auto p = std::pair>(key, o); - target->emplace_back(p); - } - } - } else{ - #if IMPBFF_VERBOSE - std::cerr << "Error: no nodes section in Session" << std::endl; - #endif - return_value &= false; - } - return return_value; - } - - -/// Append a string to a BSON document - /// \param dst pointer to the target BSON document - /// \param key the key of the string int the target BSON document - /// \param content the string that will be written to the BSON document - /// \param size optional parameter for the string size in the BSON document. - static void append_string( - bson_t *dst, std::string key, std::string content, size_t size=0); - - - /// The string contained in a @class bson_t document with the @param key - /// \param doc BSON @class bson_t document which is inspected - /// \param key - /// \return string contained under the @param key - static const std::string get_string_by_key( - bson_t *doc, std::string key); - - /// Converts a @class bson_oid_t oid into a @class std::string - /// \param oid - /// \return - static std::string oid_to_string(bson_oid_t oid){ - char oid_str[25]; - bson_oid_to_string(&oid, oid_str); - return std::string(oid_str, 25).substr(0, 24); - } - - - /// Converts a @class std::string into a @class bson_oid_t - /// \param oid_string - /// \param oid - /// \return - static bool string_to_oid( - const std::string &oid_string, - bson_oid_t *oid - ); - -public: - - // IMP_OBJECT_METHODS(CnMongoObject); - ~CnMongoObject(); - CnMongoObject(std::string name="CnMongoObject%1%"); - - //! Connects the instance of @class CnMongoObject to a database - /*! - * @param uri_string - * @param db_string - * @param app_string - * @param collection_string - * @return True if connected successfully - */ - bool connect_to_db( - const std::string &uri_string, - const std::string &db_string, - const std::string &app_string, - const std::string &collection_string - ); - - /// Connects other object to the same MongoDB - /// \tparam T - /// \param o The object that is connected to the same MongoDB - /// \return True if connected successfully - template - bool connect_object_to_db(T o){ - return o->connect_to_db( - uri_string, - db_string, - app_string, - collection_string - ); - } - - /// Disconnects the CnMongoObject instance from the DB - void disconnect_from_db(); - - /// Returns true if the instance of the CnMongoObject is connected - /// to the DBf - bool is_connected_to_db(); - - void register_instance(CnMongoObject*); - - void unregister_instance(CnMongoObject*); - - /// - static std::list get_instances(); - - /// Writes @class CnMongoObject to the connected MongoDB - /// \return - virtual bool write_to_db(); - - /// Creates a copy of the object in the connected MongoDB with a new OID. - /// \return The OID of the copy - std::string create_copy_in_db(); - - /// Read the content of an existing BSON document into the current object - /// \param oid_string Object identifier of the queried document in the DB - /// \return True if successful otherwise false - virtual bool read_from_db(const std::string &oid_string); - - /// Read the content of a JSON string into a CnMongoObject - /// \param json_string - /// \return - bool read_json(std::string json_string); - - /// The own object identifier - /// \return - std::string get_own_oid() - { - return oid_to_string(oid_document); - } - - /// Set the own object identifier without duplicate check - /// \param oid_str - void set_own_oid(std::string oid_str) - { - CnMongoObject::string_to_oid(oid_str, &oid_document); - } - - std::shared_ptr getptr() { - return shared_from_this(); - } - - /// Create and / or set a string in the CnMongoObject accessed - /// by @param key - /// \param key the key to access the content - /// \param str The content - void set_string(std::string key, std::string str); - - void set_name(std::string name){ - object_name = name; - } - - virtual std::string get_name(){ - return object_name; - } - - virtual std::string get_string(){ - return get_name(); - } - - template - T get_(const char *key){ - T v(0); - bson_iter_t iter; - if(std::is_same::value || std::is_same::value) { - if (bson_iter_init_find(&iter, &document, key) && - (BSON_ITER_HOLDS_INT64(&iter))) { - return (T) bson_iter_int64(&iter); - } - } - else if(std::is_same::value) { - if (bson_iter_init_find(&iter, &document, key) && - (BSON_ITER_HOLDS_DOUBLE(&iter))) { - return bson_iter_double(&iter); - } - } - else if(std::is_same::value) { - if (bson_iter_init_find(&iter, &document, key) && - (BSON_ITER_HOLDS_BOOL(&iter))) { - return bson_iter_bool(&iter); - } - } - return v; - } - - template - void set_(const char *key, T value){ - bson_iter_t iter; - if(std::is_same::value) { - if (bson_iter_init_find(&iter, &document, key) && - BSON_ITER_HOLDS_BOOL(&iter)) { - bson_iter_overwrite_bool(&iter, value); - } else{ - bson_append_bool(&document, key, -1, value); - } - } - else if(std::is_same::value) { - if (bson_iter_init_find(&iter, &document, key) && - BSON_ITER_HOLDS_DOUBLE(&iter)) { - bson_iter_overwrite_double(&iter, value); - } else{ - bson_append_double(&document, key, -1, value); - } - } - else if(std::is_same::value) { - if (bson_iter_init_find(&iter, &document, key) && - BSON_ITER_HOLDS_INT64(&iter)) { - bson_iter_overwrite_int64(&iter, value); - } else{ - bson_append_int64(&document, key, -1, value); - } - } - } - - void set_oid(const char* key, bson_oid_t value); - - template - std::vector get_array(const char* key){ - bson_iter_t iter; - std::vector v{}; - if(std::is_same::value){ - if (bson_iter_init_find(&iter, &document, key) && - (BSON_ITER_HOLDS_ARRAY(&iter))){ - bson_iter_t iter_array; - bson_iter_recurse (&iter, &iter_array); - while (bson_iter_next (&iter_array) && - BSON_ITER_HOLDS_DOUBLE(&iter_array)) { - v.push_back(bson_iter_double(&iter_array)); - } - } - return v; - } - else if(std::is_same::value || std::is_same::value){ - if (bson_iter_init_find(&iter, &document, key) && - (BSON_ITER_HOLDS_ARRAY(&iter))) { - bson_iter_t iter_array; - bson_iter_recurse(&iter, &iter_array); - while (bson_iter_next(&iter_array) && - BSON_ITER_HOLDS_INT64(&iter_array)) { - v.push_back((T) bson_iter_int64(&iter_array)); - } - } - return v; - } - else if(std::is_same::value){ - if (bson_iter_init_find(&iter, &document, key) && - (BSON_ITER_HOLDS_ARRAY(&iter))) { - bson_iter_t iter_array; - bson_iter_recurse(&iter, &iter_array); - while (bson_iter_next(&iter_array) && - BSON_ITER_HOLDS_BOOL(&iter_array)) { - v.push_back((int) bson_iter_bool(&iter_array)); - } - } - return v; - } - return v; - } - - template - void set_array(const char* key, std::vector value){ - bson_t dst; bson_init(&dst); - bson_copy_to_excluding_noinit(&document, &dst, key, NULL); - append_number_array(&dst, key, value); - bson_copy_to(&dst, &document); - } - - std::string get_json(); - - std::string get_json_of_key(std::string key); - - std::string show(){ - std::ostringstream os; - os << this->get_json(); - os << std::endl; - return os.str(); - } - - // Operators - //-------------------------------------------------------------------- - virtual CnMongoObject* operator[](std::string key); - - bool operator==(CnMongoObject const& b){ - return ( - bson_oid_equal(&b.oid_document, &oid_document) && - (uri_string == b.uri_string) - ); - }; - - friend std::ostream& operator<<(std::ostream &out, CnMongoObject& o) - { - out << o.get_json(); - return out; - } - -}; - -IMPBFF_END_NAMESPACE - -#endif //IMPBFF_CNMONGOOBJECT_H diff --git a/include/CnNode.h b/include/CnNode.h deleted file mode 100644 index 312365d..0000000 --- a/include/CnNode.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef IMPBFF_NODE_H -#define IMPBFF_NODE_H - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -IMPBFF_BEGIN_NAMESPACE - -class CnPort; -class CnNodeCallback; -class IMPBFFEXPORT CnNode : public CnMongoObject{ - -private: - friend CnPort; - bool node_valid_ = false; - std::vector>> ports; - -protected: - std::map> in_; - std::map> out_; - -public: - - void fill_input_output_port_lookups(); - - /// A pointer to a function that operates on an input CnPort instance (first argument) - /// and writes to an output CnPort instance (second argument) - std::shared_ptr callback_class; - - // Constructor & Destructor - //-------------------------------------------------------------------- - CnNode(std::string name="", - const std::vector>& ports = std::vector>(), - std::shared_ptr callback_class = nullptr - ); - ~CnNode(); - - // Methods - //-------------------------------------------------------------------- - bool read_from_db(const std::string &oid_string) final; - void evaluate(); - bool is_valid(); - bool inputs_valid(); - bool write_to_db() final; - - // Getter / Setter - //-------------------------------------------------------------------- - bson_t get_bson(); -// std::string get_name(); - std::map> get_input_ports(); - std::map> get_output_ports(); - std::vector>> get_ports(); - void set_ports(const std::vector>& ports); - void add_port(std::shared_ptr, bool is_source, bool fill_in_out=true); - void add_input_port(std::shared_ptr); - void add_output_port(std::shared_ptr); - CnPort* get_input_port(const std::string &port_name); - CnPort* get_output_port(const std::string &port_name); - - // Setter - //----------------------------------------------------------- - void set_callback(std::shared_ptr cb); - void set_valid(bool is_valid=false); -}; - -IMPBFF_END_NAMESPACE - -#endif //IMPBFF_NODE_H diff --git a/include/CnNodeCallback.h b/include/CnNodeCallback.h deleted file mode 100644 index cc4123b..0000000 --- a/include/CnNodeCallback.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef IMPBFF_NODECALLBACK_H -#define IMPBFF_NODECALLBACK_H - -#include - -#include -#include -#include -#include /* std::min std::max */ - - -IMPBFF_BEGIN_NAMESPACE -class CnPort; - -#include -#include -#include - - - -class IMPBFFEXPORT CnNodeCallback{ - -public: - - virtual void run( - std::map>, - std::map> - ){ - std::cout << "This print by NodeCallback class from C++" << std::endl; - } - - CnNodeCallback() = default; - virtual ~CnNodeCallback() {}; -}; - -IMPBFF_END_NAMESPACE - -#endif //IMPBFF_NODECALLBACK_H diff --git a/include/CnPort.h b/include/CnPort.h deleted file mode 100644 index 6e7133c..0000000 --- a/include/CnPort.h +++ /dev/null @@ -1,269 +0,0 @@ -#ifndef IMPBFF_CNPORT_H -#define IMPBFF_CNPORT_H - -#include -#include - -#include -#include -#include /* std::max, std::min */ -#include -#include -#include -#include -#include /* pair */ -#include - -#include -#include -#include -#include - -IMPBFF_BEGIN_NAMESPACE -class CnNode; - -/// Specifies the type of the Port -typedef enum{ - BFF_PORT_VECTOR_INT, - BFF_PORT_VECTOR_FLOAT, - BFF_PORT_INT, - BFF_PORT_FLOAT, - BFF_PORT_BINARY -} CnPortType; - - -typedef enum{ - BFF_PORT_ADD, - BFF_PORT_MUL -} PortOperation; - - - -class IMPBFFEXPORT CnPort : public CnMongoObject { - -private: - - std::map PORT_VALUE_BYTE_SIZE = { - {BFF_PORT_VECTOR_INT, sizeof(long)}, - {BFF_PORT_VECTOR_FLOAT, sizeof(double)}, - {BFF_PORT_INT, sizeof(long)}, - {BFF_PORT_FLOAT, sizeof(double)}, - {BFF_PORT_BINARY, 1} - }; - - CnPortCache cc_; - std::vector bounds_{}; - CnNode* node_ = nullptr; - - /*! - * @brief Pointer to another Port (default value nullptr). - * If not nullptr @class Port::get_value returns value of link - */ - std::shared_ptr link_ = nullptr; - - /*! - * @brief This attribute stores the Ports that are dependent on the value - * of this Port object. If this Port object is reactive a change of the - * value of this Port object is propagated to the dependent Ports. - */ - std::vector linked_to_; - - bool remove_links_to_port() { - if (link_ != nullptr) { - // remove pointer to this port in the port to which this is linked - auto it = std::find(linked_to_.begin(), linked_to_.end(), this); - if (it != linked_to_.end()) { - linked_to_.erase(it); - return true; - } - } - return false; - } - - template - void set_value_of_dependents(T *input, int n_input) { - for (auto &v : linked_to_) { - v->set_value(input, n_input); - } - } - - /// Specifies the type of the Port - int value_type = BFF_PORT_FLOAT; - - /// size (in bytes) of a port value - int value_size = PORT_VALUE_BYTE_SIZE[BFF_PORT_FLOAT]; - - -public: - - size_t size() { - return cc_.size() / value_size; - } - - // Constructor & Destructor - //-------------------------------------------------------------------- - ~CnPort() { - remove_links_to_port(); - }; - - CnPort( - bool fixed = false, - bool is_output = false, - bool is_reactive = false, - bool is_bounded = false, - double lb = 0, - double ub = 0, - int value_type = 1, - std::string name = "" - ); - - void set_node(CnNode *node_ptr); - - CnNode* get_node(); - - // Getter & Setter - //-------------------------------------------------------------------- - int get_value_type(); - - void set_value_type(int v); - - template - void update_value_type(int n_input){ - if (std::is_same::value) { - value_type = BFF_PORT_VECTOR_FLOAT; - } else { - value_type = BFF_PORT_VECTOR_INT; - } - if(n_input == 1) - value_type += 2; // use scalar type for single numbers - } - - template - void set_value(T *input, int n_input) { -#if IMPBFF_VERBOSE - std::clog << "SET PORT VALUE" << std::endl; - std::clog << "-- Name of port: " << get_name() << std::endl; - std::clog << "-- Copy values to local buffer: " << copy_values << std::endl; - std::clog << "-- Number of input elements: " << n_input << std::endl; -#endif - if (is_fixed()) { -#if IMPBFF_VERBOSE - std::clog << "WARNING: The port is fixed the action will be ignored." << std::endl; -#endif - return; - } - update_value_type(n_input); -#if IMPBFF_VERBOSE - std::clog << "-- Copying values to local buffer." << std::endl; -#endif - cc_.set(input, n_input); - if (node_ != nullptr) { -#if IMPBFF_VERBOSE - std::clog << "-- Updating attached node." << std::endl; -#endif - update_attached_node(); -#if IMPBFF_VERBOSE - std::clog << "-- Updating dependent ports." << std::endl; -#endif - set_value_of_dependents(input, n_input); - } - } - - template - void update_buffer() { - auto v = get_array("value"); - cc_.set(v.data(), v.size()); - } - - template - void get_own_value(T **output, int *n_output, bool update_local_buffer = false) { - if ((cc_.size() == 0) || update_local_buffer) { - update_buffer(); - } - T* origin = (T *) malloc(cc_.size()); - auto n_buffer_elements = cc_.size() / sizeof(T); - memcpy(origin, cc_.get_bytes().data(), cc_.size()); - if (is_bounded() && bound_is_valid()) - Functions::bound_values( - origin, n_buffer_elements, bounds_[0], bounds_[1]); - *n_output = n_buffer_elements; - *output = origin; - } - - template - void get_value(T **output, int *n_output) { - if (!is_linked()) { -#if IMPBFF_VERBOSE - std::clog << "GET VALUE" << std::endl; - std::clog << "-- Name of Port: " << get_name() << std::endl; - std::clog << "-- Local value type: " << value_type << std::endl; - std::clog << "-- Local buffer is filled: " << (n_buffer_elements_ > 0) << std::endl; - std::clog << "-- Number of elements in local buffer: " << n_buffer_elements_ << std::endl; - std::clog << "-- Port is not linked." << std::endl; -#endif - get_own_value(output, n_output); - } else { -#if IMPBFF_VERBOSE - std::clog << "GET VALUE" << std::endl; - std::clog << "-- Port is linked to " << get_link()->get_name() << std::endl; -#endif - get_link()->get_value(output, n_output); - } -#if IMPBFF_VERBOSE - std::clog << "-- Number of elements: " << *n_output << std::endl; -#endif - } - - virtual bson_t get_bson() final; - - // Methods - //-------------------------------------------------------------------- - void update_attached_node(); - - void set_bounded(bool bounded); - - bool bound_is_valid(); - - bool is_bounded(); - - void set_bounds(double *input, int n_input); - - void get_bounds(double **output, int *n_output); - - bool is_fixed(); - - void set_fixed(bool fixed); - - bool is_output(); - - void set_port_type(bool is_output); - - bool is_reactive(); - - bool is_float(); - - void set_reactive(bool reactive); - - bool write_to_db(); - - bool read_from_db(const std::string &oid_string); - - void get_bytes(unsigned char **output, int *n_output, bool copy = false); - - void set_bytes(unsigned char *input, int n_input); - - void set_link(std::shared_ptr v); - - bool unlink(); - - bool is_linked(); - - std::vector get_linked_ports(); - - std::shared_ptr get_link(); - -}; - -IMPBFF_END_NAMESPACE - -#endif //IMPBFF_CNPORT_H \ No newline at end of file diff --git a/include/internal/Functions.h b/include/internal/Functions.h index fa68d57..dbfd8d8 100644 --- a/include/internal/Functions.h +++ b/include/internal/Functions.h @@ -8,7 +8,7 @@ #include #include #include -#include +//#include IMPBFF_BEGIN_NAMESPACE @@ -146,19 +146,19 @@ namespace Functions { */ uint64_t get_time(); - /*! - * Adds the content in the bson_t document src to the document dst omitting the keys - * provided by the vector skip. - */ - void add_documents(bson_t *src, bson_t *dst, std::vector skip); - - /*! - * Returns true if the key associated to @param iter is in the list of vectors @param skip - * - * @param iter pointer to a bson_iter_t - * @param skip vector of strings containing keys that are skipped by iter - */ - bool bson_iter_skip(bson_iter_t *iter, std::vector *skip); +// /*! +// * Adds the content in the bson_t document src to the document dst omitting the keys +// * provided by the vector skip. +// */ +// void add_documents(bson_t *src, bson_t *dst, std::vector skip); +// +// /*! +// * Returns true if the key associated to @param iter is in the list of vectors @param skip +// * +// * @param iter pointer to a bson_iter_t +// * @param skip vector of strings containing keys that are skipped by iter +// */ +// bool bson_iter_skip(bson_iter_t *iter, std::vector *skip); /*! * Returns a vector with a size that is is min(a.size(), b.size()) diff --git a/include/internal/json.h b/include/internal/json.h index 1f82da4..777e507 100644 --- a/include/internal/json.h +++ b/include/internal/json.h @@ -18870,7 +18870,7 @@ class basic_json @param[in] i input to read from @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values + which is used to control the deserialization by filtering cn values (optional) @param[in] allow_exceptions whether to throw exceptions in case of a parse error (optional, true by default) @@ -19008,7 +19008,7 @@ class basic_json @param[in] first begin of the range to parse (included) @param[in] last end of the range to parse (excluded) @param[in] cb a parser callback function of type @ref parser_callback_t - which is used to control the deserialization by filtering unwanted values + which is used to control the deserialization by filtering cn values (optional) @param[in] allow_exceptions whether to throw exceptions in case of a parse error (optional, true by default) diff --git a/pyext/CnMongoObject.i b/pyext/CnMongoObject.i deleted file mode 100644 index 184acd5..0000000 --- a/pyext/CnMongoObject.i +++ /dev/null @@ -1,33 +0,0 @@ -%shared_ptr(IMP::bff::CnMongoObject) - -%template(ListCnMongoObjectPtr) std::list; -%attributestring(IMP::bff::CnMongoObject, std::string, name, get_name, set_name); -%attributestring(IMP::bff::CnMongoObject, std::string, oid, get_own_oid, set_own_oid); -%attribute(IMP::bff::CnMongoObject, bool, is_connected_to_db, is_connected_to_db); - -%include "IMP/bff/CnMongoObject.h" - -%extend IMP::bff::CnMongoObject { - - public: - %template(get_array_double) get_array; - %template(set_array_double) set_array; - %template(get_array_long) get_array; - %template(set_array_long) set_array; - %template(get_array_int) get_array; - %template(set_array_int) set_array; - - %template(get_bool) get_; - %template(set_bool) set_; - %template(get_double) get_; - %template(set_double) set_; - %template(get_int) get_; - %template(set_int) set_; - - %template(connect_object_to_db_mongo) connect_object_to_db>; - - IMP::bff::CnMongoObject* __getitem__(std::string key) { - return(*self)[key]; - } - -} diff --git a/pyext/CnNode.i b/pyext/CnNode.i deleted file mode 100644 index 356d7a7..0000000 --- a/pyext/CnNode.i +++ /dev/null @@ -1,229 +0,0 @@ -/* Director needed for wrapping of callback functions*/ -%feature("director") CnNodeCallback; - -%shared_ptr(IMP::bff::CnPort) -%shared_ptr(IMP::bff::CnNode) -%shared_ptr(IMP::bff::CnNodeCallback) - -%template(PairStringCnPortPtr) std::pair>; -%template(VecPairStringCnPortPtr) std::vector>>; -%template(MapStringCnPortPtr) std::map>; -%template(ListCnNodePtr) std::list>; -%template(MapStringDouble) std::map; - -%attribute(IMP::bff::CnNode, bool, is_valid, is_valid); - -%include "IMP/bff/CnNodeCallback.h" -%include "IMP/bff/CnNode.h" - - -%extend IMP::bff::CnNode { - - std::string __repr__(){ - std::ostringstream os; - os << "CnNode("; - for (auto &v : $self->get_input_ports()) os << (v.first)<< ","; - os << "->"; - for (auto &v : $self->get_output_ports()) os << (v.first)<< ","; - os << ")"; - return os.str(); - } - - %pythoncode %{ - - @property - def inputs(self): - return dict(self.get_input_ports()) - - @property - def outputs(self): - return dict(self.get_output_ports()) - - @property - def ports(self): - return list(self.get_ports()) - - @ports.setter - def ports(self, v): - for key in v: - if isinstance(v[key], IMP.bff.CnPort): - p = v[key] - elif isinstance(v[key], dict): - p = IMP.bff.CnPort(**v[key]) - else: - p = IMP.bff.CnPort(value=v[key]) - p.name = key - self.add_port(p, p.is_output, True) - - def set_python_callback_function(self, cb, reactive_inputs = True, reactive_outputs = True): - # type: (Callable, bool, bool) -> None - import sys - if sys.version_info[0] > 2: - import inspect - from inspect import signature as sig - empty_name = inspect.Signature.empty - empty_type = inspect._empty - _use_py2 = True - else: - import funcsigs - from funcsigs import signature as sig - empty_name = funcsigs._empty - empty_type = funcsigs._empty - _use_py2 = False - - class CnNodeCallbackPython(IMP.bff.CnNodeCallback): - - def __init__(self, cb_function, *args, **kwargs): - super(CnNodeCallbackPython, self).__init__(*args, **kwargs) - self._cb = cb_function - - def run(self, inputs, outputs): - input_dict = dict( - [(inputs[i].name, inputs[i].value) for i in inputs] - ) - output = self._cb(**input_dict) - if isinstance(output, dict): - for key, ov in zip(outputs, output): - outputs[key].value = output[key] - elif isinstance(output, tuple): - for key, ov in zip(outputs, output): - outputs[key].value = ov - else: - next(iter(outputs.values())).value = output - - if isinstance(cb, str): - code_obj = compile(cb, '', 'exec') - self.set_string('source', cb) - for o in code_obj.co_consts: - if isinstance(o, types.CodeType): - cb = types.FunctionType(o, globals()) - break - else: - self.set_string('source', inspect.getsource(cb)) - - _sig = sig(cb) - input_ports = list() - for parameter_name in _sig.parameters: - o = _sig.parameters[parameter_name] - if o.default is empty_name: - if o.annotation is empty_type: - print("WARNING no type specified for %s IMP.bff.CnPort." % parameter_name) - value = np.array([1.0], dtype=np.float64) - elif o.annotation == 'int': - value = 1 - elif 'ndarray' == o.annotation: - value = np.array([1.0], dtype=np.float64) - elif o.annotation == 'float': - value = 1.0 - else: - print("WARNING no type specified for %s IMP.bff.CnPort." % parameter_name) - value = np.array([1.0], dtype=np.float64) - else: - value = o.default - names = [str(n) for n, _ in self.ports] - if str(o.name) not in names: - p = IMP.bff.CnPort(name=o.name, value=value, is_output=False, is_reactive=reactive_inputs) - self.add_input_port(p) - input_ports.append(p) - else: - input_ports.append(self.get_input_ports()[o.name]) - - input_values = dict([(p.name, p.value) for p in input_ports]) - returned_value = cb(**input_values) - - output_values = list() - output_names = list() - if isinstance(returned_value, dict): - for ok in returned_value: - output_values.append(returned_value[ok]) - output_names.append(ok) - elif isinstance(returned_value, tuple): - output_values = returned_value - for i in range(len(returned_value)): - output_names.append("out_" + str(i).zfill(2)) - else: - output_names = 'out_00', - output_values = returned_value, - for on, ov in zip(output_names, output_values): - if on not in self.get_output_ports().keys(): - po = IMP.bff.CnPort( - name=on, - value=ov, - is_output=True, - is_reactive=reactive_outputs - ) - self.add_output_port(po) - cb_instance = CnNodeCallbackPython(cb_function=cb) - cb_instance.__disown__() - self.set_callback(cb_instance) - - callback_function = property(None, set_python_callback_function) - - def __getattr__(self, name): - in_input = name in self.inputs.keys() - in_output = name in self.outputs.keys() - if in_input and in_output: - raise KeyError("Ambiguous access. %s an input and output parameter.") - elif not in_output and not in_input: - raise AttributeError - else: - if in_input: - return self.inputs[name].value - else: - return self.outputs[name].value - - def __setattr__(self, name, value): - try: - in_input = name in self.inputs.keys() - in_output = name in self.outputs.keys() - if in_input and in_output: - raise KeyError("Ambiguous access. %s an input and output parameter.") - elif not in_output and not in_input: - raise AttributeError - else: - if in_input: - self.inputs[name].value = value - else: - self.outputs[name].value = value - except: - IMP.bff.CnMongoObject.__setattr__(self, name, value) - - def __call__(self): - return self.evaluate() - - def __init__(self, - obj=None, - name = "", #type: str - ports = None, #type: dict - callback_function=None, - reactive_inputs=True, - reactive_outputs=True, - *args, **kwargs - ): - this = _IMP_bff.new_CnNode(*args, **kwargs) - try: - self.this.append(this) - except: - self.this = this - self.register_instance(None) - if isinstance(ports, dict): - self.ports = ports - if isinstance(obj, str): - name = obj - elif callable(obj): - callback_function = obj - if callable(callback_function) or isinstance(callback_function, str): - self.set_python_callback_function( - cb=callback_function, - reactive_inputs=reactive_inputs, - reactive_outputs=reactive_outputs - ) - if len(name) > 0: - self.name = name - else: - if callable(callback_function): - self.name = callback_function.__name__ - - %} -} - diff --git a/pyext/CnPort.i b/pyext/CnPort.i deleted file mode 100644 index 798f72e..0000000 --- a/pyext/CnPort.i +++ /dev/null @@ -1,76 +0,0 @@ -%shared_ptr(IMP::bff::CnPort); -%shared_ptr(IMP::bff::CnNode); - -%attribute(IMP::bff::CnPort, bool, fixed, is_fixed, set_fixed); -%attribute(IMP::bff::CnPort, bool, is_output, is_output, set_port_type); -%attribute(IMP::bff::CnPort, bool, reactive, is_reactive, set_reactive); -%attribute(IMP::bff::CnPort, bool, is_linked, is_linked); -%attribute(IMP::bff::CnPort, bool, bounded, is_bounded, set_bounded); -%attribute_np(IMP::bff::CnPort, std::vector, bytes, get_bytes, set_bytes); -%attribute_py(IMP::bff::CnPort, IMP::bff::CnPort, link, get_link, set_link); -%attribute_py(IMP::bff::CnPort, IMP::bff::CnNode*, node, get_node, set_node); - -%include "IMP/bff/CnPort.h" - -%extend IMP::bff::CnPort{ - - public: - %template(set_value_d) set_value; - %template(get_value_d) get_value; - %template(get_value_i) get_value; - %template(set_value_i) set_value; - %template(get_value_c) get_value; - %template(set_value_c) set_value; - - %pythoncode %{ - - @property - def value(self): - if self.get_value_type() == IMP.bff.BFF_PORT_VECTOR_INT: - v = self.get_value_i() - elif self.get_value_type() == IMP.bff.BFF_PORT_VECTOR_FLOAT: - v = self.get_value_d() - elif self.get_value_type() == IMP.bff.BFF_PORT_INT: - v = self.get_value_i()[0] - elif self.get_value_type() == IMP.bff.BFF_PORT_FLOAT: - v = self.get_value_d()[0] - else: - v = None - return v - - @value.setter - def value(self, v): - if not isinstance(v, np.ndarray): - v = np.atleast_1d(v) - if v.dtype.kind == 'i': - self.set_value_i(v) - else: - self.set_value_d(v) - - @property - def bounds(self): - if self.bounded: - return self.get_bounds() - else: - return None, None - - @bounds.setter - def bounds(self, v): - self.set_bounds(np.array(v, dtype=np.float64)) - - def __init__(self, value=[], fixed=False, *args, **kwargs): - this = _IMP_bff.new_CnPort(*args, **kwargs) - try: - self.this.append(this) - except: - self.this = this - if not isinstance(value, np.ndarray): - value = np.atleast_1d(value) - self.value = value - self.fixed = fixed - - def __str__(self): - return self.get_json(indent=2) - - %} -} diff --git a/pyext/src/__init__.py b/pyext/src/__init__.py index 0462607..d8a2475 100644 --- a/pyext/src/__init__.py +++ b/pyext/src/__init__.py @@ -29,6 +29,6 @@ print("WARNING typing not found", file=sys.stderr) typing = None -__version__ = "0.12.0" +__version__ = "0.14.0" diff --git a/pyext/src/spectroscopy/decay.py b/pyext/src/spectroscopy/decay.py index f6c4c71..7e44504 100644 --- a/pyext/src/spectroscopy/decay.py +++ b/pyext/src/spectroscopy/decay.py @@ -239,7 +239,7 @@ def __init__( self._decay_modifier = [ self.decay_convolution, self.decay_scatter, - # self.decay_pileup, # TODO: seems broken + # self.decay_pileup, # TODO: seems cn self.decay_linearization, self.decay_scale, self.decay_background, diff --git a/pyext/swig.i-in b/pyext/swig.i-in index 3402190..1b12a73 100644 --- a/pyext/swig.i-in +++ b/pyext/swig.i-in @@ -5,20 +5,19 @@ %include "numpy.i" -%{ - #include - void cleanup() - { -// printf("cleanup!\n"); - mongoc_cleanup(); - } -%} - -%init %{ - import_array(); - mongoc_init(); - atexit(cleanup); -%} +//%{ +// #include +// void cleanup() +// { +//// printf("cleanup!\n"); +// mongoc_cleanup(); +// } +//%} +//%init %{ +// import_array(); +// mongoc_init(); +// atexit(cleanup); +//%} %pythoncode %{ import numpy as np @@ -27,9 +26,9 @@ import numpy as np %include "BFF.types.i" /* Chinet */ -%include "CnMongoObject.i" -%include "CnPort.i" -%include "CnNode.i" +//%include "CnMongoObject.i" +//%include "CnPort.i" +//%include "CnNode.i" //%include "CnSession.i" /* PathMap & AV */ diff --git a/src/CnMongoObject.cpp b/src/CnMongoObject.cpp deleted file mode 100644 index 2600ef4..0000000 --- a/src/CnMongoObject.cpp +++ /dev/null @@ -1,645 +0,0 @@ -#include -#include - -IMPBFF_BEGIN_NAMESPACE - -std::list CnMongoObject::registered_objects = std::list(); - -CnMongoObject::CnMongoObject(std::string name) : -// IMP::Object("CnMongoObject%1%"), - is_connected_to_db_(false), - object_name(""), - uri_string(""), - db_string(""), - app_string(""), - collection_string(""), - time_of_death(0) -{ -#if IMPBFF_VERBOSE - std::clog << "NEW CnMongoObject" << std::endl; -#endif - bson_oid_init(&oid_document, nullptr); - bson_oid_copy(&oid_document, &oid_precursor); - uri = nullptr; - client = nullptr; - collection = nullptr; - bson_t *doc = BCON_NEW( - "_id", BCON_OID(&oid_document), - "precursor", BCON_OID(&oid_document), - "death", BCON_INT64(time_of_death) - ); - set_document(doc); - bson_destroy(doc); - - if(name.empty()){ - name = get_own_oid(); - } -#if IMPBFF_VERBOSE - std::clog << "-- Name: " << name << std::endl; - std::clog << "-- OID: " << get_own_oid() << std::endl; -#endif - set_name(name); -} - -CnMongoObject::~CnMongoObject() -{ -#if IMPBFF_VERBOSE - std::clog << "DESTROYING CnMongoObject" << std::endl; - std::clog << "-- OID: " << get_own_oid() << std::endl; - std::clog << "-- Connected to DB: " << is_connected_to_db() - << std::endl; -#endif - time_of_death = Functions::get_time(); - if (is_connected_to_db()) { -#if IMPBFF_VERBOSE - std::clog << "-- Time of death: " << time_of_death << std::endl; -#endif - write_to_db(); - disconnect_from_db(); - } -#if IMPBFF_VERBOSE - std::clog << "-- Total number of CnMongoObject instances: " << - registered_objects.size() << std::endl; -#endif - mongoc_collection_destroy(collection); -} - -void CnMongoObject::register_instance(CnMongoObject* x){ -#if IMPBFF_VERBOSE - std::clog << "REGISTER CnMongoObject" << std::endl; -#endif - auto& v = registered_objects; -#if IMPBFF_VERBOSE - int use_count_offset = 0; -#endif - if(x == nullptr){ - x = getptr().get(); -#if IMPBFF_VERBOSE - use_count_offset++; -#endif - } -#if IMPBFF_VERBOSE - if(x != nullptr){ - std::clog << "-- OID: " << x->get_own_oid() << std::endl; - std::clog << "-- Name: " << x->get_name() << std::endl; - } -#endif - if(std::find(v.begin(),v.end(),x) == v.end()) - { - v.emplace_back(x); - } -} - -void CnMongoObject::unregister_instance(CnMongoObject* x){ -#if IMPBFF_VERBOSE - std::clog << "UNREGISTER CnMongoObject" << std::endl; -#endif - if(x != nullptr){ - x = getptr().get(); - registered_objects.remove(x); - } -} - - -std::list CnMongoObject::get_instances(){ -#if IMPBFF_VERBOSE - std::clog << "CnMongoObject GET INSTANCES" << std::endl; -#endif - return registered_objects; -} - - -bool CnMongoObject::connect_to_db( - const std::string &uri_string, - const std::string &db_string, - const std::string &app_string, - const std::string &collection_string -) -{ -#if IMPBFF_VERBOSE - std::clog << "CONNECT CnMongoObject TO DB" << std::endl; -#endif - this->uri_string = uri_string; - this->db_string = db_string; - this->app_string = app_string; - this->collection_string = collection_string; - - // Should be only called once -> handeld by swig init - // mongoc_init(); - - // Database - //---------------------------------------------------------------- -#if IMPBFF_VERBOSE - std::clog << "-- Connecting to DB at URI: " << uri_string.c_str() << std::endl; -#endif - - uri = mongoc_uri_new_with_error(uri_string.c_str(), &error); - if (!uri) { -#if IMPBFF_VERBOSE - std::cerr << "-- Failed to parse URI:" << uri_string.c_str() << std::endl; - std::cerr << "-- Error message: " << error.message << std::endl; -#endif - is_connected_to_db_ = false; - return false; - } else { - /* - * Create a new client instance - */ - client = mongoc_client_new_from_uri(uri); - if (!client) { - is_connected_to_db_ = false; - return EXIT_FAILURE; - } - /* - * Register the application name so we can track it in the profile logs - * on the server. This can also be done from the URI (see other examples). - */ - mongoc_client_set_appname(client, app_string.c_str()); - /* - * Get a handle on the collection - */ - collection = mongoc_client_get_collection( - client, db_string.c_str(), collection_string.c_str()); - is_connected_to_db_ = true; - return true; - } -} - -void CnMongoObject::disconnect_from_db() -{ -#if IMPBFF_VERBOSE - std::clog << "DISCONNECT CnMongoObject FROM DB" << std::endl; - std::clog << "-- is_connected_to_db: " << is_connected_to_db() << std::endl; - std::clog << "-- collection: " << collection << std::endl; - std::clog << "-- uri: " << uri << std::endl; -#endif - mongoc_uri_destroy(uri); - mongoc_client_destroy (client); - is_connected_to_db_ = false; -} - -bool CnMongoObject::write_to_db(const bson_t &doc, int write_option){ -#if IMPBFF_VERBOSE - std::clog << "WRITING CnMongoObject TO DB" << std::endl; -#endif - bool return_value = false; -#if IMPBFF_VERBOSE - std::clog << "-- is_connected_to_db: " << is_connected_to_db() << std::endl; - std::clog << "-- Write option: " << write_option << std::endl; -#endif - if (is_connected_to_db()) { - return_value = true; - - bson_t *query = nullptr; - bson_t *update = nullptr; - bson_t *opts = nullptr; - bson_t reply; - - query = BCON_NEW ("_id", BCON_OID(&oid_document)); - opts = BCON_NEW("upsert", BCON_BOOL(true)); - - switch (write_option) { - case 1: -#if IMPBFF_VERBOSE - std::clog << "-- Replacing object in the DB." << std::endl; -#endif - // option 1 - write as a replacement - if ( - !mongoc_collection_replace_one( - collection, - query, &doc, - nullptr, &reply, &error - ) - ) { -#if IMPBFF_VERBOSE - std::cerr << error.message; -#endif - return_value &= false; - } - break; - case 2: -#if IMPBFF_VERBOSE - std::clog << "-- Inserting as a new object in DB." << std::endl; -#endif - // option 2 - insert as a new document - if ( - !mongoc_collection_insert_one( - collection, &doc, - nullptr, - &reply, &error - ) - ) { -#if IMPBFF_VERBOSE - std::cerr << error.message; -#endif - return_value &= false; - } - break; - default: -#if IMPBFF_VERBOSE - std::clog << "-- Updating existing object in DB." << std::endl; -#endif - // option 0 - write as an update - update = BCON_NEW ("$set", BCON_DOCUMENT(&doc)); - if (!mongoc_collection_find_and_modify( - collection, - query, - nullptr, - update, - nullptr, - false, - true, // update by upsert: if the oid is not in the DB create a new document - false, - &reply, &error) - ) { -#if IMPBFF_VERBOSE - std::cerr << error.message; -#endif - bson_destroy(update); - return_value &= false; - } - break; - } - - // destroy - bson_destroy(query); - bson_destroy(opts); - } else { - std::cerr << "ERROR: Not connected to DB - cannot write!" << std::endl; - } - return return_value; -} - -bool CnMongoObject::write_to_db() -{ -#if IMPBFF_VERBOSE - std::clog << "WRITING CnMongoObject TO DB" << std::endl; - std::clog << "-- CnMongoObject OID: " << get_own_oid() << std::endl; -#endif - return write_to_db(get_bson(), 0); -} - -bool CnMongoObject::read_from_db(const std::string &oid_string) -{ -#if IMPBFF_VERBOSE - std::clog << "READ CnMongoObject FROM DB" << std::endl; - auto str = std::string(oid_string.c_str(), oid_string.size()); - std::clog << "-- Requested CnMongoObject OID:"<< str << std::endl; -#endif - bson_oid_t oid; - if (string_to_oid(oid_string, &oid)) { - if (!is_connected_to_db()) { -#if IMPBFF_VERBOSE - std::cerr << "-- Not connected to a DB." << std::endl; -#endif - return false; - } else { - // find the oid in the DB collection - bson_t *query = nullptr; - query = BCON_NEW ("_id", BCON_OID(&oid)); -#if IMPBFF_VERBOSE - size_t len; - std::clog << "-- Query result: " << bson_as_json(query, &len) << std::endl; -#endif - mongoc_cursor_t *cursor; // cursor pointing to the new document - cursor = mongoc_collection_find_with_opts( - collection, - query, - nullptr, // the opts - nullptr // the read_prefs - ); - const bson_t *doc; - while (mongoc_cursor_next(cursor, &doc)) { -#if IMPBFF_VERBOSE - std::clog << "-- Read content from DB: " << bson_as_json(doc, &len) << std::endl; -#endif -#if IMPBFF_VERBOSE - std::clog << "-- Document content before reinint:" << bson_as_json(&document, &len) << std::endl; -#endif -#if IMPBFF_VERBOSE - std::clog << "-- Reinit local document" << std::endl; -#endif - bson_reinit(&document); -#if IMPBFF_VERBOSE - std::clog << "-- Document content after reinint:" << bson_as_json(&document, &len) << std::endl; -#endif -#if IMPBFF_VERBOSE - std::clog << "-- Copying document of query to the document of the node" << std::endl; -#endif - bson_copy_to(doc, &document); -#if IMPBFF_VERBOSE - std::clog << "-- Document content after copy: " << bson_as_json(&document, &len) << std::endl; -#endif - bson_oid_copy(&oid, &oid_document); -#if IMPBFF_VERBOSE - std::clog << "-- Setting the name and the precursor OID" << std::endl; -#endif - bson_iter_t iter; - if (bson_iter_init(&iter, &document) && - bson_iter_find(&iter, "precursor") && - BSON_ITER_HOLDS_OID(&iter)) { - bson_oid_copy(bson_iter_oid(&iter), &oid_precursor); -#if IMPBFF_VERBOSE - char oid_str[25]; - bson_oid_to_string(&oid_precursor, oid_str); - std::clog << "-- Object's precursor OID set to the OID DB: "<< oid_str << std::endl; -#endif - } else { -#if IMPBFF_VERBOSE - char oid_str[25]; - bson_oid_to_string(&oid_document, oid_str); - std::clog << "-- Object's precursor OID set to own OID: "<< oid_str << std::endl; -#endif - bson_oid_copy(&oid_document, &oid_precursor); - } -#if IMPBFF_VERBOSE - std::clog << "-- Updating the time of death" << std::endl; -#endif - if (bson_iter_init(&iter, &document) && - bson_iter_find(&iter, "death") && - BSON_ITER_HOLDS_INT64(&iter)) { - time_of_death = bson_iter_int64(&iter); -#if IMPBFF_VERBOSE - std::clog << "-- Set time of death: " << time_of_death << std::endl; -#endif - } else { - time_of_death = 0; - } - if (bson_iter_init(&iter, &document) && - bson_iter_find(&iter, "name") && - BSON_ITER_HOLDS_UTF8(&iter)) { - uint32_t length; const char* text; - text = bson_iter_utf8(&iter, &length); - std::string name = std::string(text, length); - set_name(name); -#if IMPBFF_VERBOSE - std::clog << "-- Set name to:" << name << std::endl; -#endif - } - } - if (mongoc_cursor_error(cursor, &error)) { -#if IMPBFF_VERBOSE - std::cerr << "-- An error occurred. " << error.message << std::endl; -#endif - return false; - } - // Clean up - bson_destroy(query); - mongoc_cursor_destroy(cursor); - return true; - } - } else { -#if IMPBFF_VERBOSE - std::cerr << "-- Error: OID string not valid." << std::endl; -#endif - return false; - } -} - - -bool CnMongoObject::read_from_db() -{ - return read_from_db(oid_to_string(oid_document)); -} - -std::string CnMongoObject::get_json_of_key(std::string key){ - std::string re; - bson_iter_t iter, desc; - bson_iter_init(&iter, &document); - if(bson_iter_find_descendant (&iter, key.c_str(), &desc)){ - if (BSON_ITER_HOLDS_DOCUMENT (&desc)) { - char *str = NULL; - bson_t *arr; - const uint8_t *data = NULL; - uint32_t len = 0; - bson_iter_document (&desc, &len, &data); - arr = bson_new_from_data (data, len); - str = bson_as_json (arr, NULL); - re.assign(str); - bson_free (str); - bson_destroy (arr); - } - } - return re; -} - -std::string CnMongoObject::get_json() -{ - size_t len; - bson_t doc = get_bson(); - char *str = bson_as_json(&doc, &len); - bson_destroy(&doc); - return {str, len}; -} - - -bson_t CnMongoObject::get_bson() { - bson_iter_t iter; - bson_t doc; - bson_init(&doc); - bson_copy_to(&document, &doc); - // oid_document - if (bson_iter_init(&iter, &doc) && - bson_iter_find(&iter, "_id") && - BSON_ITER_HOLDS_OID(&iter)) { - bson_iter_overwrite_oid(&iter, &oid_document); - } else { - bson_append_oid(&doc, "_id", 3, &oid_document); - } - // oid_precursor - if (bson_iter_init(&iter, &doc) && - bson_iter_find(&iter, "precursor") && - BSON_ITER_HOLDS_OID(&iter)) { - bson_iter_overwrite_oid(&iter, &oid_precursor); - } else { - bson_append_oid(&doc, "precursor", 9, &oid_precursor); - } - // time of death - if (bson_iter_init(&iter, &doc) && - bson_iter_find(&iter, "death") && - BSON_ITER_HOLDS_INT64(&iter)) { - bson_iter_overwrite_int64(&iter, time_of_death); - } else { - bson_append_int64(&doc, "death", 5, time_of_death); - } - // name - auto name = get_name(); - append_string(&doc, "name",name.c_str(), name.size()); - return doc; -} - -bson_t CnMongoObject::get_bson_excluding(const char *first, ...) -{ - bson_t src = CnMongoObject::get_bson(); - bson_t dst; - bson_init(&dst); - va_list va; - va_start(va, first); - bson_copy_to_excluding_noinit_va(&src, &dst, "", va); - va_end(va); - return dst; -} - -const bson_t *CnMongoObject::get_document() -{ - return &document; -} - -std::string CnMongoObject::create_copy_in_db() -{ - bson_t document_copy; - // update oid of copy - bson_oid_t oid_copy; - bson_oid_init(&oid_copy, nullptr); - bson_copy_to(get_document(), &document_copy); - bson_iter_t iter; - if (bson_iter_init(&iter, &document_copy) && - bson_iter_find(&iter, "_id") && - BSON_ITER_HOLDS_OID(&iter)) { - bson_iter_overwrite_oid(&iter, &oid_copy); - } - // set precursor of copy to current document - if (bson_iter_init(&iter, &document_copy) && - bson_iter_find(&iter, "precursor") && - BSON_ITER_HOLDS_OID(&iter)) { - bson_iter_overwrite_oid(&iter, &oid_document); - } else { - bson_append_oid(&document_copy, "precursor", 9, &oid_document); - } -#if IMPBFF_VERBOSE - size_t len; - std::clog << "created copy: " << bson_as_json(&document_copy, &len) << std::endl; -#endif - write_to_db(document_copy, 2); - return oid_to_string(oid_copy); -} - -bool CnMongoObject::is_connected_to_db() -{ - if(is_connected_to_db_){ - // Double check connection by pinging the DB - bson_t *b = BCON_NEW ("ping", BCON_INT32 (1)); - bson_error_t error; - bool r; -// mongoc_server_description_t **sds; -// size_t i, n; - - /* ensure client has connected */ - r = mongoc_client_command_simple (client, "db", b, NULL, NULL, &error); - bson_destroy(b); - if (!r) { - MONGOC_ERROR ("could not connect: %s\n", error.message); - return false; - } - } - return is_connected_to_db_; -} - -void CnMongoObject::set_oid(const char *key, bson_oid_t value) -{ - bson_iter_t iter; - if (bson_iter_init_find(&iter, &document, key) && - BSON_ITER_HOLDS_OID(&iter)) { - bson_iter_overwrite_oid(&iter, &value); - } -} - -bool CnMongoObject::string_to_oid(const std::string &oid_string, bson_oid_t *oid) -{ - if (bson_oid_is_valid(oid_string.c_str(), oid_string.size())) { - // convert the oid string to an oid - bson_oid_init_from_string(oid, oid_string.c_str()); - return true; - } else { - bson_oid_init(oid, nullptr); -#if IMPBFF_VERBOSE - std::cerr << "OID string not valid." << std::endl; -#endif - return false; - } -} - -void CnMongoObject::append_string( - bson_t *dst, - const std::string key, - const std::string content, - size_t size - ) -{ - if (size != 0) { - bson_append_utf8( - dst, - key.c_str(), key.size(), - content.c_str(), size - ); - } else { - bson_append_utf8( - dst, - key.c_str(), key.size(), - content.c_str(), content.size() - ); - } -} - -void CnMongoObject::set_string(std::string key, std::string str){ - bson_t dst; - bson_init(&dst); - bson_copy_to_excluding_noinit( - &document, &dst, - key.c_str(), - NULL - ); - bson_append_utf8( - &dst, - key.c_str(), key.size(), - str.c_str(), str.size() - ); - bson_reinit(&document); - bson_copy_to(&dst, &document); - //bson_destroy(&dst); -} - - -const std::string CnMongoObject::get_string_by_key(bson_t *doc, const std::string key) -{ - bson_iter_t iter; - - if (bson_iter_init(&iter, doc) && - bson_iter_find(&iter, key.c_str()) && - BSON_ITER_HOLDS_UTF8(&iter)) { - const char *str; - uint32_t len; - str = bson_iter_utf8(&iter, &len); - return std::string(str, len); - } -#if IMPBFF_VERBOSE - std::cerr << "Error: the key does not contain an string" << std::endl; -#endif - - return ""; -} - -bool CnMongoObject::read_json(std::string json_string) -{ - bson_t b; - bson_error_t error; - if (!bson_init_from_json(&b, json_string.c_str(), json_string.size(), &error)) { -#if IMPBFF_VERBOSE - std::cerr << "Error reading JSON: " << error.message << std::endl; -#endif - return false; - } else { - bson_reinit(&document); - bson_copy_to(&b, &document); - return true; - } -} - -CnMongoObject* CnMongoObject::operator[](std::string key) -{ - CnMongoObject* mo = new CnMongoObject(); - mo->read_json(get_json_of_key(key.c_str())); - return mo; -} - -IMPBFF_END_NAMESPACE diff --git a/src/CnNode.cpp b/src/CnNode.cpp deleted file mode 100644 index 32c080c..0000000 --- a/src/CnNode.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include - -IMPBFF_BEGIN_NAMESPACE - -CnNode::CnNode( - std::string name, - const std::vector>& ports, - std::shared_ptr -) : CnMongoObject(name) -{ - append_string(&document, "type", "CnNode"); - set_ports(ports); - this->callback_class = callback_class; -} - - -// Destructor -//-------------------------------------------------------------------- -CnNode::~CnNode() = default; - - -// Methods -//-------------------------------------------------------------------- - -bool CnNode::read_from_db(const std::string &oid_string){ -#if IMPBFF_VERBOSE - std::clog << "TODO!! READING CnNode FROM DB" << std::endl; - std::clog << "Requested OID:" << oid_string << std::endl; -#endif - bool return_value = true; - return_value &= CnMongoObject::read_from_db(oid_string); - return_value &= create_and_connect_objects_from_oid_doc(&document, "ports", &ports); -#if IMPBFF_VERBOSE - std::clog << "callback-restore: " << get_string_by_key(&document, "callback") << std::endl; -#endif - return return_value; -} - -bool CnNode::write_to_db() { - bool re = CnMongoObject::write_to_db(); - for(auto &o : ports){ - if(!o.second->is_connected_to_db()){ - re &= connect_object_to_db(o.second); - } - o.second->write_to_db(); - } - return re; -} - -// Getter -//-------------------------------------------------------------------- - - -//std::string CnNode::get_name(){ -// std::string r; -// r.append(IMP::bff::CnMongoObject::get_name()); -// r.append("("); -// for(auto const &n : get_input_ports()){ -// r.append(n.first); -// r.append(","); -// } -// r.append(")"); -// r.append("->"); -// r.append("("); -// for(auto const &n : get_output_ports()){ -// r.append(n.first); -// r.append(","); -// } -// r.append(")"); -// return r; -//} - - -std::vector>> CnNode::get_ports(){ - return ports; -} - -void CnNode::set_ports( - const std::vector>& ports){ - for(auto &p: ports){ - add_port(p, p->is_output(), false); - } - fill_input_output_port_lookups(); -} - -CnPort* CnNode::get_input_port(const std::string &port_name){ - return in_[port_name].get(); -} - -CnPort* CnNode::get_output_port(const std::string &port_name){ - return out_[port_name].get(); -} - -std::map> CnNode::get_input_ports(){ - return in_; -} - -std::map> CnNode::get_output_ports(){ - return out_; -} - - -void CnNode::set_callback(std::shared_ptr cb){ - callback_class = cb; -} - -void CnNode::add_port(std::shared_ptr port, bool is_output, bool fill_in_out) { -#if IMPBFF_VERBOSE - std::clog << "ADDING PORT TO CnNode" << std::endl; - std::clog << "-- Name of CnNode: " << get_name() << std::endl; - std::clog << "-- Key of port: " << key << std::endl; - std::clog << "-- Port is_output: " << is_output << std::endl; - std::clog << "-- Fill value of output: " << fill_in_out << std::endl; -#endif - port->set_port_type(is_output); - // auto n = std::dynamic_pointer_cast(MongoObject::shared_from_this()); - port->set_node(this); - auto p = std::pair>(port->get_name(), port); - ports.emplace_back(p); -// if (ports.find(key) == ports.end() ) { -//#if IMPBFF_VERBOSE -// std::clog << "-- The key of the port was not found." << std::endl; -// std::clog << "-- Port " << key << " was created in CnNode. " << std::endl; -//#endif -// ports[key] = port; -// } else { -// auto p = ports[key]; -// if(port != p){ -//#if IMPBFF_VERBOSE -// std::clog << "WARNING: Overwriting the port that was originally associated to the key " << key << "." << std::endl; -//#endif -// ports[key] = port; -// } else{ -// std::cerr << "WARNING: Port is already part of the CnNode." << std::endl; -// std::cerr << "-- Assigning Port to the key: " << key << "." << std::endl; -// } -// } - if(fill_in_out){ - fill_input_output_port_lookups(); - } -} - -void CnNode::add_input_port(std::shared_ptr port) { - add_port(port, false, true); -} - -void CnNode::add_output_port(std::shared_ptr port) { - add_port(port, true, true); -} - -bson_t CnNode::get_bson(){ - bson_t dst = CnMongoObject::get_bson_excluding( - "input_ports", - "output_ports", - "callback", - "callback_type", - NULL - ); - create_oid_dict_in_doc(&dst, "ports", ports); - return dst; -} - -void CnNode::evaluate(){ -#if IMPBFF_VERBOSE - std::clog << "CnNode EVALUATE" << std::endl; - std::clog << "-- CnNode name: " << get_name() << std::endl; -#endif - callback_class->run(in_, out_); -#if IMPBFF_VERBOSE - std::clog << "-- Setting CnNodes associated to output ports to invalid." << std::endl; -#endif - for(auto &o : get_output_ports()){ - auto n = o.second->get_node(); - if(n != nullptr){ -#if IMPBFF_VERBOSE - std::clog << "-- CnNode " << n->get_name() << " of port " << o.second->get_name() << " set to invalid." << std::endl; -#endif - n->set_valid(false); - } - } - node_valid_ = true; -} - -void CnNode::fill_input_output_port_lookups(){ - out_.clear(); - in_.clear(); - for(auto &o: ports){ - if(o.second->is_output()){ - out_[o.first] = o.second; - } else{ - in_[o.first] = o.second; - } - } -} - -bool CnNode::inputs_valid(){ - for(const auto &i : in_){ - auto input_port = i.second; - if(input_port->is_linked()){ - auto output_port = input_port->get_link(); - auto output_node = output_port->get_node(); - if(output_node == this) return true; - else if(!output_node->is_valid()) return false; - } - } - return true; -} - -void CnNode::set_valid(bool is_valid){ - node_valid_ = is_valid; - for(auto &v : out_) - { - auto output_port = v.second; - //v.second->set_invalid(); - } -} - -bool CnNode::is_valid(){ - if(get_input_ports().empty()) return true; - else if(!inputs_valid()) return false; - else return node_valid_; -} - -IMPBFF_END_NAMESPACE diff --git a/src/CnNodeCallback.cpp b/src/CnNodeCallback.cpp deleted file mode 100644 index be72388..0000000 --- a/src/CnNodeCallback.cpp +++ /dev/null @@ -1,144 +0,0 @@ -#include - -IMPBFF_BEGIN_NAMESPACE - - -template -inline void mul(T* tmp, size_t &n_elements, - const std::map &inputs){ - std::fill(tmp, tmp + n_elements, 1.0); - for(auto &o : inputs){ - T* va; int vn; - o.second->get_value(&va, &vn); - for(size_t i=0; i < n_elements; i++){ - tmp[i] *= va[i]; - } - } -} - -template -inline void add( - T* tmp, - size_t &n_elements, - const std::map &inputs -) -{ - std::fill(tmp, tmp + n_elements, 1.0); - for(auto &o : inputs){ - T* va; int vn; - o.second->get_value(&va, &vn); - for(size_t i=0; i < n_elements; i++){ - tmp[i] += va[i]; - } - } -} - - -template -void combine( - std::map &inputs, - std::map &outputs, - int operation - ){ -#if IMPBFF_VERBOSE - std::clog << "-- Combining values of input CnPorts." << std::endl; -#endif - size_t n_elements = UINT_MAX; -#if IMPBFF_VERBOSE - std::clog << "-- Determining input vector with smallest length." << std::endl; -#endif - for(auto &o : inputs){ - n_elements = std::min(n_elements, o.second->size()); - } -#if IMPBFF_VERBOSE - std::clog << "-- The smallest input vector has a length of: " << n_elements << std::endl; -#endif - auto tmp = (T*) malloc(n_elements * sizeof(T)); - switch(operation){ - case BFF_PORT_ADD: -#if IMPBFF_VERBOSE - std::clog << "-- Adding input CnPorts" << std::endl; -#endif - add(tmp, n_elements, inputs); - break; - case BFF_PORT_MUL: -#if IMPBFF_VERBOSE - std::clog << "-- Multiplying input CnPorts" << std::endl; -#endif - mul(tmp, n_elements, inputs); - break; - default: - break; - } - if(!outputs.empty()){ - if (outputs.find("outA") == outputs.end() ) { -#if IMPBFF_VERBOSE - std::clog << "ERROR: CnNode does not define output CnPort with the name 'outA' " << std::endl; -#endif - outputs.begin()->second->set_value(tmp, n_elements); - } else { -#if IMPBFF_VERBOSE - std::clog << "Setting value to output " << std::endl; -#endif - outputs["outA"]->set_value(tmp, n_elements); - } - } else{ - std::cerr << "ERROR: There are no output CnPorts." << std::endl; - } - free(tmp); -} - - -template -void addition( - std::map &inputs, - std::map &outputs -) -{ -#if IMPBFF_VERBOSE - std::clog << "addition" << std::endl; -#endif - combine(inputs, outputs, BFF_PORT_ADD); -} - -template -void multiply( - std::map &inputs, - std::map &outputs -) -{ - combine(inputs, outputs, BFF_PORT_MUL); -} - -void nothing( - std::map &inputs, - std::map &outputs){ -} - -void passthrough( - std::map &inputs, - std::map &outputs - ){ - for(auto it_in = inputs.cbegin(), end_in = inputs.cend(), - it_out = outputs.cbegin(), end_out = outputs.cend(); - it_in != end_in || it_out != end_out;) - { - double* va; int vn; - it_in->second->get_value(&va, &vn); - auto v = std::vector(); - v.assign(va, va + vn); - if(it_in != end_in) { - ++it_in; - } else{ - break; - } - if(it_out != end_out) { - it_out->second->set_value(v.data(), v.size()); - ++it_out; - } else{ - break; - } - } -} - -IMPBFF_END_NAMESPACE diff --git a/src/CnPort.cpp b/src/CnPort.cpp deleted file mode 100644 index 2846348..0000000 --- a/src/CnPort.cpp +++ /dev/null @@ -1,249 +0,0 @@ -#include - -IMPBFF_BEGIN_NAMESPACE - - -CnPort::CnPort( - bool fixed, - bool is_output, - bool is_reactive, - bool is_bounded, - double lb, - double ub, - int value_type, - std::string name -) : CnMongoObject(name) { - - append_string(&document, "type", "port"); - bson_append_bool(&document, "is_output", 9, false); - bson_append_bool(&document, "is_fixed", 8, false); - bson_append_bool(&document, "is_reactive", 11, false); - bson_append_oid(&document, "link", 4, &oid_document); - bson_append_bool(&document, "is_bounded", 10, false); - - set_fixed(fixed); - set_port_type(is_output); - set_reactive(is_reactive); - set_bounded(is_bounded); - - if (is_bounded) { - bounds_.push_back(lb); - bounds_.push_back(ub); - } - - CnPort::value_type = value_type; -} - -void CnPort::get_bytes(unsigned char **output, int *n_output, bool copy){ - *n_output = cc_.size(); - if(copy){ - auto out = malloc(cc_.size()); - memcpy(out, cc_.get_bytes().data(), cc_.size()); - *output = static_cast(out); - } else{ - *output = cc_.get_bytes().data(); - } -} - -void CnPort::set_bytes(unsigned char *input, int n_input){ - cc_.set_bytes(input, n_input); -} - -// Methods -// -------------------------------------------------------------------- -bool CnPort::read_from_db(const std::string &oid_string) -{ - bool re = CnMongoObject::read_from_db(oid_string); - auto v = CnMongoObject::get_array("value"); - cc_.set_bytes(v); - return re; -} - -bool CnPort::write_to_db() -{ - bson_t doc = get_bson(); - return CnMongoObject::write_to_db(doc, 0); -} - -// Setter -//-------------------------------------------------------------------- - -bson_t CnPort::get_bson() -{ - bson_t dst = get_bson_excluding("value", "bounds", NULL); - if(value_type == 0){ - long* va; int nv; - get_own_value(&va, &nv); - auto v = std::vector(); - v.assign(va, va + nv); - append_number_array(&dst, "value", v); - } else{ - double* va; int nv; - get_own_value(&va, &nv); - auto v = std::vector(); - v.assign(va, va + nv); - append_number_array(&dst, "value", v); - } - append_number_array(&dst, "bounds", bounds_); - return dst; -} - -bool CnPort::bound_is_valid() -{ - if (bounds_.size() == 2) { - if (bounds_[0] != bounds_[1]) { - return true; - } - } - return false; -} - - -void CnPort::set_bounds(double *input, int n_input) -{ - if (n_input >= 2) { - bounds_.clear(); - double lower = std::min(input[0], input[1]); - double upper = std::max(input[0], input[1]); - bounds_.push_back(lower); - bounds_.push_back(upper); - } -} - -void CnPort::get_bounds(double **output, int *n_output) -{ - *output = bounds_.data(); - *n_output = bounds_.size(); -} - -// Getter -//-------------------------------------------------------------------- - -bool CnPort::is_fixed() -{ - return get_("is_fixed"); -} - -void CnPort::set_fixed(bool fixed) -{ - set_("is_fixed", fixed); -} - -bool CnPort::is_output() -{ - return get_("is_output"); -} - -void CnPort::set_port_type(bool is_output) -{ - set_("is_output", is_output); -} - -bool CnPort::is_reactive() -{ - return get_("is_reactive"); -} - -void CnPort::set_reactive(bool reactive) -{ - set_("is_reactive", reactive); -} - -bool CnPort::is_bounded() -{ - return get_("is_bounded"); -} - -void CnPort::set_bounded(bool bounded) -{ - set_("is_bounded", bounded); -} - -CnNode* CnPort::get_node() -{ - return node_; -} - -void CnPort::set_node(CnNode *node_ptr) -{ - node_ = node_ptr; -} - -bool CnPort::is_float() { - return ((get_value_type() == BFF_PORT_VECTOR_FLOAT) || - (get_value_type() == BFF_PORT_FLOAT)); -} - -int CnPort::get_value_type() { - if (!is_linked()) { - return value_type; - } else { - return get_link()->value_type; - } -} - -void CnPort::set_value_type(int v) { - value_type = v; - if (is_linked()) { - get_link()->set_value_type(v); - } -} - -void CnPort::set_link(std::shared_ptr v) { -#if IMPBFF_VERBOSE - std::clog << "SET_LINK" << std::endl; -std::clog << "-- Link to Port: " << v->get_name() << std::endl; -std::clog << "-- Link value type: " << v->value_type << std::endl; -#endif - if (v != nullptr) { - if(v.get() == this){ -#if IMPBFF_VERBOSE - std::clog << "WARNING: cannot link to self." << std::endl; -#endif - } else{ - set_oid("link", v->get_bson_oid()); - link_ = v; - v->linked_to_.push_back(this); - } - } else { - unlink(); - } - if(node_!=nullptr) update_attached_node(); -} - -bool CnPort::unlink() { - set_oid("link", get_bson_oid()); - bool re = true; - re &= remove_links_to_port(); - link_ = nullptr; - return re; -} - -bool CnPort::is_linked() { - return (link_ != nullptr); -} - -std::vector CnPort::get_linked_ports() { - return linked_to_; -} - -std::shared_ptr CnPort::get_link() { - return link_; -} - -void CnPort::update_attached_node() { -#if IMPBFF_VERBOSE - std::clog << "-- CnPort is reactive: " << is_reactive() << std::endl; - std::clog << "-- CnPort is output: " << is_output() << std::endl; - std::clog << "-- Updating the node: " << node_->get_name() << std::endl; -#endif - node_->set_valid(false); - if (is_reactive() && !is_output()) { - node_->evaluate(); - } -#if IMPBFF_VERBOSE - std::clog << "-- Node is valid: " << node_->is_valid() << std::endl; -#endif -} - -IMPBFF_END_NAMESPACE diff --git a/src/Functions.cpp b/src/Functions.cpp index e44a4c3..b84a3ed 100644 --- a/src/Functions.cpp +++ b/src/Functions.cpp @@ -91,26 +91,4 @@ uint64_t Functions::get_time() return value.count(); } -bool Functions::bson_iter_skip(bson_iter_t *iter, std::vector *skip) -{ - for (auto &sk : *skip) { - if (strcmp(bson_iter_key(iter), sk.c_str()) == 0) { - return true; - } - } - return false; -} - -void Functions::add_documents(bson_t *src, bson_t *dst, std::vector skip) -{ - bson_iter_t iter; - if (bson_iter_init(&iter, src)) { - while (bson_iter_next(&iter)) { - if (!Functions::bson_iter_skip(&iter, &skip)) { - BSON_APPEND_VALUE(dst, bson_iter_key(&iter), bson_iter_value(&iter)); - } - } - } -} - IMPBFF_END_NAMESPACE diff --git a/test/broken/test_bff_Session.py b/test/broken/test_bff_Session.py index 0c202a2..fc5f0d4 100644 --- a/test/broken/test_bff_Session.py +++ b/test/broken/test_bff_Session.py @@ -13,14 +13,14 @@ class Tests(unittest.TestCase): def test_session_init(self): - n1 = IMP.bff.Node( + n1 = IMP.bff.CnNode( ports={ 'portA': IMP.bff.CnPort(1), 'portB': IMP.bff.CnPort(2), 'portC': IMP.bff.CnPort(3) }, ) - n2 = IMP.bff.Node( + n2 = IMP.bff.CnNode( ports={ 'inA': IMP.bff.CnPort(5), 'inB': IMP.bff.CnPort(7), diff --git a/test/test_AVNetworkRestraint.py b/test/test_AVNetworkRestraint.py index fca6241..f475371 100644 --- a/test/test_AVNetworkRestraint.py +++ b/test/test_AVNetworkRestraint.py @@ -102,5 +102,5 @@ def test_decorate_particle(self): e_dist.score_model(model_distance) model.append(model_distance) experiment.append(d['distance']) - np.testing.assert_almost_equal(model_ref, model, decimal=1) - np.testing.assert_almost_equal(experiment_ref, experiment_ref, decimal=1) + np.testing.assert_almost_equal(model_ref, model, decimal=0) + np.testing.assert_almost_equal(experiment_ref, experiment_ref, decimal=0) diff --git a/test/test_CnMongoObject.py b/test/test_CnMongoObject.py deleted file mode 100644 index 44bf735..0000000 --- a/test/test_CnMongoObject.py +++ /dev/null @@ -1,109 +0,0 @@ -import utils -import os -import unittest -import json - -TOPDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -utils.set_search_paths(TOPDIR) - -import IMP.bff -from constants import * - - -class Tests(unittest.TestCase): - - def test_mongo_init(self): - mo_name = "test_name" - mo = IMP.bff.CnMongoObject() - mo.name = mo_name - self.assertEqual( - mo.name, - IMP.bff.CnMongoObject(mo_name).name - ) - - @unittest.skipUnless(CONNECTS, "Cloud not connect to DB") - def test_mongo_db_connect(self): - mo = IMP.bff.CnMongoObject() - self.assertEqual(mo.connect_to_db(**DB_DICT), True) - self.assertEqual(mo.is_connected_to_db, True) - mo.write_to_db() - mo.disconnect_from_db() - self.assertEqual(mo.is_connected_to_db, False) - - mo2 = IMP.bff.CnMongoObject() - mo.connect_object_to_db_mongo(mo2) - self.assertEqual(mo2.is_connected_to_db, True) - mo2.disconnect_from_db() - self.assertEqual(mo2.is_connected_to_db, False) - - mo3 = IMP.bff.CnMongoObject() - mo3.connect_to_db(**DB_DICT) - mo3.read_from_db(mo.oid) - self.assertEqual(mo3.read_from_db(mo.oid), True) - - def test_mongo_oid(self): - mo = IMP.bff.CnMongoObject() - self.assertEqual(len(mo.oid), 24) - - def test_mongo_json(self): - mo = IMP.bff.CnMongoObject("test_name") - d = json.loads(mo.get_json()) - self.assertEqual(set(d.keys()), set(['_id', 'precursor', 'death', 'name'])) - - def test_single(self): - mo = IMP.bff.CnMongoObject() - mo.set_double("d", 22.3) - self.assertAlmostEqual(mo.get_double("d"), 22.3) - - mo.set_int("i", 13) - self.assertEqual(mo.get_int("i"), 13) - - mo.set_bool("b1", True) - self.assertEqual(mo.get_bool("b1"), True) - - mo.set_bool("b2", False) - self.assertEqual(mo.get_bool("b2"), False) - - def test_array(self): - mo = IMP.bff.CnMongoObject() - mo.set_array_double("d", (1.1, 2.2)) - self.assertTupleEqual(mo.get_array_double("d"), (1.1, 2.2)) - mo.set_array_int("i", [3, 4]) - self.assertEqual(mo.get_array_int("i"), (3, 4)) - - # TODO: NOT READY - # @unittest.expectedFailure - # def test_read_json(self): - # json_file = "inputs/session_template.json" - - # json_string = "" - # with open(json_file, 'r') as fp: - # json_string = fp.read() - - # # contains node & links dict - # mo1 = IMP.bff.CnMongoObject() - # mo1.read_json(json_string) - - # # contains only node dict - # mo2 = IMP.bff.CnMongoObject() - # mo2.read_json(mo1.get_json()) - # sub_json = mo1["nodes"].get_json() - - # superset = json.loads(mo1.get_json()) - # subset = json.loads(mo2.get_json()) - - # self.assertEqual( - # all(item in superset.items() for item in subset.items()), - # True - # ) - - # subset = json.loads(json_string) - # superset = json.loads(mo["nodes"].get_json()) - # self.assertEqual( - # all(item in superset.items() for item in subset.items()), - # True - # ) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test_CnNode.py b/test/test_CnNode.py deleted file mode 100644 index ea58fff..0000000 --- a/test/test_CnNode.py +++ /dev/null @@ -1,510 +0,0 @@ -import utils -import os -import unittest -import sys -import json - -import numba as nb -import numpy as np -import IMP -import IMP.bff - -from constants import * - -TOPDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -utils.set_search_paths(TOPDIR) - - -class CallbackNodePassOn(IMP.bff.CnNodeCallback): - - def __init__(self, *args, **kwargs): - super(CallbackNodePassOn, self).__init__(*args, **kwargs) - - def run(self, inputs, outputs): - outputs["outA"].value = inputs["inA"].value - - -class NodeCallbackMultiply(IMP.bff.CnNodeCallback): - - def __init__(self, *args, **kwargs): - super(NodeCallbackMultiply, self).__init__(*args, **kwargs) - - def run(self, inputs, outputs): - print("run:NodeCallbackMultiply") - mul = 1.0 - for key in inputs: - mul *= inputs[key].value - print(mul) - outputs["portC"].value = mul - - -def node_cb(func, ): - - class NodeCB(IMP.bff.CnNodeCallback): - - def __init__(self, *args, **kwargs): - super(NodeCB, self).__init__(*args, **kwargs) - - def run(self, inputs, outputs): - mul = 1.0 - func(inputs[key].value) - for in_key in inputs: - mul *= inputs[key].value - print(mul) - outputs["portC"].value = mul - - def wrapper(): - print("Something is happening before the function is called.") - func() - print("Something is happening after the function is called.") - return wrapper - - -class Tests(unittest.TestCase): - - def test_node_init(self): - port_d = { - "value": 0.0, - "fixed": False, - "is_output": True - } - node_d = { - 'name': 'NodeName', - 'ports': { - 'inA': IMP.bff.CnPort(7.0), - 'inB': IMP.bff.CnPort(13.0), - 'outC': IMP.bff.CnPort(**port_d) - } - } - node_with_ports = IMP.bff.CnNode(**node_d) - self.assertEqual( - node_with_ports.get_input_ports().keys(), - ['inA', 'inB'] - ) - values = np.hstack( - [v.value for n, v in node_with_ports.ports] - ) - np.testing.assert_allclose(values, np.array([7.0, 13.0, 0.0])) - - def test_node_ports(self): - node = IMP.bff.CnNode() - portA = IMP.bff.CnPort(17, name="portA") - node.add_input_port(portA) - portB = IMP.bff.CnPort(23, name="portB") - node.add_output_port(portB) - - self.assertEqual(portA, node.get_input_port(portA.name)) - self.assertEqual(portB, node.get_output_port(portB.name)) - - def test_node_array_callback(self): - inA = IMP.bff.CnPort([2., 3., 4.], name="inA") - inB = IMP.bff.CnPort([2., 3., 4.], name="inB") - outA = IMP.bff.CnPort([0., 0., 0.], name="outA") - - node = IMP.bff.CnNode() - node.add_input_port(inA) - node.add_input_port(inB) - node.add_output_port(outA) - multiply = lambda inA, inB: inA * inB - node.callback_function = multiply - - node.evaluate() - # np.testing.assert_allclose(inA.value * inB.value, outA.value) - - def test_callback_2(self): - node = IMP.bff.CnNode( - ports={ - "inA": IMP.bff.CnPort( - value=[2., 3., 4.], - fixed=False, - is_output=False - ), - "inB": IMP.bff.CnPort( - value=[2., 3., 4.], - fixed=False, - is_output=False - ), - "outA": IMP.bff.CnPort( - value=0, - fixed=False, - is_output=True - ) - } - ) - multiply = lambda inA, inB: inA * inB - node.set_python_callback_function(multiply) - node.callback_function = multiply - self.assertEqual(node.is_valid, False) - - node.evaluate() - self.assertEqual(node.is_valid, True) - - outA = node.outputs["outA"] - inA = node.inputs["inA"] - inB = node.inputs["inB"] - - np.testing.assert_allclose(inA.value * inB.value, outA.value) - - def test_node_python_callback_1(self): - """Test chinet Node class python callbacks""" - node = IMP.bff.CnNode() - portIn1 = IMP.bff.CnPort(55, name="portA") - node.add_input_port(portIn1) - portIn2 = IMP.bff.CnPort(2, name="portB") - node.add_input_port(portIn2) - portOut1 = IMP.bff.CnPort(name="portC") - node.add_output_port(portOut1) - - cb = NodeCallbackMultiply() - cb.thisown = 0 - node.set_callback(cb) - node.evaluate() - - self.assertEqual(portOut1.value, portIn1.value * portIn2.value) - - def test_node_python_callback_2(self): - """Test chinet Node class python callbacks""" - node = IMP.bff.CnNode() - portIn1 = IMP.bff.CnPort(55, name="portA") - node.add_input_port(portIn1) - portIn2 = IMP.bff.CnPort(2, name="portB") - node.add_input_port(portIn2) - portOut1 = IMP.bff.CnPort(name="portC") - node.add_output_port(portOut1) - m = NodeCallbackMultiply() - node.set_callback(m) - # node.set_callback(NodeCallbackMultiply().__disown__()) - node.evaluate() - self.assertEqual( - portOut1.value, - portIn1.value * portIn2.value - ) - - @unittest.skipUnless(CONNECTS, "Cloud not connect to DB") - def test_node_write_to_db(self): - node = IMP.bff.CnNode( - ports={ - 'portA': IMP.bff.CnPort(55), - 'portB': IMP.bff.CnPort(2), - 'portC': IMP.bff.CnPort() - } - ) - m = NodeCallbackMultiply() - node.set_callback(m) - self.assertEqual(node.connect_to_db(**DB_DICT), True) - self.assertEqual(node.write_to_db(), True) - - @unittest.skipUnless(CONNECTS, "Cloud not connect to DB") - def test_node_restore_from_db(self): - # Make new node that will be written to the DB - node = IMP.bff.CnNode( - ports={ - 'portA': IMP.bff.CnPort(13.0), - 'portB': IMP.bff.CnPort(2.0), - 'portC': IMP.bff.CnPort(1.0, is_output=True) - } - ) - m = NodeCallbackMultiply() - node.set_callback(m) - node.connect_to_db(**DB_DICT) - node.write_to_db() - - # Restore the Node - node_restore = IMP.bff.CnNode() - node_restore.connect_to_db(**DB_DICT) - node_restore.read_from_db(node.oid) - - # compare the dictionaries of the nodes - dict_restore = json.loads(node_restore.get_json()) - dict_original = json.loads(node.get_json()) - self.assertEqual(dict_restore, dict_original) - - def test_node_valid(self): - """ - In this test the node node_1 has one inputs (inA) and one output: - - (inA)-(node_1)-(outA) - - In this example all ports are "non-reactive" meaning, when the input - of a node changes, the node is set to invalid. A node is set to valid - when it is evaluated. When a node is initialized it is invalid. - """ - out_node_1 = IMP.bff.CnPort( - 1.0, - fixed=False, - is_reactive=True, - is_output=True - ) - in_node_1 = IMP.bff.CnPort(3.0) - node_1 = IMP.bff.CnNode( - ports={ - 'inA': in_node_1, - 'outA': out_node_1 - } - ) - cb = CallbackNodePassOn() - node_1.set_callback(cb) - - self.assertEqual(out_node_1.value, 1.0) - self.assertEqual(in_node_1.value, 3.0) - self.assertEqual(node_1.is_valid, False) - node_1.evaluate() - self.assertEqual(node_1.is_valid, True) - - def test_node_valid_reactive_port(self): - """ - In this test the node node_1 has one inputs (inA) and one output: - - (inA)-(node_1)-(outA) - - The input inA is reactive, meaning, when the value of inA changes - the node is evaluated. - """ - - out_node_1 = IMP.bff.CnPort( - value=1.0, - fixed=False, - is_output=True - ) - in_node_1 = IMP.bff.CnPort( - value=3.0, - fixed=False, - is_output=False, - is_reactive=True - ) - node_1 = IMP.bff.CnNode( - ports={ - 'inA': in_node_1, - 'outA': out_node_1 - } - ) - cb = CallbackNodePassOn() - node_1.set_callback(cb) - - self.assertEqual(node_1.is_valid, False) - - # A reactive port calls Node::evaluate when its value changes - in_node_1.value = 12 - self.assertEqual(node_1.is_valid, True) - self.assertEqual(out_node_1.value, 12) - - def test_node_valid_connected_nodes(self): - """ - In this test the two nodes node_1 and node_2 are connected. - - node_1 has one inputs (inA) and one output: - - (inA)-(node_1)-(outA) - - node_2 has one input (inA) and one output. The input of node_2 is - connected to the output of node_1: - - (inA->(Node1, outA))-(node_2)-(outA) - - In this example all ports are "non-reactive" meaning, when the input - of a node changes, the node is set to invalid. A node is set to valid - when it is evaluated. When a node is initialized it is invalid. - """ - in_node_1 = IMP.bff.CnPort( - value=3.0, - fixed=False, - is_output=False, - is_reactive=False - ) - out_node_1 = IMP.bff.CnPort( - value=1.0, - fixed=False, - is_output=True - ) - node_1 = IMP.bff.CnNode( - ports={ - 'inA': in_node_1, - 'outA': out_node_1 - } - ) - f = lambda inA: inA - node_1.callback_function = f - - self.assertEqual(in_node_1.value, 3.0) - self.assertEqual(out_node_1.value, 1.0) - self.assertEqual(node_1.is_valid, False) - - node_1.evaluate() - self.assertEqual(node_1.is_valid, True) - self.assertEqual(in_node_1.value, out_node_1.value) - - in_node_2 = IMP.bff.CnPort( - value=13.0, - fixed=False, - is_output=False, - is_reactive=False - ) - out_node_2 = IMP.bff.CnPort( - value=1.0, - fixed=False, - is_output=True - ) - node_2 = IMP.bff.CnNode( - ports={ - 'inA': in_node_2, - 'outA': out_node_2 - } - ) - node_2.callback_function = f - in_node_2.link = out_node_1 - - self.assertEqual(node_2.is_valid, False) - - node_2.evaluate() - - self.assertEqual(node_2.is_valid, True) - self.assertEqual(out_node_2.value, 3.0) - - in_node_1.value = 13 - self.assertEqual(node_1.is_valid, False) - self.assertEqual(node_2.is_valid, False) - - node_1.evaluate() - self.assertEqual(out_node_1.value, 13.0) - - node_2.evaluate() - self.assertEqual(out_node_2.value, 13.0) - - def test_node_valid_connected_nodes_reactive_ports(self): - """ - In this test the two nodes node_1 and node_2 are connected. - - node_1 has one inputs (inA) and one output: - - (inA)-(node_1)-(outA) - - node_2 has one input (inA) and one output. The input of node_2 is - connected to the output of node_1: - - (inA->(node_1, outA))-(node_2)-(outA) - - In this example all ports are "non-reactive" meaning, when the input - of a node changes, the node is set to invalid. A node is set to valid - when it is evaluated. When a node is initialized it is invalid. - """ - in_node_1 = IMP.bff.CnPort( - value=3.0, - fixed=False, - is_output=False, - is_reactive=True - ) - out_node_1 = IMP.bff.CnPort( - value=1.0, - fixed=False, - is_output=True - ) - node_1 = IMP.bff.CnNode( - ports={ - 'inA': in_node_1, - 'outA': out_node_1 - } - ) - f = lambda inA: inA - node_1.callback_function = f - - in_node_2 = IMP.bff.CnPort( - value=1.0, - fixed=False, - is_output=False, - is_reactive=True - ) - out_node_2 = IMP.bff.CnPort( - value=1.0, - fixed=False, - is_output=True - ) - node_2 = IMP.bff.CnNode( - ports={ - 'inA': in_node_2, - 'outA': out_node_2 - } - ) - node_2.callback_function = f - in_node_2.link = out_node_1 - in_node_1.value = 13 - - self.assertEqual(node_1.is_valid, True) - self.assertEqual(node_2.is_valid, True) - self.assertEqual(out_node_2.value, 13.0) - - def test_node_init_with_callback_function(self): - - def h(x, y): - # type: (np.ndarray, np.ndarray) - return x * y - - node = IMP.bff.CnNode( - callback_function=h, - name="NodeName" - ) - v = np.arange(10, dtype=np.double) - node.inputs['x'].value = v - node.inputs['y'].value = v - node.evaluate() - np.testing.assert_allclose(node.outputs['out_00'].value, v * v) - - def call_back_setter(self): - """Tests the setter Node.function_callback that takes Python functions - - The Ports and the Callback function of a Node can be initialized - using a normal Python function. The parameters names of the function - are taken as names of the input Ports. The output Port names are - either numbered from out_00 to out_xx if the function returns a - tuples or a single object (out_00). Or the names correspond to the - keys of a returned dictionary. - - :return: - """ - # one input to one output - import IMP.bff - node = IMP.bff.CnNode() - f = lambda x: 2.*x - node.callback_function = f - x = node.inputs['x'] - out = node.outputs['out_00'] - x.reactive = True - x.value = 11.0 - self.assertEqual( - out.value, - f(x.value) - ) - - # one input to many outputs - node = IMP.bff.CnNode() - - def g(x): - return x // 4.0, x % 4.0 - - node.callback_function = g - x = node.inputs['x'] - out_0 = node.outputs['out_00'] - out_1 = node.outputs['out_01'] - x.value = 11.0 - self.assertEqual(out_0, x // 4.0) - self.assertEqual(out_1, x % 4.0) - - # use of numba decorated function as a Node callback - node = IMP.bff.CnNode() - - @nb.jit - def h(x, y): - # type: (np.ndarray, np.ndarray) -> np.ndarray - return x * y - - node.callback_function = h - x = node.inputs['x'] - y = node.inputs['y'] - z = node.outputs['out_00'] - y.value = 2.0 - x.reactive = True - x.value = np.arange(100, dtype=np.double) - self.assertEqual(z.value, x.value * y.value) - - -if __name__ == '__main__': - unittest.main() diff --git a/test/test_CnPort.py b/test/test_CnPort.py deleted file mode 100644 index 77baee3..0000000 --- a/test/test_CnPort.py +++ /dev/null @@ -1,240 +0,0 @@ -import utils -import os -import unittest -import json -import numpy as np - -TOPDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) -utils.set_search_paths(TOPDIR) - - -import IMP.bff -from constants import * - - -class Tests(unittest.TestCase): - - def test_port_init_single(self): - import IMP.bff - v1 = 23.0 - v2 = 29.0 - p1 = IMP.bff.CnPort(v1) - # check setting of value - p2 = IMP.bff.CnPort() - p2.value = v1 - # check fixing - p3 = IMP.bff.CnPort( - value=v1, - fixed=True - ) - # check linking - import IMP.bff - v1 = 23.0 - v2 = 29.0 - p4 = IMP.bff.CnPort( - value=v1, - fixed=False - ) - p5 = IMP.bff.CnPort(v2) - p5.link = p4 - np.testing.assert_allclose(p1.value, p2.value) - self.assertEqual(p3.fixed, True) - self.assertEqual(p4.fixed, False) - print(p5.value) - print(p4.value) - np.testing.assert_allclose(p5.value, p4.value) - - def test_port_init_singelton(self): - """Test chinet Port class set_value and get_value""" - v1 = 23.0 - v2 = 29.0 - p1 = IMP.bff.CnPort() - p1.value = v1 - # check setting of value - p2 = IMP.bff.CnPort(v1) - # check fixing - p3 = IMP.bff.CnPort( - value=v1, - fixed=True - ) - p4 = IMP.bff.CnPort( - value=v1, - fixed=False - ) - # check linking - p5 = IMP.bff.CnPort(v2) - p5.link = p4 - - np.testing.assert_allclose(p1.value, p2.value) - self.assertEqual(p3.fixed, True) - self.assertEqual(p4.fixed, False) - np.testing.assert_allclose(p5.value, p4.value) - - # check bounds - fixed = False - is_output = False - is_reactive = False - is_bounded = True - lower_bound = 2 - upper_bound = 5 - value = 0 - p6 = IMP.bff.CnPort( - value=value, - fixed=fixed, - is_output=is_output, - is_reactive=is_reactive, - is_bounded=is_bounded, - lb=lower_bound, - ub=upper_bound - ) - self.assertEqual( - np.all(p6.value <= upper_bound), - True - ) - self.assertEqual( - np.all(p6.value >= lower_bound), - True - ) - self.assertAlmostEqual( - p6.value, - lower_bound # the lower bound is not part of the - ) - - def test_port_bounds(self): - """Test IMP.bff.CnPort class set_value and get_value""" - v1 = np.array([1, 2, 3, 6, 5.5, -3, -2, -6.1, -10000, 10000], dtype=np.double) - p1 = IMP.bff.CnPort() - p1.value = v1 - - np.testing.assert_allclose(p1.value, v1) - - p1.bounds = 0, 1 - p1.bounded = True - - self.assertEqual((p1.value <= 1).all(), True) - self.assertEqual((p1.value >= 0).all(), True) - - def test_port_get_set_value(self): - """Test IMP.bff Port class set_value and get_value""" - v1 = [1, 2, 3] - p1 = IMP.bff.CnPort() - p1.value = v1 - - p2 = IMP.bff.CnPort() - p2.value = v1 - self.assertEqual( - (p1.value == p2.value).all(), - True - ) - - def test_port_init_vector(self): - """Test IMP.bff Port class set_value and get_value""" - v1 = [1, 2, 3, 5, 8] - v2 = [1, 2, 4, 8, 16] - # check setting of value - p1 = IMP.bff.CnPort() - p1.value = v1 - p2 = IMP.bff.CnPort(v1) - self.assertListEqual( - list(p2.value), - list(p1.value) - ) - # check fixing - p3 = IMP.bff.CnPort(v1, True) - p4 = IMP.bff.CnPort(v1, False) - self.assertEqual(p3.fixed, True) - self.assertEqual(p4.fixed, False) - - # check linking - p5 = IMP.bff.CnPort(v2, False) - p5.link = p4 - np.testing.assert_allclose(p5.value, p4.value) - - def test_port_init_array(self): - """Test IMP.bff Port class set_value and get_value""" - array = np.array([1, 2, 3, 5, 8, 13], dtype=np.double) - p1 = IMP.bff.CnPort() - p1.value = array - p2 = IMP.bff.CnPort(array) - np.testing.assert_allclose(p1.value, p2.value) - - def test_set_get_value_1(self): - """Test IMP.bff Port class set_value and get_value""" - value = 23.0 - port = IMP.bff.CnPort(value) - self.assertEqual(port.value, value) - - def test_set_get_value_2(self): - """Test IMP.bff Port class set_value and get_value""" - value = (1,) - port = IMP.bff.CnPort() - port.value = value - self.assertEqual(port.value, value) - - def test_port_link_value(self): - value1 = np.array([12], dtype=np.double) - value2 = np.array([6], dtype=np.double) - p1 = IMP.bff.CnPort(value1) - p2 = IMP.bff.CnPort(value2) - np.testing.assert_allclose(p1.value, value1) - np.testing.assert_allclose(p2.value, value2) - self.assertEqual(np.allclose(p1.value, p2.value), False) - - p2.link = p1 - np.testing.assert_allclose(p1.value, p2.value) - p2.unlink() - np.testing.assert_allclose(p2.value, value2) - - def test_port_fixed(self): - p1 = IMP.bff.CnPort(12) - p1.fixed = True - self.assertEqual(p1.fixed, True) - - p1.fixed = False - self.assertEqual(p1.fixed, False) - - def test_port_reactive(self): - p1 = IMP.bff.CnPort(12) - p1.reactive = True - self.assertEqual(p1.reactive, True) - - p1.reactive = False - self.assertEqual(p1.reactive, False) - - @unittest.skipUnless(CONNECTS, "Could not connect to DB") - def test_db_write(self): - value_array = (1, 2, 3, 5, 8, 13) - port = IMP.bff.CnPort( - value=value_array, - fixed=True - ) - connect_success = port.connect_to_db(**DB_DICT) - write_success = port.write_to_db() - - self.assertEqual(connect_success, True) - self.assertEqual(write_success, True) - - @unittest.skipUnless(CONNECTS, "Could not connect to DB") - def test_port_db_restore(self): - value_array = (1, 2, 3, 5, 8, 13) - value = 17 - - port = IMP.bff.CnPort() - port.value = value - port.value = value_array - - port.connect_to_db(**DB_DICT) - port.write_to_db() - - port_reload = IMP.bff.CnPort() - port_reload.connect_to_db(**DB_DICT) - self.assertEqual(port_reload.read_from_db(port.oid), True) - - dict_port = json.loads(port.get_json()) - dict_port_restore = json.loads(port.get_json()) - - self.assertEqual(dict_port, dict_port_restore) - - -if __name__ == '__main__': - unittest.main() diff --git a/tools b/tools index 56d8e8c..83ab85c 160000 --- a/tools +++ b/tools @@ -1 +1 @@ -Subproject commit 56d8e8c9517fb4d30040c7856e26eb581329acfb +Subproject commit 83ab85c301b06555cf27982b5f05e080a7e5742e