Skip to content

Commit 45671d5

Browse files
committed
add continuous highlighting
1 parent 0574c28 commit 45671d5

File tree

3 files changed

+130
-4
lines changed

3 files changed

+130
-4
lines changed

Code/GraphMol/MolDraw2D/MolDraw2D.cpp

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,70 @@ namespace RDKit {
4848
}
4949
drawMolecule(mol,highlight_atoms,&highlight_bonds,highlight_atom_map);
5050
}
51+
52+
void MolDraw2D::doContinuousHighlighting( const ROMol &mol ,
53+
const vector<int> *highlight_atoms ,
54+
const vector<int> *highlight_bonds ,
55+
const map<int,DrawColour> *highlight_atom_map,
56+
const map<int,DrawColour> *highlight_bond_map ) {
57+
int orig_lw=lineWidth();
58+
bool orig_fp=fillPolys();
59+
ROMol::VERTEX_ITER this_at , end_at;
60+
if(highlight_bonds){
61+
boost::tie( this_at , end_at ) = mol.getVertices();
62+
while( this_at != end_at ) {
63+
int this_idx = mol[*this_at]->getIdx();
64+
ROMol::OEDGE_ITER nbr , end_nbr;
65+
boost::tie( nbr , end_nbr ) = mol.getAtomBonds( mol[*this_at].get() );
66+
while( nbr != end_nbr ) {
67+
const BOND_SPTR bond = mol[*nbr];
68+
++nbr;
69+
int nbr_idx = bond->getOtherAtomIdx( this_idx );
70+
if( nbr_idx < static_cast<int>( at_cds_.size() ) && nbr_idx > this_idx ) {
71+
if(std::find(highlight_bonds->begin(),highlight_bonds->end(),bond->getIdx()) != highlight_bonds->end()){
72+
DrawColour col=drawOptions().highlightColour;
73+
if(highlight_bond_map &&
74+
highlight_bond_map->find(bond->getIdx())!=highlight_bond_map->end()){
75+
col = highlight_bond_map->find(bond->getIdx())->second;
76+
}
77+
setLineWidth(orig_lw*8);
78+
pair<float,float> at1_cds = at_cds_[this_idx];
79+
pair<float,float> at2_cds = at_cds_[nbr_idx];
80+
drawLine( at1_cds , at2_cds , col , col);
81+
}
82+
}
83+
}
84+
++this_at;
85+
}
86+
}
87+
if(highlight_atoms){
88+
boost::tie( this_at , end_at ) = mol.getVertices();
89+
while( this_at != end_at ) {
90+
int this_idx = mol[*this_at]->getIdx();
91+
if(std::find(highlight_atoms->begin(),highlight_atoms->end(),this_idx) != highlight_atoms->end()){
92+
DrawColour col=drawOptions().highlightColour;
93+
if(highlight_atom_map &&
94+
highlight_atom_map->find(this_idx)!=highlight_atom_map->end()){
95+
col = highlight_atom_map->find(this_idx)->second;
96+
}
97+
std::pair<double,double> p1=at_cds_[this_idx];
98+
std::pair<double,double> p2=at_cds_[this_idx];
99+
p1.first -= 0.4;
100+
p1.second -= 0.4;
101+
p2.first += 0.4;
102+
p2.second += 0.4;
103+
setColour(col);
104+
setFillPolys(true);
105+
setLineWidth(1);
106+
drawEllipse(p1,p2);
107+
}
108+
++this_at;
109+
}
110+
}
111+
setLineWidth(orig_lw);
112+
setFillPolys(orig_fp);
113+
}
114+
51115
void MolDraw2D::drawMolecule( const ROMol &mol ,
52116
const vector<int> *highlight_atoms ,
53117
const vector<int> *highlight_bonds ,
@@ -59,7 +123,14 @@ namespace RDKit {
59123
calculateScale();
60124
setFontSize( font_size_ );
61125

62-
if(drawOptions().circleAtoms && highlight_atoms){
126+
if(drawOptions().continuousHighlight){
127+
// if we're doing continuous highlighting, start by drawing the highlights
128+
doContinuousHighlighting(mol,highlight_atoms,highlight_bonds,
129+
highlight_atom_map,highlight_bond_map);
130+
// at this point we shouldn't be doing any more higlighting, so blow out those variables:
131+
highlight_bonds=NULL;
132+
highlight_atoms=NULL;
133+
} else if(drawOptions().circleAtoms && highlight_atoms){
63134
ROMol::VERTEX_ITER this_at , end_at;
64135
boost::tie( this_at , end_at ) = mol.getVertices();
65136
setFillPolys(false);
@@ -414,7 +485,7 @@ namespace RDKit {
414485
std::find(highlight_bonds->begin(),highlight_bonds->end(),bond->getIdx()) != highlight_bonds->end()){
415486
highlight_bond=true;
416487
}
417-
488+
418489
DrawColour col1,col2;
419490
int orig_lw=lineWidth();
420491
if( !highlight_bond ){
@@ -427,7 +498,11 @@ namespace RDKit {
427498
} else {
428499
col1 = col2 = drawOptions().highlightColour;
429500
}
430-
setLineWidth(orig_lw*2);
501+
if( drawOptions().continuousHighlight ){
502+
setLineWidth(orig_lw*8);
503+
} else {
504+
setLineWidth(orig_lw*2);
505+
}
431506
}
432507

433508

Code/GraphMol/MolDraw2D/MolDraw2D.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ namespace RDKit {
4040
bool circleAtoms; // draws circles under highlighted atoms
4141
DrawColour highlightColour; // default highlight color
4242
std::map<int,std::string> *atomLabels; // replacement labels for atoms
43+
bool continuousHighlight; // highlight by drawing an outline *underneath* the molecule
4344

4445
MolDrawOptions() :
4546
dummiesAreAttachments(false),
4647
circleAtoms(true),
4748
highlightColour(1,0,0),
48-
atomLabels(NULL)
49+
atomLabels(NULL),
50+
continuousHighlight(false)
4951
{};
5052
};
5153

@@ -207,6 +209,13 @@ namespace RDKit {
207209
// adds LaTeX-like annotation for super- and sub-script.
208210
std::pair<std::string,OrientType> getAtomSymbolAndOrientation( const Atom &atom ,
209211
const std::pair<float,float> &nbr_sum );
212+
213+
virtual void doContinuousHighlighting( const ROMol &mol ,
214+
const std::vector<int> *highlight_atoms,
215+
const std::vector<int> *highlight_bonds,
216+
const std::map<int,DrawColour> *highlight_atom_map,
217+
const std::map<int,DrawColour> *highlight_bond_map );
218+
210219
};
211220

212221
}

Code/GraphMol/MolDraw2D/test1.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,48 @@ void test3(){
281281
}
282282
delete m;
283283
}
284+
{
285+
std::string smiles="Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-]";
286+
std::string nameBase="test3_4";
287+
ROMol *m = SmilesToMol(smiles);
288+
TEST_ASSERT(m);
289+
RDDepict::compute2DCoords(*m);
290+
WedgeMolBonds(*m,&(m->getConformer()));
291+
static const int ha[] = {11,12,13,14,15,16,3};
292+
std::vector<int> highlight_atoms(ha, ha+sizeof(ha)/sizeof(int));
293+
std::map<int,DrawColour> highlight_colors;
294+
highlight_colors[12]=DrawColour(.5,.5,1);
295+
highlight_colors[13]=DrawColour(.5,1,.5);
296+
MolDrawOptions options;
297+
options.circleAtoms=true;
298+
options.highlightColour=DrawColour(1,.5,.5);
299+
options.continuousHighlight=true;
300+
301+
#ifdef RDK_CAIRO_BUILD
302+
{
303+
cairo_surface_t *surface =
304+
cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 300, 300);
305+
cairo_t *cr = cairo_create (surface);
306+
307+
MolDraw2DCairo drawer(300,300,cr);
308+
drawer.drawOptions() = options;
309+
drawer.drawMolecule(*m,&highlight_atoms,&highlight_colors);
310+
drawer.finishDrawing();
311+
cairo_destroy (cr);
312+
cairo_surface_write_to_png (surface, (nameBase+".png").c_str());
313+
cairo_surface_destroy (surface);
314+
}
315+
#endif
316+
{
317+
std::ofstream outs((nameBase+".svg").c_str());
318+
MolDraw2DSVG drawer(300,300,outs);
319+
drawer.drawOptions() = options;
320+
drawer.drawMolecule(*m,&highlight_atoms,&highlight_colors);
321+
drawer.finishDrawing();
322+
outs.flush();
323+
}
324+
delete m;
325+
}
284326
std::cout << " Done" << std::endl;
285327
}
286328

0 commit comments

Comments
 (0)