From 4ea67c70a58acc55a8eee44af20f8bf0887577b7 Mon Sep 17 00:00:00 2001 From: David Cosgrove Date: Mon, 14 Apr 2025 17:03:50 +0100 Subject: [PATCH] Support pickling Shape inputs (#8434) * Stash for transfer. * Basic serialization. * Serialization of ShapeInput. * Default c'tor and operator=. * Response to review. * Add cmake to macOS CI image. * Add make, not cmake. * Conditional serialization test. --------- Co-authored-by: David Cosgrove --- .azure-pipelines/mac_build.yml | 2 +- .azure-pipelines/mac_build_java.yml | 2 +- External/pubchem_shape/PubChemShape.hpp | 56 +++++++++++++++++++++++-- External/pubchem_shape/test.cpp | 21 ++++++++++ 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/.azure-pipelines/mac_build.yml b/.azure-pipelines/mac_build.yml index d46140deb..8d68d379e 100644 --- a/.azure-pipelines/mac_build.yml +++ b/.azure-pipelines/mac_build.yml @@ -27,7 +27,7 @@ steps: libboost-python=$(boost_version) libboost-python-devel=$(boost_version) \ qt \ numpy matplotlib=3.8 cairo pillow eigen pandas=2.1 \ - jupyter=1.0 ipython=8.20 sphinx myst-parser pytest nbval + jupyter=1.0 ipython=8.20 sphinx myst-parser pytest nbval make displayName: Setup build environment - bash: | export CONDA=/tmp/miniforge diff --git a/.azure-pipelines/mac_build_java.yml b/.azure-pipelines/mac_build_java.yml index 6ffc8c36f..9d2bceaf6 100644 --- a/.azure-pipelines/mac_build_java.yml +++ b/.azure-pipelines/mac_build_java.yml @@ -23,7 +23,7 @@ steps: libcxx=$(compiler_version) cmake=3.26 \ libboost=$(boost_version) \ libboost-devel=$(boost_version) \ - cairo eigen swig=4.2 + cairo eigen swig=4.2 make conda activate rdkit_build displayName: Setup build environment - bash: | diff --git a/External/pubchem_shape/PubChemShape.hpp b/External/pubchem_shape/PubChemShape.hpp index a55064f9d..19090167b 100644 --- a/External/pubchem_shape/PubChemShape.hpp +++ b/External/pubchem_shape/PubChemShape.hpp @@ -1,12 +1,62 @@ +#ifndef RDKIT_PUBCHEMSHAPE_GUARD +#define RDKIT_PUBCHEMSHAPE_GUARD + #include #include #include -#ifndef RDKIT_PUBCHEMSHAPE_GUARD -#define RDKIT_PUBCHEMSHAPE_GUARD +#ifdef RDK_USE_BOOST_SERIALIZATION +#include +#include +#include +#include +#include +#include +#endif //! The input for the pubchem shape alignment code struct RDKIT_PUBCHEMSHAPE_EXPORT ShapeInput { + ShapeInput() = default; + ShapeInput(const std::string &str) { +#ifndef RDK_USE_BOOST_SERIALIZATION + PRECONDITION(0, "Boost SERIALIZATION is not enabled") +#else + std::stringstream ss(str); + boost::archive::text_iarchive ia(ss); + ia &*this; +#endif + } + ShapeInput(const ShapeInput &other) = default; + ShapeInput(ShapeInput &&other) = default; + ShapeInput &operator=(const ShapeInput &other) = default; + ShapeInput &operator=(ShapeInput &&other) = default; + ~ShapeInput() = default; + + std::string toString() const { +#ifndef RDK_USE_BOOST_SERIALIZATION + PRECONDITION(0, "Boost SERIALIZATION is not enabled") +#else + std::stringstream ss; + boost::archive::text_oarchive oa(ss); + oa &*this; + return ss.str(); +#endif + } + +#ifdef RDK_USE_BOOST_SERIALIZATION + template + void serialize(Archive &ar, const unsigned int) { + ar & coord; + ar & alpha_vector; + ar & atom_type_vector; + ar & volumeAtomIndexVector; + ar & colorAtomType2IndexVectorMap; + ar & shift; + ar & sov; + ar & sof; + } +#endif + std::vector coord; std::vector alpha_vector; std::vector atom_type_vector; @@ -70,4 +120,4 @@ RDKIT_PUBCHEMSHAPE_EXPORT std::pair AlignMolecule( double opt_param = 1.0, unsigned int max_preiters = 10u, unsigned int max_postiters = 30u); -#endif \ No newline at end of file +#endif diff --git a/External/pubchem_shape/test.cpp b/External/pubchem_shape/test.cpp index 737b09415..3d3193082 100644 --- a/External/pubchem_shape/test.cpp +++ b/External/pubchem_shape/test.cpp @@ -282,3 +282,24 @@ TEST_CASE("Github #8096") { CHECK_THAT(nbr_ct, Catch::Matchers::WithinAbs(1.0, 0.005)); } } + +#ifdef RDK_USE_BOOST_SERIALIZATION +TEST_CASE("Serialization") { + auto m1 = + "[H]c1c([H])c([H])c([H])c([H])c1[H] |(-2.06264,-0.844763,-0.0261403;-1.04035,-0.481453,-0.0114878;-0.00743655,-1.41861,-0.0137121;-0.215455,-2.47997,-0.0295909;1.29853,-0.949412,0.00507497;2.12524,-1.65277,0.00390664;1.58501,0.395878,0.0254188;2.61997,0.704365,0.0394811;0.550242,1.31385,0.0273741;0.783172,2.37039,0.0434262;-0.763786,0.88847,0.00908113;-1.60557,1.58532,0.0100194)|"_smiles; + REQUIRE(m1); + auto shape = PrepareConformer(*m1); + auto istr = shape.toString(); + + ShapeInput shape2(istr); + CHECK(shape2.coord == shape.coord); + CHECK(shape2.alpha_vector == shape.alpha_vector); + CHECK(shape2.atom_type_vector == shape.atom_type_vector); + CHECK(shape2.volumeAtomIndexVector == shape.volumeAtomIndexVector); + CHECK(shape2.colorAtomType2IndexVectorMap == + shape.colorAtomType2IndexVectorMap); + CHECK(shape2.shift == shape.shift); + CHECK_THAT(shape2.sov, Catch::Matchers::WithinAbs(253.764, 0.005)); + CHECK_THAT(shape2.sof, Catch::Matchers::WithinAbs(5.074, 0.005)); +} +#endif \ No newline at end of file