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 <david@cozchemix.co.uk>
This commit is contained in:
David Cosgrove
2025-04-14 17:03:50 +01:00
committed by GitHub
parent 37edf5b823
commit 4ea67c70a5
4 changed files with 76 additions and 5 deletions

View File

@@ -1,12 +1,62 @@
#ifndef RDKIT_PUBCHEMSHAPE_GUARD
#define RDKIT_PUBCHEMSHAPE_GUARD
#include <GraphMol/ROMol.h>
#include <map>
#include <vector>
#ifndef RDKIT_PUBCHEMSHAPE_GUARD
#define RDKIT_PUBCHEMSHAPE_GUARD
#ifdef RDK_USE_BOOST_SERIALIZATION
#include <RDGeneral/BoostStartInclude.h>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/vector.hpp>
#include <RDGeneral/BoostEndInclude.h>
#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 <class Archive>
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<float> coord;
std::vector<double> alpha_vector;
std::vector<unsigned int> atom_type_vector;
@@ -70,4 +120,4 @@ RDKIT_PUBCHEMSHAPE_EXPORT std::pair<double, double> AlignMolecule(
double opt_param = 1.0, unsigned int max_preiters = 10u,
unsigned int max_postiters = 30u);
#endif
#endif

View File

@@ -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