-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMolDraw2D.H
166 lines (136 loc) · 7.48 KB
/
MolDraw2D.H
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
//
// file MolDraw2D.H
// David Cosgrove
// AstraZeneca
// 27th May 2014
//
// This class makes a 2D drawing of an RDKit molecule.
// It draws heavily on $RDBASE/GraphMol/MolDrawing/MolDrawing.h.
// One purpose of this is to make it easier to overlay annotations on top of
// the molecule drawing, which is difficult to do from the output of
// MolDrawing.h
// The class design philosophy echoes that of the OpenEye's original OEDepict
// classes, with a virtual base class defining the interface and doing all
// the heavy lifting and concrete derived classes that implement
// library-specific drawing code such as drawing a line, writing a string
// etc.
#ifndef RDKITMOLDRAW2D_H
#define RDKITMOLDRAW2D_H
#include <vector>
#include <GraphMol/RDKitBase.h>
#include <boost/tuple/tuple.hpp>
// ****************************************************************************
namespace RDKit {
class MolDraw2D {
public :
typedef enum { C = 0 , N , E , S , W } OrientType;
typedef boost::tuple<float,float,float> DrawColour;
MolDraw2D( int width , int height );
virtual ~MolDraw2D() {}
virtual void DrawMolecule( const ROMol &mol ,
const std::vector<int> &highlight_atoms = std::vector<int>() ,
const std::map<int,DrawColour> &highlight_map = std::map<int,DrawColour>() );
// transform a set of coords in the molecule's coordinate system
// to drawing system coordinates and vice versa. Note that the coordinates have
// the origin in the top left corner, which is how Qt and Cairo have it, no
// doubt a holdover from X Windows. This means that a higher y value will be
// nearer the bottom of the screen. This doesn't really matter except when
// doing text superscripts and subscripts.
virtual std::pair<float,float> getDrawCoords( const std::pair<float,float> &mol_cds ) const;
virtual std::pair<float,float> getDrawCoords( int at_num ) const;
virtual std::pair<float,float> getAtomCoords( const std::pair<int,int> &screen_cds ) const;
virtual std::pair<float,float> getAtomCoords( int at_num ) const;
virtual int width() const { return width_; }
virtual int height() const { return height_; }
virtual float scale() const { return scale_; }
virtual float fontSize() const { return font_size_; }
// set font size in molecule coordinate units. That's probably Angstrom for
// RDKit.
virtual void setFontSize( float new_size );
virtual void calculateScale();
virtual void setColour( const DrawColour &col ) { curr_colour_ = col; }
virtual DrawColour getColour() const { return curr_colour_; }
// establishes whether to put string draw mode into super- or sub-script
// mode based on contents of instring from i onwards. Increments i appropriately
// and returns true or false depending on whether it did something or not
bool set_string_draw_mode( const std::string &instring , int &draw_mode ,
int &i ) const;
private :
int width_ , height_;
float scale_;
float x_min_ , y_min_ , x_range_ , y_range_;
float x_trans_ , y_trans_;
// font_size_ in molecule coordinate units. Default 0.5 (a bit bigger
// than the default width of a double bond)
float font_size_;
DrawColour curr_colour_;
std::vector<std::pair<float,float> > at_cds_; // from mol
std::vector<int> atomic_nums_;
std::vector<std::pair<std::string,OrientType> > atom_syms_;
virtual void drawLine( const std::pair<float,float> &cds1 ,
const std::pair<float,float> &cds2 ) = 0;
virtual void drawLine( const std::pair<float,float> &cds1 ,
const std::pair<float,float> &cds2 ,
const DrawColour &col1 ,
const DrawColour &col2 );
// draw the char, with the bottom left hand corner at cds
virtual void drawChar( char c , const std::pair<float,float> &cds ) = 0;
// drawString centres the string on cds.
virtual void drawString( const std::string &str ,
const std::pair<float,float> &cds );
// draw a filled triangle
virtual void drawTriangle( const std::pair<float,float> &cds1 ,
const std::pair<float,float> &cds2 ,
const std::pair<float,float> &cds3 ) = 0;
virtual void clearDrawing() = 0;
// using the current scale, work out the size of the label in molecule coordinates.
// Bear in mind when implementing this, that, for example, NH2 will appear as
// NH<sub>2</sub> to convey that the 2 is a subscript, and this needs to accounted
// for in the width and height.
virtual void getStringSize( const std::string &label , float &label_width ,
float &label_height ) const = 0;
// return a DrawColour based on the contents of highlight_atoms or
// highlight_map, falling back to atomic number by default
DrawColour get_colour( int atom_idx ,
const std::vector<int> &highlight_atoms ,
const std::map<int,DrawColour> &highlight_map );
DrawColour get_colour_by_atomic_num( int atomic_num );
void extract_atom_coords( const ROMol &mol );
void extract_atom_symbols( const ROMol &mol );
void draw_bond( const ROMol &mol , const BOND_SPTR &bond ,
int at1_idx , int at2_idx ,
const std::vector<int> &highlight_atoms ,
const std::map<int,DrawColour> &highlight_map );
void draw_wedged_bond( const std::pair<float,float> &cds1 ,
const std::pair<float,float> &cds2 ,
bool draw_dashed , const DrawColour &col1 ,
const DrawColour &col2 );
void draw_atom_label( int atom_num ,
const std::vector<int> &highlight_atoms ,
const std::map<int,DrawColour> &highlight_map );
// calculate normalised perpendicular to vector between two coords
std::pair<float,float> calc_perpendicular( const std::pair<float,float> &cds1 ,
const std::pair<float,float> &cds2 );
// cds1 and cds2 are 2 atoms in a ring. Returns the perpendicular pointing into
// the ring.
std::pair<float,float> bond_inside_ring( const ROMol &mol , const BOND_SPTR &bond ,
const std::pair<float,float> &cds1 ,
const std::pair<float,float> &cds2 );
// cds1 and cds2 are 2 atoms in a chain double bond. Returns the perpendicular
// pointing into the inside of the bond
std::pair<float,float> bond_inside_double_bond( const ROMol &mol , const BOND_SPTR &bond );
// calculate normalised perpendicular to vector between two coords, such that
// it's inside the angle made between (1 and 2) and (2 and 3).
std::pair<float,float> calc_inner_perpendicular( const std::pair<float,float> &cds1 ,
const std::pair<float,float> &cds2 ,
const std::pair<float,float> &cds3 );
// take the coords for atnum, with neighbour nbr_cds, and move cds out to accommodate
// the label associated with it.
void adjust_bond_end_for_label( int atnum , const std::pair<float,float> &nbr_cds ,
std::pair<float,float> &cds ) const;
// adds LaTeX-like annotation for super- and sub-script.
std::pair<std::string,OrientType> get_atom_symbol_and_orientation( const Atom &atom ,
const std::pair<float,float> &nbr_sum );
};
}
#endif // RDKITMOLDRAW2D_H