1 package org.molwind.chemical.view;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import java.awt.Color;
21 import java.awt.Dimension;
22 import java.awt.Font;
23 import java.awt.Graphics2D;
24 import java.awt.image.BufferedImage;
25 import java.util.ArrayList;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.List;
29
30 import org.openscience.cdk.DefaultChemObjectBuilder;
31 import org.openscience.cdk.aromaticity.HueckelAromaticityDetector;
32 import org.openscience.cdk.exception.CDKException;
33 import org.openscience.cdk.geometry.GeometryTools;
34 import org.openscience.cdk.interfaces.IAtomContainer;
35 import org.openscience.cdk.interfaces.IBond;
36 import org.openscience.cdk.interfaces.IMolecule;
37 import org.openscience.cdk.interfaces.IMoleculeSet;
38 import org.openscience.cdk.isomorphism.UniversalIsomorphismTester;
39 import org.openscience.cdk.isomorphism.mcss.RMap;
40 import org.openscience.cdk.renderer.IRenderer2D;
41 import org.openscience.cdk.renderer.Renderer2D;
42 import org.openscience.cdk.renderer.Renderer2DModel;
43
44 import org.molwind.chemical.model.ChemicalEntity;
45 import org.molwind.model.PartOf;
46
47
48
49
50
51
52
53
54 public class SubstructureRenderer implements MoleculeRenderer {
55
56 private double zoom = 1d;
57
58
59
60
61
62
63
64 public double getZoom() {
65 return zoom;
66 }
67
68
69
70
71
72
73
74 public void setZoom(final double newZoom) {
75 this.zoom = newZoom;
76 }
77
78
79 private void detectAromaticity(final ChemicalEntity chemicalEntity)
80 throws CDKException {
81 IMolecule molecule = chemicalEntity.getMolecule();
82 HueckelAromaticityDetector.detectAromaticity(molecule);
83 }
84
85 private IAtomContainer markSubstructure(
86 final ChemicalEntity chemicalEntity,
87 final ChemicalEntity[] parents)
88 throws CDKException {
89 IMolecule molecule = chemicalEntity.getMolecule();
90 ArrayList atomIndex = new ArrayList();
91
92 for (int i = 0; i < parents.length; i++) {
93 IMolecule parentMolecule = parents[i].getMolecule();
94 if (UniversalIsomorphismTester.isSubgraph(
95 molecule, parentMolecule)) {
96 List sMap = UniversalIsomorphismTester.getSubgraphAtomsMaps(
97 molecule, parentMolecule);
98 Iterator it = ((List) sMap.get(0)).iterator();
99
100 while (it.hasNext()) {
101 RMap rm = (RMap) it.next();
102 Integer ai = Integer.valueOf(rm.getId1());
103 if (!atomIndex.contains(ai)) {
104 atomIndex.add(ai);
105 }
106 }
107 }
108 }
109
110 Integer[] ato = new Integer[atomIndex.size()];
111 ato = (Integer[]) atomIndex.toArray(ato);
112 IAtomContainer highB =
113 DefaultChemObjectBuilder.getInstance().newAtomContainer();
114 IBond bond;
115
116 for (int i = 0; i < ato.length; i++) {
117 for (int j = i + 1; j < ato.length; j++) {
118 bond = highB.getBond(molecule.getAtom(ato[i]),
119 molecule.getAtom(ato[j]));
120 if (bond != null) {
121 highB.addBond(bond);
122 }
123 }
124 }
125 return highB;
126 }
127
128 private Color getBackgroundColor(final ChemicalEntity chemicalEntity) {
129 ChemicalEntity[] children =
130 (ChemicalEntity[]) chemicalEntity.getRelationship(
131 PartOf.right(chemicalEntity));
132
133 Color background = Color.white;
134
135 if (children.length > 0) {
136 if (children.length < 6) {
137 background = new Color(190, 255, 190);
138 } else if (children.length < 16) {
139 background = new Color(255, 255, 160);
140 } else {
141 background = new Color(255, 160, 160);
142 }
143 }
144 return background;
145 }
146
147 private Dimension scaleMolecule(final ChemicalEntity chemicalEntity,
148 final HashMap coordinates) {
149 IMolecule molecule = chemicalEntity.getMolecule();
150 Dimension imageDimension = GeometryTools.get2DDimension(
151 molecule, coordinates);
152
153 GeometryTools.makeRenderingCoordinates(
154 (IMoleculeSet) molecule, coordinates);
155 GeometryTools.scaleMolecule(molecule, imageDimension, 15, coordinates);
156 GeometryTools.center(molecule, imageDimension, coordinates);
157 GeometryTools.translateAllPositive(molecule, coordinates);
158 GeometryTools.translate2D(molecule, 10, 0, coordinates);
159
160 double[] minMax = GeometryTools.getMinMax(molecule, coordinates);
161 int width = (int) minMax[2] - (int) minMax[0];
162 int height = (int) minMax[3] - (int) minMax[1];
163 imageDimension.setSize(width + 10, height + 10);
164
165 return imageDimension;
166 }
167
168 private BufferedImage createImage(final Dimension dimension) {
169 return new BufferedImage(((int) dimension.getWidth()) + 15,
170 ((int) dimension.getHeight()) + 15, BufferedImage.TYPE_INT_RGB);
171 }
172
173 private BufferedImage renderImage(
174 final Dimension dimension,
175 final ChemicalEntity chemicalEntity,
176 final IAtomContainer highB,
177 final HashMap coordinates) {
178 BufferedImage image = createImage(dimension);
179 Renderer2DModel r2dm = new Renderer2DModel();
180
181 r2dm.setSelectedPartColor(Color.GREEN);
182 r2dm.setSelectedPart(highB);
183
184 double z = getZoom() * 2;
185 int width = (int) (dimension.getWidth() * z);
186 int height = (int) (dimension.getHeight() * z);
187
188 Font font = new Font("Arial", Font.PLAIN, (int) (12 * 2 * z));
189
190 r2dm.setBackgroundDimension(dimension);
191 r2dm.setDrawNumbers(false);
192 r2dm.setColorAtomsByType(true);
193 r2dm.setShowAromaticity(false);
194 r2dm.setZoomFactor(z);
195 r2dm.setUseAntiAliasing(true);
196 r2dm.setIsCompact(false);
197
198 Color background = getBackgroundColor(chemicalEntity);
199 r2dm.setBackColor(background);
200
201 Graphics2D g2d = image.createGraphics();
202 IRenderer2D r2d = new Renderer2D(r2dm);
203
204 g2d.setColor(background);
205 g2d.fillRect(0, 0, width + 15, height + 15);
206 g2d.setColor(Color.black);
207
208 r2dm.setRenderingCoordinates(coordinates);
209 IMolecule molecule = chemicalEntity.getMolecule();
210 r2d.paintMoleculeSet((IMoleculeSet) molecule, g2d);
211
212 return image;
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226 public BufferedImage getImage(final ChemicalEntity chemicalEntity)
227 throws CDKException {
228 ChemicalEntity[] parents =
229 (ChemicalEntity[]) chemicalEntity.getRelationship(
230 PartOf.left(chemicalEntity));
231
232 for (int i = 0; i < parents.length; i++) {
233 detectAromaticity(parents[i]);
234 }
235 detectAromaticity(chemicalEntity);
236
237 IAtomContainer hiMol = markSubstructure(chemicalEntity, parents);
238 HashMap coordinates = new HashMap();
239 Dimension dimension = scaleMolecule(chemicalEntity, coordinates);
240 BufferedImage image = renderImage(dimension, chemicalEntity,
241 hiMol, coordinates);
242
243 return image;
244 }
245
246 }