1 package uk.ac.cam.ch.wwmm.opsin;
2 
3 import static org.junit.Assert.*;
4 
5 import java.util.Collections;
6 import java.util.List;
7 
8 import org.junit.Before;
9 import org.junit.Test;
10 
11 import uk.ac.cam.ch.wwmm.opsin.BondStereo.BondStereoValue;
12 
13 public class SMILESWriterTest {
14 
15 	private FragmentManager fm;
16 
17 	@Before
setup()18 	public void setup(){
19 		IDManager idManager = new IDManager();
20 		fm = new FragmentManager(new SMILESFragmentBuilder(idManager), idManager);
21 	}
22 
23 	@Test
testRoundTrip1()24 	public void testRoundTrip1() throws StructureBuildingException {
25 		Fragment f = fm.buildSMILES("C");
26 		fm.makeHydrogensExplicit();
27 		String smiles = SMILESWriter.generateSmiles(f);
28 		assertEquals("C", smiles);
29 	}
30 
31 	@Test
testRoundTrip2()32 	public void testRoundTrip2() throws StructureBuildingException {
33 		Fragment f = fm.buildSMILES("C#N");
34 		fm.makeHydrogensExplicit();
35 		String smiles = SMILESWriter.generateSmiles(f);
36 		assertEquals("C#N", smiles);
37 	}
38 
39 	@Test
testRoundTrip3()40 	public void testRoundTrip3() throws StructureBuildingException {
41 		Fragment f = fm.buildSMILES(StringTools.multiplyString("C",200));
42 		fm.makeHydrogensExplicit();
43 		String smiles = SMILESWriter.generateSmiles(f);
44 		assertEquals(StringTools.multiplyString("C",200), smiles);
45 	}
46 
47 	@Test
testRoundTrip4()48 	public void testRoundTrip4() throws StructureBuildingException {
49 		Fragment f = fm.buildSMILES("O=C=O");
50 		fm.makeHydrogensExplicit();
51 		String smiles = SMILESWriter.generateSmiles(f);
52 		assertEquals("O=C=O", smiles);
53 	}
54 
55 	@Test
testRoundTrip5()56 	public void testRoundTrip5() throws StructureBuildingException {
57 		Fragment f = fm.buildSMILES("CCN(CC)CC");
58 		fm.makeHydrogensExplicit();
59 		String smiles = SMILESWriter.generateSmiles(f);
60 		assertEquals("CCN(CC)CC", smiles);
61 	}
62 
63 	@Test
testRoundTrip6()64 	public void testRoundTrip6() throws StructureBuildingException {
65 		Fragment f = fm.buildSMILES("CC(=O)O");
66 		fm.makeHydrogensExplicit();
67 		String smiles = SMILESWriter.generateSmiles(f);
68 		assertEquals("CC(=O)O", smiles);
69 	}
70 
71 	@Test
testRoundTrip7()72 	public void testRoundTrip7() throws StructureBuildingException {
73 		Fragment f = fm.buildSMILES("C1CCCCC1");
74 		fm.makeHydrogensExplicit();
75 		String smiles = SMILESWriter.generateSmiles(f);
76 		assertEquals("C1CCCCC1", smiles);
77 	}
78 
79 	@Test
testRoundTrip8()80 	public void testRoundTrip8() throws StructureBuildingException {
81 		Fragment f = fm.buildSMILES("C1=CC=CC=C1");
82 		fm.makeHydrogensExplicit();
83 		String smiles = SMILESWriter.generateSmiles(f);
84 		assertEquals("C1=CC=CC=C1", smiles);
85 	}
86 
87 	@Test
testRoundTrip9()88 	public void testRoundTrip9() throws StructureBuildingException {
89 		Fragment f = fm.buildSMILES("NC(Cl)(Br)C(=O)O");
90 		fm.makeHydrogensExplicit();
91 		String smiles = SMILESWriter.generateSmiles(f);
92 		assertEquals("NC(Cl)(Br)C(=O)O", smiles);
93 	}
94 
95 	@Test
testRoundTrip10()96 	public void testRoundTrip10() throws StructureBuildingException {
97 		Fragment f = fm.buildSMILES("[NH4+].[Cl-].F.[He-2]");
98 		fm.makeHydrogensExplicit();
99 		String smiles = SMILESWriter.generateSmiles(f);
100 		assertEquals("[NH4+].[Cl-].F.[He-2]", smiles);
101 	}
102 
103 	@Test
testRoundTrip11()104 	public void testRoundTrip11() throws StructureBuildingException {
105 		Fragment f = fm.buildSMILES("[NH4+].[Cl-].F.[He-2]");
106 		List<Atom> atomList = f.getAtomList();
107 		Collections.reverse(atomList);
108 		f.reorderAtomCollection(atomList);
109 		fm.makeHydrogensExplicit();
110 		String smiles = SMILESWriter.generateSmiles(f);
111 		assertEquals("[He-2].F.[Cl-].[NH4+]", smiles);
112 	}
113 
114 	@Test
testRoundTrip12()115 	public void testRoundTrip12() throws StructureBuildingException {
116 		Fragment f = fm.buildSMILES("CCO.N=O.C#N");
117 		fm.makeHydrogensExplicit();
118 		String smiles = SMILESWriter.generateSmiles(f);
119 		assertEquals("CCO.N=O.C#N", smiles);
120 	}
121 
122 	@Test
testOrganic1()123 	public void testOrganic1() throws StructureBuildingException {
124 		Fragment f = fm.buildSMILES("[S]");
125 		String smiles = SMILESWriter.generateSmiles(f);
126 		assertEquals("[S]", smiles);
127 	}
128 
129 	@Test
testOrganic2()130 	public void testOrganic2() throws StructureBuildingException {
131 		Fragment f = fm.buildSMILES("[S][H]");
132 		String smiles = SMILESWriter.generateSmiles(f);
133 		assertEquals("[SH]", smiles);
134 	}
135 
136 	@Test
testOrganic3()137 	public void testOrganic3() throws StructureBuildingException {
138 		Fragment f = fm.buildSMILES("[S]([H])[H]");
139 		String smiles = SMILESWriter.generateSmiles(f);
140 		assertEquals("S", smiles);
141 	}
142 
143 	@Test
testOrganic4()144 	public void testOrganic4() throws StructureBuildingException {
145 		Fragment f = fm.buildSMILES("[S]([H])([H])[H]");
146 		String smiles = SMILESWriter.generateSmiles(f);
147 		assertEquals("[SH3]", smiles);
148 	}
149 
150 	@Test
testOrganic5()151 	public void testOrganic5() throws StructureBuildingException {
152 		Fragment f = fm.buildSMILES("[S]([H])([H])([H])[H]");
153 		String smiles = SMILESWriter.generateSmiles(f);
154 		assertEquals("[SH4]", smiles);
155 	}
156 
157 	@Test
testOrganic6()158 	public void testOrganic6() throws StructureBuildingException {
159 		Fragment f = fm.buildSMILES("S(F)(F)(F)F");
160 		String smiles = SMILESWriter.generateSmiles(f);
161 		assertEquals("S(F)(F)(F)F", smiles);
162 	}
163 
164 	@Test
testOrganic7()165 	public void testOrganic7() throws StructureBuildingException {
166 		Fragment f = fm.buildSMILES("S([H])(F)(F)(F)(F)F");
167 		String smiles = SMILESWriter.generateSmiles(f);
168 		assertEquals("S(F)(F)(F)(F)F", smiles);
169 	}
170 
171 	@Test
testOrganic8()172 	public void testOrganic8() throws StructureBuildingException {
173 		Fragment f = fm.buildSMILES("S([H])([H])(F)(F)(F)F");
174 		String smiles = SMILESWriter.generateSmiles(f);
175 		assertEquals("[SH2](F)(F)(F)F", smiles);
176 	}
177 
178 	@Test
testOrganic9()179 	public void testOrganic9() throws StructureBuildingException {
180 		Fragment f = fm.buildSMILES("S(F)(F)(F)(F)(F)(F)F");
181 		String smiles = SMILESWriter.generateSmiles(f);
182 		assertEquals("S(F)(F)(F)(F)(F)(F)F", smiles);
183 	}
184 
185 	@Test
testOrganic10()186 	public void testOrganic10() throws StructureBuildingException {
187 		Fragment f = fm.buildSMILES("[I]([H])([H])[H]");
188 		String smiles = SMILESWriter.generateSmiles(f);
189 		assertEquals("[IH3]", smiles);
190 	}
191 
192 	@Test
testCharged1()193 	public void testCharged1() throws StructureBuildingException {
194 		Fragment f = fm.buildSMILES("[CH3+]");
195 		fm.makeHydrogensExplicit();
196 		String smiles = SMILESWriter.generateSmiles(f);
197 		assertEquals("[CH3+]", smiles);
198 	}
199 
200 	@Test
testCharged2()201 	public void testCharged2() throws StructureBuildingException {
202 		Fragment f = fm.buildSMILES("[Mg+2]");
203 		fm.makeHydrogensExplicit();
204 		String smiles = SMILESWriter.generateSmiles(f);
205 		assertEquals("[Mg+2]", smiles);
206 	}
207 	@Test
testCharged3()208 	public void testCharged3() throws StructureBuildingException {
209 		Fragment f = fm.buildSMILES("[BH4-]");
210 		fm.makeHydrogensExplicit();
211 		String smiles = SMILESWriter.generateSmiles(f);
212 		assertEquals("[BH4-]", smiles);
213 	}
214 
215 	@Test
testCharged4()216 	public void testCharged4() throws StructureBuildingException {
217 		Fragment f = fm.buildSMILES("[O-2]");
218 		fm.makeHydrogensExplicit();
219 		String smiles = SMILESWriter.generateSmiles(f);
220 		assertEquals("[O-2]", smiles);
221 	}
222 
223 	@Test
testIsotope()224 	public void testIsotope() throws StructureBuildingException {
225 		Fragment f = fm.buildSMILES("[15NH3]");
226 		fm.makeHydrogensExplicit();
227 		String smiles = SMILESWriter.generateSmiles(f);
228 		assertEquals("[15NH3]", smiles);
229 	}
230 
231 	@Test
testRGroup1()232 	public void testRGroup1() throws StructureBuildingException {
233 		Fragment f = fm.buildSMILES("[R]CC[R]");
234 		fm.makeHydrogensExplicit();
235 		String smiles = SMILESWriter.generateSmiles(f);
236 		assertEquals("*CC*", smiles);
237 	}
238 
239 	@Test
testRGroup2()240 	public void testRGroup2() throws StructureBuildingException {
241 		Fragment f = fm.buildSMILES("[H][R]");
242 		fm.makeHydrogensExplicit();
243 		String smiles = SMILESWriter.generateSmiles(f);
244 		assertEquals("[H]*", smiles);
245 	}
246 
247 	@Test
testRingOpeningsGreaterThan10()248 	public void testRingOpeningsGreaterThan10() throws StructureBuildingException {
249 		Fragment f = fm.buildSMILES("C12=C3C4=C5C6=C1C7=C8C9=C1C%10=C%11C(=C29)C3=C2C3=C4C4=C5C5=C9C6=C7C6=C7C8=C1C1=C8C%10=C%10C%11=C2C2=C3C3=C4C4=C5C5=C%11C%12=C(C6=C95)C7=C1C1=C%12C5=C%11C4=C3C3=C5C(=C81)C%10=C23");
250 		fm.makeHydrogensExplicit();
251 		String smiles = SMILESWriter.generateSmiles(f);
252 		assertEquals("C12=C3C4=C5C6=C1C1=C7C8=C9C%10=C%11C(=C28)C3=C3C2=C4C4=C5C5=C8C6=C1C1=C6C7=C9C9=C7C%10=C%10C%11=C3C3=C2C2=C4C4=C5C5=C%11C%12=C(C1=C85)C6=C9C9=C%12C%12=C%11C4=C2C2=C%12C(=C79)C%10=C32", smiles);
253 	}
254 
255 	@Test
testHydrogenNotBondedToAnyNonHydrogen1()256 	public void testHydrogenNotBondedToAnyNonHydrogen1() throws StructureBuildingException {
257 		Fragment f = fm.buildSMILES("[H-].[H+]");
258 		String smiles = SMILESWriter.generateSmiles(f);
259 		assertEquals("[H-].[H+]", smiles);
260 	}
261 
262 	@Test
testHydrogenNotBondedToAnyNonHydrogen2()263 	public void testHydrogenNotBondedToAnyNonHydrogen2() throws StructureBuildingException {
264 		Fragment f = fm.buildSMILES("[H][H]");
265 		String smiles = SMILESWriter.generateSmiles(f);
266 		assertEquals("[H][H]", smiles);
267 	}
268 
269 	@Test
testHydrogenNotBondedToAnyNonHydrogen3()270 	public void testHydrogenNotBondedToAnyNonHydrogen3() throws StructureBuildingException {
271 		Fragment f = fm.buildSMILES("[2H][H]");
272 		String smiles = SMILESWriter.generateSmiles(f);
273 		assertEquals("[2H][H]", smiles);
274 	}
275 
276 	@Test
testHydrogenNotBondedToAnyNonHydrogen4()277 	public void testHydrogenNotBondedToAnyNonHydrogen4() throws StructureBuildingException {
278 		Fragment f = fm.buildSMILES("[H]B1[H]B([H])[H]1");
279 		String smiles = SMILESWriter.generateSmiles(f);
280 		assertEquals("B1[H]B[H]1", smiles);
281 	}
282 
283 	@Test
testTetrahedralChirality1()284 	public void testTetrahedralChirality1() throws StructureBuildingException {
285 		Fragment f = fm.buildSMILES("N[C@@H](F)C");
286 		fm.makeHydrogensExplicit();
287 		String smiles = SMILESWriter.generateSmiles(f);
288 		assertEquals("N[C@@H](F)C", smiles);
289 	}
290 
291 	@Test
testTetrahedralChirality2()292 	public void testTetrahedralChirality2() throws StructureBuildingException {
293 		Fragment f = fm.buildSMILES("N[C@H](F)C");
294 		fm.makeHydrogensExplicit();
295 		String smiles = SMILESWriter.generateSmiles(f);
296 		assertEquals("N[C@H](F)C", smiles);
297 	}
298 
299 	@Test
testTetrahedralChirality3()300 	public void testTetrahedralChirality3() throws StructureBuildingException {
301 		Fragment f = fm.buildSMILES("C2.N1.F3.[C@@H]231");
302 		fm.makeHydrogensExplicit();
303 		String smiles = SMILESWriter.generateSmiles(f);
304 		assertEquals("C[C@H](F)N", smiles);
305 	}
306 
307 	@Test
testTetrahedralChirality4()308 	public void testTetrahedralChirality4() throws StructureBuildingException {
309 		Fragment f = fm.buildSMILES("[C@@H]231.C2.N1.F3");
310 		fm.makeHydrogensExplicit();
311 		String smiles = SMILESWriter.generateSmiles(f);
312 		assertEquals("[C@H](C)(N)F", smiles);
313 	}
314 
315 	@Test
testTetrahedralChirality5()316 	public void testTetrahedralChirality5() throws StructureBuildingException {
317 		Fragment f = fm.buildSMILES("[C@@H](Cl)1[C@H](C)(F).Br1");
318 		fm.makeHydrogensExplicit();
319 		String smiles = SMILESWriter.generateSmiles(f);
320 		assertEquals("[C@H](Cl)([C@H](C)F)Br", smiles);
321 	}
322 
323 	@Test
testTetrahedralChirality6()324 	public void testTetrahedralChirality6() throws StructureBuildingException {
325 		Fragment f = fm.buildSMILES("I[C@@](Cl)(Br)F");
326 		fm.makeHydrogensExplicit();
327 		String smiles = SMILESWriter.generateSmiles(f);
328 		assertEquals("I[C@@](Cl)(Br)F", smiles);
329 	}
330 
331 
332 	@Test
testTetrahedralChirality7()333 	public void testTetrahedralChirality7() throws StructureBuildingException {
334 		Fragment f = fm.buildSMILES("C[S@](N)=O");
335 		fm.makeHydrogensExplicit();
336 		String smiles = SMILESWriter.generateSmiles(f);
337 		assertEquals("C[S@](N)=O", smiles);
338 	}
339 
340 	@Test
testDoubleBondSupport1()341 	public void testDoubleBondSupport1() throws StructureBuildingException {
342 		Fragment f = fm.buildSMILES("C/C=C/C");
343 		fm.makeHydrogensExplicit();
344 		String smiles = SMILESWriter.generateSmiles(f);
345 		if (!smiles.equals("C/C=C/C") && !smiles.equals("C\\C=C\\C")){
346 			fail(smiles +" did not correspond to one of the expected SMILES strings");
347 		}
348 	}
349 
350 
351 	@Test
testDoubleBondSupport2()352 	public void testDoubleBondSupport2() throws StructureBuildingException {
353 		Fragment f = fm.buildSMILES("C/C=C\\C");
354 		fm.makeHydrogensExplicit();
355 		String smiles = SMILESWriter.generateSmiles(f);
356 		if (!smiles.equals("C/C=C\\C") && !smiles.equals("C\\C=C/C")){
357 			fail(smiles +" did not correspond to one of the expected SMILES strings");
358 		}
359 	}
360 
361 
362 	@Test
testDoubleBondSupport3()363 	public void testDoubleBondSupport3() throws StructureBuildingException {
364 		Fragment f = fm.buildSMILES("C/C=C\\C=C/C");
365 		fm.makeHydrogensExplicit();
366 		String smiles = SMILESWriter.generateSmiles(f);
367 		if (!smiles.equals("C/C=C\\C=C/C") && !smiles.equals("C\\C=C/C=C\\C")){
368 			fail(smiles +" did not correspond to one of the expected SMILES strings");
369 		}
370 	}
371 
372 	@Test
testDoubleBondSupport4()373 	public void testDoubleBondSupport4() throws StructureBuildingException {
374 		Fragment f = fm.buildSMILES("ClC(C(=O)[O-])=CC(=CC(=O)[O-])Cl");
375 		fm.makeHydrogensExplicit();
376 		f.findBond(2, 6).setBondStereoElement(new Atom[]{f.getAtomByID(1), f.getAtomByID(2), f.getAtomByID(6), f.getAtomByID(7)}, BondStereoValue.TRANS);
377 		f.findBond(7, 8).setBondStereoElement(new Atom[]{f.getAtomByID(12), f.getAtomByID(7), f.getAtomByID(8), f.getAtomByID(9)}, BondStereoValue.TRANS);
378 		String smiles = SMILESWriter.generateSmiles(f);
379 		if (!smiles.equals("Cl\\C(\\C(=O)[O-])=C\\C(=C/C(=O)[O-])\\Cl") && !smiles.equals("Cl/C(/C(=O)[O-])=C/C(=C\\C(=O)[O-])/Cl")){
380 			fail(smiles +" did not correspond to one of the expected SMILES strings");
381 		}
382 	}
383 
384 	@Test
testDoubleBondSupport5()385 	public void testDoubleBondSupport5() throws StructureBuildingException {
386 		Fragment f = fm.buildSMILES("C/C=N\\O");
387 		fm.makeHydrogensExplicit();
388 		String smiles = SMILESWriter.generateSmiles(f);
389 		if (!smiles.equals("C/C=N\\O") && !smiles.equals("C\\C=N/O")){
390 			fail(smiles +" did not correspond to one of the expected SMILES strings");
391 		}
392 	}
393 
394 	@Test
testDoubleBondSupport6()395 	public void testDoubleBondSupport6() throws StructureBuildingException {
396 		Fragment f = fm.buildSMILES("O=C(/C=C(C(O)=O)\\C=C/C(O)=O)O");
397 		fm.makeHydrogensExplicit();
398 		String smiles = SMILESWriter.generateSmiles(f);
399 		if (!smiles.equals("O=C(/C=C(/C(O)=O)\\C=C/C(O)=O)O") && !smiles.equals("O=C(\\C=C(\\C(O)=O)/C=C\\C(O)=O)O")){
400 			fail(smiles +" did not correspond to one of the expected SMILES strings");
401 		}
402 	}
403 
404 	@Test
testDoubleBondSupport7()405 	public void testDoubleBondSupport7() throws StructureBuildingException {
406 		Fragment f = fm.buildSMILES("C(=C(C=CC(=O)O)C(=O)O)C(=O)O");
407 		fm.makeHydrogensExplicit();
408 		f.findBond(1, 2).setBondStereoElement(new Atom[]{f.getAtomByID(11), f.getAtomByID(1), f.getAtomByID(2), f.getAtomByID(8)}, BondStereoValue.TRANS);
409 		f.findBond(3, 4).setBondStereoElement(new Atom[]{f.getAtomByID(2), f.getAtomByID(3), f.getAtomByID(4), f.getAtomByID(5)}, BondStereoValue.TRANS);
410 		String smiles = SMILESWriter.generateSmiles(f);
411 		if (!smiles.equals("C(=C(/C=C/C(=O)O)\\C(=O)O)/C(=O)O") && !smiles.equals("C(=C(\\C=C\\C(=O)O)/C(=O)O)\\C(=O)O")){
412 			fail(smiles +" did not correspond to one of the expected SMILES strings");
413 		}
414 	}
415 
416 	@Test
testDoubleBondSupport8()417 	public void testDoubleBondSupport8() throws StructureBuildingException {
418 		//hydrogen on the nitrogen must be explicit!
419 		Fragment f = fm.buildSMILES("[H]/N=C(\\N)/O");
420 		fm.makeHydrogensExplicit();
421 		String smiles = SMILESWriter.generateSmiles(f);
422 		if (!smiles.equals("[H]/N=C(\\N)/O") && !smiles.equals("[H]\\N=C(/N)\\O")){
423 			fail(smiles +" did not correspond to one of the expected SMILES strings");
424 		}
425 	}
426 
427 	@Test
testLabelling1()428 	public void testLabelling1() throws StructureBuildingException {
429 		Fragment f = fm.buildSMILES("CCC", "", XmlDeclarations.NONE_LABELS_VAL);
430 		for (Atom a : f.getAtomList()) {
431 			assertEquals(0, a.getLocants().size());
432 		}
433 
434 		Fragment f2 = fm.buildSMILES("CCC", "", "");
435 		for (Atom a : f2.getAtomList()) {
436 			assertEquals(0, a.getLocants().size());
437 		}
438 	}
439 
440 	@Test
testLabelling2()441 	public void testLabelling2() throws StructureBuildingException {
442 		Fragment f = fm.buildSMILES("CCC", "", "1/2,alpha,2'/");
443 		List<Atom> atoms = f.getAtomList();
444 		assertEquals(1, atoms.get(0).getLocants().size());
445 		assertEquals(3, atoms.get(1).getLocants().size());
446 		assertEquals(0, atoms.get(2).getLocants().size());
447 
448 		assertEquals("1", atoms.get(0).getLocants().get(0));
449 		assertEquals("2", atoms.get(1).getLocants().get(0));
450 		assertEquals("alpha", atoms.get(1).getLocants().get(1));
451 		assertEquals("2'", atoms.get(1).getLocants().get(2));
452 	}
453 }
454