/// // Copyright (C) 2001-2021 Greg Landrum and Rational Discovery LLC // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include #ifndef RD_MOLPICKLE_H #define RD_MOLPICKLE_H #include #include #include #include #include #include #include #include #include // Std stuff #include #include #include #ifdef WIN32 #include #endif #include #include namespace RDKit { class ROMol; class RingInfo; //! used to indicate exceptions whilst pickling (serializing) molecules class RDKIT_GRAPHMOL_EXPORT MolPicklerException : public std::exception { public: MolPicklerException(const char *msg) : _msg(msg) {} MolPicklerException(const std::string msg) : _msg(msg) {} const char *what() const noexcept override { return _msg.c_str(); } ~MolPicklerException() noexcept override = default; private: std::string _msg; }; namespace PicklerOps { BETTER_ENUM( PropertyPickleOptions, unsigned int, NoProps = 0, // no data pickled (default pickling, single-precision coords) MolProps = 0x1, // only public non computed properties AtomProps = 0x2, BondProps = 0x4, QueryAtomData = 0x2, // n.b. DEPRECATED and set to AtomProps (does the same work) PrivateProps = 0x10, ComputedProps = 0x20, AllProps = 0x0000FFFF, // all data pickled CoordsAsDouble = 0x00010000, // save coordinates in double precision NoConformers = 0x00020000 // do not include conformers or associated properties ); } // namespace PicklerOps //! handles pickling (serializing) molecules class RDKIT_GRAPHMOL_EXPORT MolPickler { public: static const std::int32_t versionMajor; //!< mark the pickle major version static const std::int32_t versionMinor; //!< mark the pickle minor version static const std::int32_t versionPatch; //!< mark the pickle patch version static const std::int32_t endianId; //!< mark the endian-ness of the pickle //! the pickle format is tagged using these tags: //! NOTE: if you add to this list, be sure to put new entries AT THE BOTTOM, /// otherwise //! you will break old pickles. typedef enum { VERSION = 0, BEGINATOM, ATOM_INDEX, ATOM_NUMBER, ATOM_POS, ATOM_CHARGE, ATOM_NEXPLICIT, ATOM_CHIRALTAG, ATOM_MASS, ATOM_ISAROMATIC, ENDATOM, BEGINBOND, BOND_INDEX, BOND_BEGATOMIDX, BOND_ENDATOMIDX, BOND_TYPE, BOND_DIR, ENDBOND, BEGINPROPS, ENDPROPS, BEGINSSSR, ENDSSSR, ENDMOL, BEGINCONFS, ATOM_MAPNUMBER, BEGINQUERY, QUERY_VALUE, QUERY_ISNEGATED, QUERY_NUMCHILDREN, QUERY_BOOL, QUERY_AND, QUERY_OR, QUERY_XOR, QUERY_EQUALS, QUERY_GREATER, QUERY_GREATEREQUAL, QUERY_LESS, QUERY_LESSEQUAL, QUERY_RANGE, QUERY_SET, QUERY_NULL, QUERY_ATOMRING, QUERY_RECURSIVE, ENDQUERY, ATOM_DUMMYLABEL, BEGIN_ATOM_MONOMER, ATOM_PDB_RESIDUE_SERIALNUMBER, ATOM_PDB_RESIDUE_ALTLOC, ATOM_PDB_RESIDUE_RESIDUENAME, ATOM_PDB_RESIDUE_CHAINID, ATOM_PDB_RESIDUE_INSERTIONCODE, ATOM_PDB_RESIDUE_OCCUPANCY, ATOM_PDB_RESIDUE_TEMPFACTOR, ATOM_PDB_RESIDUE_ISHETEROATOM, ATOM_PDB_RESIDUE_SECONDARYSTRUCTURE, ATOM_PDB_RESIDUE_RESIDUENUMBER, ATOM_PDB_RESIDUE_SEGMENTNUMBER, END_ATOM_MONOMER, BEGINATOMPROPS, BEGINBONDPROPS, BEGINQUERYATOMDATA, BEGINSGROUP, BEGINSTEREOGROUP, BEGINCONFPROPS, BEGINCONFS_DOUBLE, QUERY_TYPELABEL, BEGINSYMMSSSR, BEGINFASTFIND, BEGINFINDOTHERORUNKNOWN, QUERY_PROPERTY, QUERY_PROPERTY_WITH_VALUE, // add new entries above here INVALID_TAG = 255 } Tags; static unsigned int getDefaultPickleProperties(); static void setDefaultPickleProperties(unsigned int); static const CustomPropHandlerVec &getCustomPropHandlers(); static void addCustomPropHandler(const CustomPropHandler &handler); //! pickles a molecule and sends the results to stream \c ss static void pickleMol(const ROMol *mol, std::ostream &ss); static void pickleMol(const ROMol *mol, std::ostream &ss, unsigned int propertyFlags); static void pickleMol(const ROMol &mol, std::ostream &ss); static void pickleMol(const ROMol &mol, std::ostream &ss, unsigned int propertyFlags) { MolPickler::pickleMol(&mol, ss, propertyFlags); } //! pickles a molecule and adds the results to string \c res static void pickleMol(const ROMol *mol, std::string &res); static void pickleMol(const ROMol *mol, std::string &res, unsigned int propertyFlags); static void pickleMol(const ROMol &mol, std::string &res); static void pickleMol(const ROMol &mol, std::string &res, unsigned int propertyFlags) { MolPickler::pickleMol(&mol, res, propertyFlags); } //! constructs a molecule from a pickle stored in a string static void molFromPickle(const std::string &pickle, ROMol *mol, unsigned int propertyFlags); static void molFromPickle(const std::string &pickle, ROMol &mol, unsigned int propertyFlags) { MolPickler::molFromPickle(pickle, &mol, propertyFlags); } static void molFromPickle(const std::string &pickle, ROMol *mol) { MolPickler::molFromPickle(pickle, mol, PicklerOps::PropertyPickleOptions::AllProps); } static void molFromPickle(const std::string &pickle, ROMol &mol) { MolPickler::molFromPickle(pickle, &mol, PicklerOps::PropertyPickleOptions::AllProps); } //! constructs a molecule from a pickle stored in a stream static void molFromPickle(std::istream &ss, ROMol *mol, unsigned int propertyFlags); static void molFromPickle(std::istream &ss, ROMol &mol, unsigned int propertyFlags) { MolPickler::molFromPickle(ss, &mol, propertyFlags); } static void molFromPickle(std::istream &ss, ROMol *mol) { MolPickler::molFromPickle(ss, mol, PicklerOps::PropertyPickleOptions::AllProps); } static void molFromPickle(std::istream &ss, ROMol &mol) { MolPickler::molFromPickle(ss, &mol, PicklerOps::PropertyPickleOptions::AllProps); } private: //! Pickle nonquery atom data static std::int32_t _pickleAtomData(std::ostream &tss, const Atom *atom); //! depickle nonquery atom data static void _unpickleAtomData(std::istream &tss, Atom *atom, int version); static void _pickleQueryAtomData(std::ostream &tss, const Atom *atom); //! do the actual work of pickling a molecule template static void _pickle(const ROMol *mol, std::ostream &ss, unsigned int propertyFlags); //! do the actual work of pickling an Atom template static void _pickleAtom(std::ostream &ss, const Atom *atom); //! do the actual work of pickling a Bond template static void _pickleBond(std::ostream &ss, const Bond *bond, std::map &atomIdxMap); //! do the actual work of pickling an SSSR structure template static void _pickleSSSR(std::ostream &ss, const RingInfo *ringInfo, std::map &atomIdxMap); //! do the actual work of pickling a SubstanceGroup template static void _pickleSubstanceGroup(std::ostream &ss, const SubstanceGroup &sgroup, std::map &atomIdxMap, std::map &bondIdxMap); //! do the actual work of pickling Stereo Group data template static void _pickleStereo(std::ostream &ss, std::vector groups, std::map &atomIdxMap, std::map &bondIdxMap); //! do the actual work of pickling a Conformer template static void _pickleConformer(std::ostream &ss, const Conformer *conf); //! do the actual work of de-pickling a molecule template static void _depickle(std::istream &ss, ROMol *mol, int version, int numAtoms, unsigned int propertyFlags); //! extract atomic data from a pickle and add the resulting Atom to the /// molecule template static Atom *_addAtomFromPickle(std::istream &ss, ROMol *mol, RDGeom::Point3D &pos, int version, bool directMap = false); //! extract bond data from a pickle and add the resulting Bond to the molecule template static Bond *_addBondFromPickle(std::istream &ss, ROMol *mol, int version, bool directMap = false); //! extract ring info from a pickle and add the resulting RingInfo to the /// molecule template static void _addRingInfoFromPickle( std::istream &ss, ROMol *mol, int version, bool directMap = false, FIND_RING_TYPE ringType = FIND_RING_TYPE::FIND_RING_TYPE_OTHER_OR_UNKNOWN); //! extract a SubstanceGroup from a pickle template static SubstanceGroup _getSubstanceGroupFromPickle(std::istream &ss, ROMol *mol, int version); template static void _depickleStereo(std::istream &ss, ROMol *mol, int version); //! extract a conformation from a pickle template static Conformer *_conformerFromPickle(std::istream &ss, int version); //! pickle standard properties static void _pickleProperties(std::ostream &ss, const RDProps &props, unsigned int pickleFlags); //! unpickle standard properties static void _unpickleProperties(std::istream &ss, RDProps &props, int version); //! backwards compatibility static void _pickleV1(const ROMol *mol, std::ostream &ss); //! backwards compatibility static void _depickleV1(std::istream &ss, ROMol *mol); //! backwards compatibility static void _addAtomFromPickleV1(std::istream &ss, ROMol *mol); //! backwards compatibility static void _addBondFromPickleV1(std::istream &ss, ROMol *mol); }; namespace PicklerOps { // clang-format off using QueryDetails = boost::variant< MolPickler::Tags, std::tuple, std::tuple, std::tuple, std::tuple>, std::tuple, std::tuple>; // clang-format on template QueryDetails getQueryDetails(const Queries::Query *query); } // namespace PicklerOps }; // namespace RDKit #endif