File: MolBundle.h

package info (click to toggle)
rdkit 202503.1-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 220,160 kB
  • sloc: cpp: 399,240; python: 77,453; ansic: 25,517; java: 8,173; javascript: 4,005; sql: 2,389; yacc: 1,565; lex: 1,263; cs: 1,081; makefile: 580; xml: 229; fortran: 183; sh: 105
file content (205 lines) | stat: -rw-r--r-- 5,903 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
//
//  Copyright (C) 2017-2023 Greg Landrum and other RDKit contributors
//
//   @@ 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.
//
/*! \file MolBundle.h

  \brief Defines a class for managing bundles of molecules

*/

#include <RDGeneral/export.h>
#ifndef RD_MOLBUNDLE_AUG2017
#define RD_MOLBUNDLE_AUG2017

/// Std stuff
#include <vector>

// boost stuff
#include <RDGeneral/BoostStartInclude.h>
#include <boost/smart_ptr.hpp>
#include <RDGeneral/BoostEndInclude.h>

#ifdef RDK_USE_BOOST_SERIALIZATION
#include <RDGeneral/BoostStartInclude.h>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/split_member.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/archive_exception.hpp>
#include <RDGeneral/BoostEndInclude.h>
#endif

// our stuff
#include <RDGeneral/Exceptions.h>
#include <GraphMol/MolPickler.h>

namespace RDKit {
class ROMol;

inline bool MolBundleCanSerialize() {
#ifdef RDK_USE_BOOST_SERIALIZATION
  return true;
#else
  return false;
#endif
};

//! MolBundle contains a collection of related ROMols
/*!
  This is designed to allow handling things like enumerating link nodes,
  polymers, etc.
*/
class MolBundle : public RDProps {
 public:
  MolBundle() : RDProps() {}

  //! copy constructor
  MolBundle(const MolBundle &other) : RDProps(other) { d_mols = other.d_mols; }
  MolBundle(const std::string &pkl) { initFromString(pkl); }
  virtual ~MolBundle() {}

  MolBundle &operator=(const MolBundle &other) = default;

  //! returns our molecules
  virtual const std::vector<boost::shared_ptr<ROMol>> &getMols() const {
    return d_mols;
  }

  //! adds a new molecule and returns the total number of molecules
  virtual size_t addMol(boost::shared_ptr<ROMol> nmol) {
    PRECONDITION(nmol.get(), "bad mol pointer");
    d_mols.push_back(nmol);
    return (d_mols.size());
  }
  //! returns the number of molecules from the bundle
  virtual size_t size() const { return d_mols.size(); }
  //! returns whether or not the bundle is empty
  virtual bool empty() const { return d_mols.empty(); }

  //! returns a particular molecule in the bundle
  virtual const boost::shared_ptr<ROMol> getMol(size_t idx) const {
    if (idx >= d_mols.size()) {
      throw IndexErrorException(static_cast<int>(idx));
    }
    return d_mols[idx];
  }
  //! returns a particular molecule from the bundle
  virtual const boost::shared_ptr<ROMol> operator[](size_t idx) const {
    return getMol(idx);
  }

  //! serializes (pickles) to a stream
  void toStream(std::ostream &ss) const {
#ifndef RDK_USE_BOOST_SERIALIZATION
    RDUNUSED_PARAM(ss);
    PRECONDITION(0, "Boost SERIALIZATION is not enabled")
#else
    boost::archive::text_oarchive ar(ss);
    ar << *this;
#endif
  };
  //! returns a string with a serialized (pickled) representation
  std::string serialize() const {
    std::stringstream ss;
    toStream(ss);
    return ss.str();
  };
  //! initializes from a stream pickle
  void initFromStream(std::istream &ss) {
#ifndef RDK_USE_BOOST_SERIALIZATION
    RDUNUSED_PARAM(ss);
    PRECONDITION(0, "Boost SERIALIZATION is not enabled")
#else
    boost::archive::text_iarchive ar(ss);
    ar >> *this;
#endif
  };
  //! initializes from a string pickle
  void initFromString(const std::string &text) {
    std::stringstream ss(text);
    initFromStream(ss);
  };

#ifdef RDK_USE_BOOST_SERIALIZATION
  // FIX: we don't currently serialize properties
  template <class Archive>
  void save(Archive &ar, const unsigned int version) const {
    RDUNUSED_PARAM(version);
    std::vector<std::string> pkls;
    for (const auto &mol : d_mols) {
      std::string pkl;
      MolPickler::pickleMol(*mol, pkl);
      pkls.push_back(pkl);
    }
    ar << pkls;
  }

  template <class Archive>
  void load(Archive &ar, const unsigned int version) {
    RDUNUSED_PARAM(version);

    std::vector<std::string> pkls;
    ar >> pkls;
    d_mols.clear();
    for (const auto &pkl : pkls) {
      d_mols.push_back(ROMOL_SPTR(new ROMol(pkl)));
    }
  }
  BOOST_SERIALIZATION_SPLIT_MEMBER()
#endif

 protected:
  std::vector<boost::shared_ptr<ROMol>> d_mols;
};

//! FixedMolSizeMolBundle contains a collection of ROMols with the same
//! number of atoms and bonds.
/*!
  This is designed to allow handling things like enhanced stereochemistry,
  but can no doubt be (ab)used in other ways.

  Implementation note: at the moment this isn't taking advantage of the fact
  that the number of atoms and bonds remains constant. This may be used in the
  future to allow this to be more efficient.

*/
class FixedMolSizeMolBundle : public MolBundle {
 public:
  FixedMolSizeMolBundle() : MolBundle() {}

  //! copy constructor
  FixedMolSizeMolBundle(const FixedMolSizeMolBundle &other)
      : MolBundle(other) {}

  ~FixedMolSizeMolBundle() override = default;

  //! adds a new molecule and returns the total number of molecules
  //!  enforces that the new molecule has the same number of atoms and bonds
  //!  as the molecules that are already there.
  size_t addMol(boost::shared_ptr<ROMol> nmol) override {
    PRECONDITION(nmol.get(), "bad mol pointer");
    if (d_mols.size()) {
      if (nmol->getNumAtoms() != d_mols[0]->getNumAtoms()) {
        throw ValueErrorException(
            "all molecules in a bundle must have the same number of atoms");
      }
      // REVIEW: should we allow different numbers of bonds?
      if (nmol->getNumBonds() != d_mols[0]->getNumBonds()) {
        throw ValueErrorException(
            "all molecules in a bundle must have the same number of bonds");
      }
    }
    d_mols.push_back(nmol);
    return (d_mols.size());
  }
};

};  // namespace RDKit
#endif