34 #ifndef __RD_SLNPARSEOPS_H__ 35 #define __RD_SLNPARSEOPS_H__ 42 #include <boost/lexical_cast.hpp> 48 void bookmarkAtomID(RWMol *mp, Atom *atom) {
53 if (mp->hasAtomBookmark(label)) {
54 std::stringstream err;
55 err <<
"SLN Parser error: Atom ID " << label <<
" used a second time.";
56 throw SLNParseException(err.str());
58 if (mp->hasBondBookmark(label)) {
59 std::stringstream err;
60 err <<
"SLN Parser error: Atom ID " << label
61 <<
" appears *after* its ring closure.";
62 throw SLNParseException(err.str());
64 mp->setAtomBookmark(atom, label);
69 template <
typename BondType>
70 void addBondToMol(RWMol *mp, BondType *bond) {
73 mp->addBond(bond,
true);
77 bond->setIsAromatic(
true);
78 bond->getBeginAtom()->setIsAromatic(
true);
79 bond->getEndAtom()->setIsAromatic(
true);
86 template <
typename AtomType>
87 int startMol(std::vector<RWMol *> &molList, AtomType *firstAtom,
91 mp->
addAtom(firstAtom,
true,
true);
92 bookmarkAtomID(mp, firstAtom);
98 for (
unsigned int i = 0; i < firstAtom->getNumExplicitHs(); ++i) {
102 firstAtom->setNumExplicitHs(0);
105 int sz = molList.size();
106 molList.push_back(mp);
112 template <
typename AtomType,
typename BondType>
114 AtomType *atom, BondType *bond,
bool doingQuery) {
116 RWMol *mp = molList[idx];
121 Atom *a1 = mp->getActiveAtom();
122 int atomIdx1 = a1->
getIdx();
123 int atomIdx2 = mp->addAtom(atom,
true,
true);
124 bookmarkAtomID(mp, atom);
125 bond->setOwningMol(mp);
126 bond->setBeginAtomIdx(atomIdx1);
127 bond->setEndAtomIdx(atomIdx2);
128 addBondToMol(mp, bond);
134 for (
unsigned int i = 0; i < atom->getNumExplicitHs(); ++i) {
135 int hIdx = mp->addAtom(
new Atom(1),
false,
true);
138 atom->setNumExplicitHs(0);
142 template <
typename AtomType>
144 AtomType *atom,
bool doingQuery) {
153 template <
typename BondType>
155 unsigned int ringIdx, BondType *bond,
156 bool postponeAllowed =
true) {
158 RWMol *mp = molList[molIdx];
162 if (!mp->hasAtomBookmark(ringIdx)) {
163 if (postponeAllowed) {
165 bond->setOwningMol(mp);
166 bond->setEndAtomIdx(mp->getActiveAtom()->getIdx());
167 mp->setBondBookmark(bond, ringIdx);
170 std::stringstream err;
171 err <<
"SLN Parser error: Ring closure " << ringIdx
172 <<
" does not have a corresponding opener.";
176 Atom *opener = mp->getAtomWithBookmark(ringIdx);
179 Atom *closer = mp->getActiveAtom();
181 bond->setBeginAtom(opener);
182 bond->setEndAtom(closer);
183 addBondToMol(mp, bond);
187 unsigned int ringIdx) {
193 template <
typename BondType>
195 unsigned int branchIdx, BondType *&bond) {
197 RWMol *mp = molList[molIdx];
200 RWMol *branch = molList[branchIdx];
204 unsigned int activeAtomIdx = mp->getActiveAtom()->getIdx();
205 unsigned int nOrigAtoms = mp->getNumAtoms();
210 mp->insertMol(*branch);
213 for (ROMol::ATOM_BOOKMARK_MAP::const_iterator bmIt =
214 branch->getAtomBookmarks()->begin();
215 bmIt != branch->getAtomBookmarks()->end(); ++bmIt) {
216 if (bmIt->first < 0)
continue;
217 if (mp->hasAtomBookmark(bmIt->first)) {
218 std::stringstream err;
219 err <<
"SLN Parser error: Atom ID " << bmIt->first
220 <<
" used a second time.";
222 }
else if (mp->hasBondBookmark(bmIt->first)) {
223 std::stringstream err;
224 err <<
"SLN Parser error: Atom ID " << bmIt->first
225 <<
" appears *after* its ring closure.";
229 "bad atom bookmark list on branch");
231 mp->getAtomWithIdx((*bmIt->second.begin())->getIdx() + nOrigAtoms);
232 mp->setAtomBookmark(tgtAtom, bmIt->first);
237 for (ROMol::BOND_BOOKMARK_MAP::const_iterator bmIt =
238 branch->getBondBookmarks()->begin();
239 bmIt != branch->getBondBookmarks()->end(); ++bmIt) {
241 "bad bond bookmark list on branch");
242 for (ROMol::BOND_PTR_LIST::const_iterator bondIt = bmIt->second.begin();
243 bondIt != bmIt->second.end(); ++bondIt) {
244 Bond *tgtBond = *bondIt;
245 if (bmIt->first > 0 && mp->hasAtomBookmark(bmIt->first)) {
246 Atom *tmpAtom = mp->getActiveAtom();
250 mp->setActiveAtom(tmpAtom);
255 mp->setBondBookmark(tgtBond, bmIt->first);
262 bond->setOwningMol(mp);
263 bond->setBeginAtomIdx(activeAtomIdx);
264 bond->setEndAtomIdx(nOrigAtoms);
265 addBondToMol(mp, bond);
272 unsigned int sz = molList.size();
273 if (sz == branchIdx + 1) {
274 molList.resize(sz - 1);
280 unsigned int branchIdx) {
289 unsigned int fragIdx) {
295 template <
typename T>
297 std::string res = boost::lexical_cast<std::string>(val);
304 RWMol::BOND_BOOKMARK_MAP *marks = mol->getBondBookmarks();
305 RWMol::BOND_BOOKMARK_MAP::iterator markI = marks->begin();
306 while (markI != marks->end()) {
307 RWMol::BOND_PTR_LIST &bonds = markI->second;
308 for (RWMol::BOND_PTR_LIST::iterator bondIt = bonds.begin();
309 bondIt != bonds.end(); ++bondIt) {
std::string convertToString(T val)
convenience function to convert the argument to a string
void addAtomToMol(std::vector< RWMol *> &molList, unsigned int idx, AtomType *atom, BondType *bond, bool doingQuery)
adds an atom to a molecule
RWMol is a molecule class that is intended to be edited.
unsigned int addAtom(bool updateLabel=true)
adds an empty Atom to our collection
#define CHECK_INVARIANT(expr, mess)
pulls in the RDKit Query functionality
pulls in the core RDKit functionality
int addBranchToMol(std::vector< RWMol *> &molList, unsigned int molIdx, unsigned int branchIdx, BondType *&bond)
int startMol(std::vector< RWMol *> &molList, AtomType *firstAtom, bool doingQuery)
initialize a molecule
unsigned int getIdx() const
returns our index within the ROMol
unsigned int getEndAtomIdx() const
returns the index of our end Atom
Includes a bunch of functionality for handling Atom and Bond queries.
class for representing a bond
void setOwningMol(ROMol *other)
sets our owning molecule
void setOwningMol(ROMol *other)
sets our owning molecule
void CleanupAfterParseError(RWMol *mol)
void setEndAtomIdx(unsigned int what)
sets the index of our end Atom
const std::string _AtomID
#define PRECONDITION(expr, mess)
int addFragToMol(std::vector< RWMol *> &molList, unsigned int molIdx, unsigned int fragIdx)
adds the atoms and bonds from a fragment to the molecule, sets no bond
The class for representing atoms.
void closeRingBond(std::vector< RWMol *> &molList, unsigned int molIdx, unsigned int ringIdx, BondType *bond, bool postponeAllowed=true)
closes an indexed ring in a molecule using the bond provided
unsigned int addBond(unsigned int beginAtomIdx, unsigned int endAtomIdx, Bond::BondType order=Bond::UNSPECIFIED)
adds a Bond between the indicated Atoms