13 #ifndef _RD_MOLDRAWING_H_ 14 #define _RD_MOLDRAWING_H_ 18 #include <boost/foreach.hpp> 19 #include <boost/lexical_cast.hpp> 48 void drawLine(std::vector<ElementType> &res,
int atnum1,
int atnum2,
49 int lineWidth,
int dashed,
double x1,
double y1,
double x2,
52 res.push_back(static_cast<ElementType>(lineWidth));
53 res.push_back(dashed);
54 res.push_back(static_cast<ElementType>(atnum1));
55 res.push_back(static_cast<ElementType>(atnum2));
56 res.push_back(static_cast<ElementType>(x1));
57 res.push_back(static_cast<ElementType>(y1));
58 res.push_back(static_cast<ElementType>(x2));
59 res.push_back(static_cast<ElementType>(y2));
63 std::string symbol =
"";
64 OrientType orient =
C;
71 bool leftToRight =
true;
76 symbol = boost::lexical_cast<std::string>(isotope) + symbol;
81 symbol +=
":" + mapNum;
87 h += boost::lexical_cast<std::string>(nHs);
96 std::string sgn =
"+";
102 sgn += boost::lexical_cast<std::string>(chg);
107 symbol = sgn + symbol;
112 if (fabs(nbrSum.
y) > 1) {
113 islope = nbrSum.
x / fabs(nbrSum.
y);
117 if (fabs(islope) > .85) {
132 return std::make_pair(symbol, orient);
137 const std::vector<int> *highlightAtoms = 0,
138 bool includeAtomCircles =
false,
139 unsigned int dotsPerAngstrom = 100,
140 double dblBondOffset = 0.3,
141 double dblBondLengthFrac = 0.8,
142 double angstromsPerChar = 0.20) {
146 std::vector<ElementType> res;
148 res.push_back(static_cast<ElementType>(dotsPerAngstrom));
155 std::vector<std::pair<std::string, OrientType> > atomSymbols;
156 ROMol::VERTEX_ITER bAts, eAts;
158 while (bAts != eAts) {
159 ROMol::OEDGE_ITER nbr, endNbrs;
161 boost::tie(nbr, endNbrs) = mol.
getAtomBonds(mol[*bAts].
get());
163 locs[mol[*bAts]->getIdx()].y);
164 while (nbr != endNbrs) {
167 int a2Idx = bond->getOtherAtomIdx(mol[*bAts]->getIdx());
171 atomSymbols.push_back(
179 double minx = 1e6, miny = 1e6, maxx = -1e6, maxy = -1e6;
180 for (
unsigned int i = 0; i < mol.
getNumAtoms(); ++i) {
184 boost::tie(symbol, orient) = atomSymbols[i];
193 minx = pt.
x - symbol.size() / 2 * angstromsPerChar;
196 minx = pt.
x - symbol.size() * angstromsPerChar;
206 maxx = pt.
x + symbol.size() / 2 * angstromsPerChar;
209 maxx = pt.
x + symbol.size() * angstromsPerChar;
215 miny = pt.
y - 1.5 * angstromsPerChar;
218 maxy = pt.
y + angstromsPerChar;
221 minx = std::min(pt.
x, minx);
222 miny = std::min(pt.
y, miny);
223 maxx = std::max(pt.
x, maxx);
224 maxy = std::max(pt.
y, maxy);
227 double dimx = (maxx - minx), dimy = (maxy - miny);
229 res.push_back(static_cast<ElementType>(dotsPerAngstrom * 0));
230 res.push_back(static_cast<ElementType>(dotsPerAngstrom * 0));
231 res.push_back(static_cast<ElementType>(dotsPerAngstrom * dimx));
232 res.push_back(static_cast<ElementType>(dotsPerAngstrom * dimy));
236 while (bAts != eAts) {
237 int a1Idx = mol[*bAts]->getIdx();
239 ROMol::OEDGE_ITER nbr, endNbrs;
241 boost::tie(nbr, endNbrs) = mol.
getAtomBonds(mol[*bAts].
get());
242 while (nbr != endNbrs) {
245 int a2Idx = bond->getOtherAtomIdx(a1Idx);
247 if (highlightAtoms &&
248 std::find(highlightAtoms->begin(), highlightAtoms->end(), a1Idx) !=
249 highlightAtoms->end() &&
250 std::find(highlightAtoms->begin(), highlightAtoms->end(), a2Idx) !=
251 highlightAtoms->end()) {
256 if (a2Idx < a1Idx)
continue;
259 int atnum1 = mol[*bAts]->getAtomicNum();
274 perp *= dblBondOffset;
275 startP += (obv * (1. - dblBondLengthFrac) / 2);
276 endP -= (obv * (1. - dblBondLengthFrac) / 2);
278 perp *= 0.5 * dblBondOffset;
281 dotsPerAngstrom * (startP.
x + perp.
x),
282 dotsPerAngstrom * (startP.
y + perp.
y),
283 dotsPerAngstrom * (endP.x + perp.
x),
284 dotsPerAngstrom * (endP.y + perp.
y));
287 dotsPerAngstrom * (startP.
x - perp.
x),
288 dotsPerAngstrom * (startP.
y - perp.
y),
289 dotsPerAngstrom * (endP.x - perp.
x),
290 dotsPerAngstrom * (endP.y - perp.
y));
293 dotsPerAngstrom * (startP.
x - perp.
x),
294 dotsPerAngstrom * (startP.
y - perp.
y),
295 dotsPerAngstrom * (endP.x - perp.
x),
296 dotsPerAngstrom * (endP.y - perp.
y));
302 dotsPerAngstrom * (a1.x), dotsPerAngstrom * (a1.y),
303 dotsPerAngstrom * (a2.
x), dotsPerAngstrom * (a2.
y));
306 dotsPerAngstrom * (a1.x), dotsPerAngstrom * (a1.y),
307 dotsPerAngstrom * (a2.
x), dotsPerAngstrom * (a2.
y));
312 dotsPerAngstrom * a1.x, dotsPerAngstrom * a1.y,
313 dotsPerAngstrom * a2.
x, dotsPerAngstrom * a2.
y);
327 ROMol::OEDGE_ITER nbr2, endNbrs2;
328 boost::tie(nbr2, endNbrs2) = mol.
getAtomBonds(mol[*bAts].
get());
329 while (nbr2 != endNbrs2) {
332 if (bond2->getIdx() == bond->getIdx() ||
335 bool sharedRing =
false;
336 BOOST_FOREACH (
const INT_VECT &ring,
338 if (std::find(ring.begin(), ring.end(), bond->getIdx()) !=
340 std::find(ring.begin(), ring.end(), bond2->getIdx()) !=
348 int a3Idx = bond2->getOtherAtomIdx(a1Idx);
349 if (a3Idx != a2Idx) {
351 locs[a3Idx].y - miny);
360 perp *= dblBondOffset;
363 a1 + obv * (.5 * (1. - dblBondLengthFrac));
365 obv *= dblBondLengthFrac;
369 dotsPerAngstrom * (offsetStart.
x + perp.
x),
370 dotsPerAngstrom * (offsetStart.
y + perp.
y),
371 dotsPerAngstrom * (offsetStart.
x + obv.x + perp.
x),
372 dotsPerAngstrom * (offsetStart.
y + obv.y + perp.
y));
378 boost::tie(symbol, orient) = atomSymbols[a1Idx];
379 if (symbol !=
"" || includeAtomCircles) {
381 res.push_back(mol[*bAts]->getAtomicNum());
382 res.push_back(static_cast<ElementType>(dotsPerAngstrom * a1.
x));
383 res.push_back(static_cast<ElementType>(dotsPerAngstrom * a1.
y));
384 res.push_back(static_cast<ElementType>(symbol.length()));
385 if (symbol.length()) {
386 BOOST_FOREACH (
char c, symbol) {
387 res.push_back(static_cast<ElementType>(c));
390 res.push_back(static_cast<ElementType>(orient));
400 const std::vector<int> *highlightAtoms = 0,
401 bool kekulize =
true,
402 bool includeAtomCircles =
false) {
415 std::vector<int> drawing =
416 DrawMol(*cp, -1, highlightAtoms, includeAtomCircles);
boost::shared_ptr< Bond > BOND_SPTR
const Conformer & getConformer(int id=-1) const
std::pair< std::string, OrientType > getAtomSymbolAndOrientation(const Atom &atom, RDGeom::Point2D nbrSum)
void Kekulize(RWMol &mol, bool markAtomsBonds=true, unsigned int maxBackTracks=100)
Kekulizes the molecule.
std::vector< int > MolToDrawing(const RDKit::ROMol &mol, const std::vector< int > *highlightAtoms=0, bool kekulize=true, bool includeAtomCircles=false)
ATOM_ITER_PAIR getVertices()
returns an iterator pair for looping over all Atoms
unsigned int numBondRings(unsigned int idx) const
returns the number of rings bond idx is involved in
int findSSSR(const ROMol &mol, std::vector< std::vector< int > > &res)
finds a molecule's Smallest Set of Smallest Rings
RWMol is a molecule class that is intended to be edited.
unsigned int getNumAtoms(bool onlyExplicit=1) const
returns our number of atoms
const VECT_INT_VECT & bondRings() const
returns our bond-rings vectors
const std::string molAtomMapNumber
unsigned int getTotalNumHs(bool includeNeighbors=false) const
returns the total number of Hs (implicit and explicit) that this Atom is bound to ...
unsigned int getNumConformers() const
unsigned int getNumRadicalElectrons() const
returns the number of radical electrons for this Atom
std::vector< Point3D > POINT3D_VECT
pulls in the core RDKit functionality
ROMol is a molecule class that is intended to have a fixed topology.
RingInfo * getRingInfo() const
unsigned int getIsotope() const
returns our isotope number
double dotProduct(const Point2D &other) const
std::vector< int > INT_VECT
int getFormalCharge() const
returns the formal charge of this atom
std::vector< ElementType > DrawMol(const ROMol &mol, int confId=-1, const std::vector< int > *highlightAtoms=0, bool includeAtomCircles=false, unsigned int dotsPerAngstrom=100, double dblBondOffset=0.3, double dblBondLengthFrac=0.8, double angstromsPerChar=0.20)
int getAtomicNum() const
returns our atomic number
bool hasProp(const std::string &key) const
void getProp(const std::string &key, T &res) const
allows retrieval of a particular property value
OBOND_ITER_PAIR getAtomBonds(Atom const *at) const
provides access to all Bond objects connected to an Atom
unsigned int compute2DCoords(RDKit::ROMol &mol, const RDGeom::INT_POINT2D_MAP *coordMap=0, bool canonOrient=false, bool clearConfs=true, unsigned int nFlipsPerSample=0, unsigned int nSamples=0, int sampleSeed=0, bool permuteDeg4Nodes=false)
Generate 2D coordinates (a depiction) for a molecule.
unsigned int getDegree() const
Atom * getAtomWithIdx(unsigned int idx)
returns a pointer to a particular Atom
std::string getSymbol() const
returns our symbol (determined by our atomic number)
The class for representing atoms.
bool isInitialized() const
checks to see if we've been properly initialized
void drawLine(std::vector< ElementType > &res, int atnum1, int atnum2, int lineWidth, int dashed, double x1, double y1, double x2, double y2)