$darkmode
DENOPTIM
TemplateTest.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2022 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.graph;
20
21import static org.junit.jupiter.api.Assertions.assertEquals;
22import static org.junit.jupiter.api.Assertions.assertSame;
23import static org.junit.jupiter.api.Assertions.assertThrows;
24import static org.junit.jupiter.api.Assertions.assertTrue;
25import static org.junit.jupiter.api.Assertions.fail;
26
27import java.io.File;
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.List;
31import java.util.Random;
32
33import javax.vecmath.Point3d;
34
35import org.junit.jupiter.api.Test;
36import org.junit.jupiter.api.io.TempDir;
37import org.openscience.cdk.DefaultChemObjectBuilder;
38import org.openscience.cdk.exception.CDKException;
39import org.openscience.cdk.geometry.alignment.KabschAlignment;
40import org.openscience.cdk.interfaces.IAtom;
41import org.openscience.cdk.interfaces.IAtomContainer;
42import org.openscience.cdk.interfaces.IBond;
43import org.openscience.cdk.interfaces.IChemObjectBuilder;
44
45import denoptim.exception.DENOPTIMException;
46import denoptim.graph.Vertex.BBType;
47import denoptim.io.DenoptimIO;
48import denoptim.utils.GraphUtils;
49import denoptim.utils.MoleculeUtils;
50
55public class TemplateTest
56{
57 final long SEED = 13;
58 Random rng = new Random(SEED);
59 static IChemObjectBuilder chemBuilder = DefaultChemObjectBuilder.getInstance();
60
61 @TempDir
62 File tempDir;
63
64 private final String NL = System.getProperty("line.separator");
65 private final String SEP = System.getProperty("file.separator");
66
67//------------------------------------------------------------------------------
68
69 @Test
70 public void testClone() throws Exception
71 {
72 EmptyVertex vA = new EmptyVertex(0);
73 vA.addAP();
74 vA.addAP();
75 vA.addAP();
76 EmptyVertex vB = new EmptyVertex(1);
77 vB.addAP();
78 vB.addAP();
79 EmptyVertex vC = new EmptyVertex(2);
80 vC.addAP();
81 vC.addAP();
82 vA.addAP();
83 EmptyVertex vRcvA = new EmptyVertex(3);
84 vRcvA.addAP();
85 vRcvA.setAsRCV(true);
86 EmptyVertex vRcvC = new EmptyVertex(4);
87 vRcvC.addAP();
88 vRcvC.setAsRCV(true);
89
90 DGraph g = new DGraph();
91 g.addVertex(vA);
92 g.appendVertexOnAP(vA.getAP(0), vB.getAP(1));
93 g.appendVertexOnAP(vB.getAP(0), vC.getAP(1));
94 g.appendVertexOnAP(vA.getAP(1), vRcvA.getAP(0));
95 g.appendVertexOnAP(vC.getAP(0), vRcvC.getAP(0));
96
97 Ring r = new Ring(new ArrayList<Vertex>(
98 Arrays.asList(vRcvA, vA, vB, vC, vRcvC)));
99 g.addRing(r);
100
101 Template t = new Template(BBType.NONE);
102 //TODO-v3 add required APs and check they are cloned properly
103 t.setInnerGraph(g);
104 t.freezeTemplate();
105 t.setProperty("PROPNAME","PROVALUE");
106
107 Template c = t.clone();
108
109 assertEquals(t.getFreeAPCount(),c.getFreeAPCount(),
110 "Different #free APs");
111 assertEquals("PROVALUE",c.getProperty("PROPNAME"));
112 for (int i=0; i<t.getFreeAPCount(); i++)
113 {
114 AttachmentPoint oriAP = t.getAP(i);
115 AttachmentPoint cloAP = c.getAP(i);
116 assertTrue(oriAP.hashCode() != cloAP.hashCode(), "Hashcode of APs");
117 assertTrue(oriAP.getAPClass() == cloAP.getAPClass(), "APClass");
118 assertTrue(oriAP.getAtomPositionNumber()
119 == cloAP.getAtomPositionNumber(), "AP AtomSource");
120 }
121
122 DGraph oriIG = t.getInnerGraph();
123 DGraph cloIG = c.getInnerGraph();
124 assertTrue(oriIG.hashCode() != cloIG.hashCode(),
125 "InnerGraph graph hash");
126 assertEquals(oriIG.getVertexCount(),
127 cloIG.getVertexCount(),"InnerGraph vertex count");
128 for (int i=0; i<oriIG.getVertexCount(); i++)
129 {
130 Vertex ov = oriIG.getVertexAtPosition(i);
131 Vertex cv = cloIG.getVertexAtPosition(i);
132 assertTrue(ov.hashCode() != cv.hashCode(),"InnerGraph vertex hash");
133 }
134
135 assertEquals(oriIG.getRingCount(),
136 cloIG.getRingCount(),"InnerGraph ring count");
137 assertEquals(oriIG.getRings().get(0).getSize(),
138 cloIG.getRings().get(0).getSize(),"InnerGraph ring count");
139 }
140
141//------------------------------------------------------------------------------
142
143 @Test
145 try {
147 Template clone = t.clone();
148 assertTrue(t.sameAs(clone, new StringBuilder()));
149 } catch (DENOPTIMException e) {
150 fail("Unexpected exception thrown.");
151
152 }
153 }
154
155//------------------------------------------------------------------------------
156
169 /* Constructing innermost template */
170 Vertex ohFrag = getOHFragment();
171 DGraph g = new DGraph();
172 g.addVertex(ohFrag);
173 Template nestedTemp = new Template(BBType.FRAGMENT);
174 nestedTemp.setInnerGraph(g);
175
176 /* Constructing outermost template */
177 Vertex ch2Frag = getCH2Fragment();
178 g = new DGraph();
179 g.addVertex(ch2Frag);
180 g.appendVertexOnAP(ch2Frag.getAP(0), nestedTemp.getAP(0));
181
182 Template outerTemp = new Template(BBType.FRAGMENT);
183 outerTemp.setInnerGraph(g);
184
185 return outerTemp;
186 }
187
188//------------------------------------------------------------------------------
189
196 private static Vertex getCH2Fragment() throws DENOPTIMException
197 {
198 IAtomContainer atomContainer = chemBuilder.newAtomContainer();
199 String[] elements = new String[]{"C", "H", "H"};
200 Point3d[] atmCoords = new Point3d[]{
201 new Point3d(0.0, 0.0, 0.0),
202 new Point3d(0.0000, -0.8900, -0.6293),
203 new Point3d(0.0000, 0.8900, -0.6293),
204 };
205 for (int i=0; i<elements.length; i++) {
206 IAtom atom = chemBuilder.newAtom();
207 atom.setSymbol(elements[i]);
208 atom.setPoint3d(atmCoords[i]);
209 atomContainer.addAtom(atom);
210 }
211 atomContainer.addBond(0, 1, IBond.Order.SINGLE);
212 atomContainer.addBond(0, 2, IBond.Order.SINGLE);
213
214 Fragment v = new Fragment(
216 atomContainer,
218
219 Point3d[] apCoords = new Point3d[]{
220 new Point3d(-0.8900, 0.0000, 0.6293),
221 new Point3d(0.8900, 0.0000, 0.6293),
222 };
223 for (int i = 0; i < 2; i++) {
224 APClass apClass = APClass.make("c", 0);
225 v.addAP(0, apClass, apCoords[i]);
226 }
227 return v;
228 }
229
230//------------------------------------------------------------------------------
231
239 {
240 IAtomContainer atomContainer = chemBuilder.newAtomContainer();
241 String[] elements = new String[]{"C", "O", "N"};
242 Point3d[] atmCoords = new Point3d[]{
243 new Point3d(0.6748, -0.1898, -0.0043),
244 new Point3d(1.0460, -1.3431, -0.0581),
245 new Point3d(-0.6427, 0.0945, -0.0002),
246 };
247 for (int i=0; i<elements.length; i++) {
248 IAtom atom = chemBuilder.newAtom();
249 atom.setSymbol(elements[i]);
250 atom.setPoint3d(atmCoords[i]);
251 atomContainer.addAtom(atom);
252 }
253 atomContainer.addBond(0, 1, IBond.Order.DOUBLE);
254 atomContainer.addBond(0, 2, IBond.Order.SINGLE);
255
256 Fragment v = new Fragment(
258 atomContainer,
260
261 Point3d[] apCoords = new Point3d[]{
262 new Point3d(1.6864, 0.9254, 0.0580),
263 new Point3d(-1.6259, -0.9902, 0.0560),
264 new Point3d(-1.0915, 1.4881, -0.0518),
265 };
266 int[] srcAtm = new int[] {0, 2, 2};
267 APClass[] apClass = new APClass[] {
268 APClass.make("Camide", 0),
269 APClass.make("NAmide", 0),
270 APClass.make("NAmide", 0)};
271 for (int i = 0; i < 3; i++) {
272 v.addAP(srcAtm[i], apClass[i],apCoords[i]);
273 }
274 return v;
275 }
276
277//------------------------------------------------------------------------------
278
284 IAtomContainer atomContainer = chemBuilder.newAtomContainer();
285 String[] elements = new String[]{"O", "H"};
286 for (String e : elements) {
287 IAtom atom = chemBuilder.newAtom();
288 atom.setSymbol(e);
289 atomContainer.addAtom(atom);
290 }
291
292 atomContainer.addBond(0, 1, IBond.Order.SINGLE);
293
294 Fragment v = new Fragment(
296 atomContainer,
298 double precision = 10*10*10*10;
299 APClass apClass = APClass.make("o", 0);
300 v.addAP(
301 0,
302 apClass,
303 new Point3d(
304 (double) (Math.round(rng.nextDouble() * precision)) / precision,
305 (double) (Math.round(rng.nextDouble() * precision)) / precision,
306 (double) (Math.round(rng.nextDouble() * precision)) / precision)
307 );
308 return v;
309 }
310
311//------------------------------------------------------------------------------
312
313 @Test
315 throws DENOPTIMException
316 {
317 Template template = new Template(BBType.NONE);
318 EmptyVertex v = new EmptyVertex();
319 v.addAP();
320 DGraph innerGraph = new DGraph();
321 innerGraph.addVertex(v);
322 template.setInnerGraph(innerGraph);
323
324 int totalAPCount = 1;
325 for (int i = 0; i < totalAPCount; i++) {
326 Vertex actualOwner = template.getAttachmentPoints().get(i)
327 .getOwner();
328 assertSame(template, actualOwner);
329 }
330 }
331
332//------------------------------------------------------------------------------
333
334 @Test
336 throws DENOPTIMException
337 {
338 Template template =
339 new Template(BBType.NONE);
340 int requiredAPCount = 2;
341 EmptyVertex v1 = new EmptyVertex();
342 EmptyVertex v2 = new EmptyVertex();
343 int v1APCount = 3;
344 int v2APCount = 2;
345 for (int i = 0; i < requiredAPCount; i++) {
346 template.addRequiredAP(null, null);
347 }
348 for (int i = 0; i < v1APCount; i++) {
349 v1.addAP();
350 }
351 for (int i = 0; i < v2APCount; i++) {
352 v2.addAP();
353 }
354 DGraph innerGraph = new DGraph();
355 innerGraph.addVertex(v1);
356 innerGraph.appendVertexOnAP(v1.getAP(0), v2.getAP(0));
357 template.setInnerGraph(innerGraph);
358
359// System.err.println(innerGraph.getAvailableAPs().toString());
360
361 // -2 since 2 APs are used to connect v1 and v2.
362 int expectedAPCount = v1APCount + v2APCount - 2;
363 int actualAPCount = template.getAttachmentPoints().size();
364 assertEquals(expectedAPCount, actualAPCount);
365 }
366
367//------------------------------------------------------------------------------
368
369 @Test
371 throws DENOPTIMException {
372 int numberOfAPs = 2;
373 List<Point3d> dirVecs = Arrays.asList(
374 new Point3d(1.0, -2.1,3.2),
375 new Point3d(-2.0, 1.1, -3.2)
376 );
377 List<APClass> APClasses = Arrays.asList(
378 APClass.make("rule1", 0),
379 APClass.make("rule2", 1)
380 );
381
382 Template template =
383 new Template(BBType.NONE);
384 EmptyVertex v = new EmptyVertex();
385 for (int i = 0; i < numberOfAPs; i++) {
386 template.addRequiredAP(dirVecs.get(i),
387 APClasses.get(i));
388 v.addAP(APClasses.get(i));
389 }
390 DGraph innerGraph = new DGraph();
391 innerGraph.addVertex(v);
392
393 testAtLeastSameNumberOfAPs(template, numberOfAPs);
394 testSameAPClass(template, innerGraph);
395 }
396
397//------------------------------------------------------------------------------
398
399 private void testSameAPClass(Template t, DGraph innerGraph)
400 {
401 AttachmentPoint ap = innerGraph.getVertexAtPosition(0).getAP(1);
402 try {
403 ap.setAPClass(
404 innerGraph.getVertexAtPosition(0).getAP(0).getAPClass());
405 assertThrows(IllegalArgumentException.class,
406 () -> t.setInnerGraph(innerGraph));
407 } catch (Exception e) {
408 fail("Expected " + IllegalArgumentException.class + ", but was "
409 + e.getClass());
410 }
411 }
412
413//------------------------------------------------------------------------------
414
416 int expNumberOfAPs) throws DENOPTIMException
417 {
418 EmptyVertex v = new EmptyVertex();
419 for (int i = 0; i < expNumberOfAPs - 1; i++) {
420 v.addAP();
421 }
422 DGraph innerGraph = new DGraph();
423 innerGraph.addVertex(v);
424 assertThrows(IllegalArgumentException.class,
425 () -> t.setInnerGraph(innerGraph));
426 }
427
428//------------------------------------------------------------------------------
429
430 @Test
432 Template t = new Template(BBType.NONE);
433 DGraph g = new DGraph();
434 t.setInnerGraph(g);
435 assertThrows(IllegalArgumentException.class, () -> t.addRequiredAP(
436 new Point3d(0,0,0), APClass.make("dummy:0")));
437 }
438
439//------------------------------------------------------------------------------
440
457 {
458 Vertex v1 = getCH2Fragment();
459 Vertex v2 = getCH2Fragment();
460 Vertex v3 = getCH2Fragment();
461 Vertex v4 = getCH2Fragment();
463
464 DGraph g = new DGraph();
465 g.addVertex(v1);
466 g.appendVertexOnAP(v1.getAP(0), v5.getAP(0));
467 g.appendVertexOnAP(v1.getAP(1), v2.getAP(1));
468 g.appendVertexOnAP(v2.getAP(0), v3.getAP(1));
469 g.appendVertexOnAP(v3.getAP(0), v4.getAP(0));
470
472 t.setInnerGraph(g);
473
474 return t;
475 }
476
477//------------------------------------------------------------------------------
478
479 @Test
480 public void testGetIAtomContainer() throws Exception
481 {
483
484 IAtomContainer mol = t.getIAtomContainer();
485
486 String[] elements = new String[]{"C", "H", "N", "O"};
487 int[] expected = new int[]{5, 8, 1, 1};
488 for (int i=0; i<elements.length; i++)
489 {
490 assertEquals(expected[i],
491 MoleculeUtils.countAtomsOfElement(mol, elements[i]),
492 "Number of '" + elements[i] + "'.");
493 }
494
495 String refGeometry = NL +
496 " CDK 04132117333D" + NL +
497 NL +
498 " 15 14 0 0 0 0 0 0 0 0999 V2000" + NL +
499 " 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
500 " 0.0000 -0.8900 -0.6293 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
501 " 0.0000 0.8900 -0.6293 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
502 " -1.0602 0.0000 0.7497 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
503 " -1.4136 -1.0211 1.3004 O 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
504 " -1.7681 1.1349 0.9158 N 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
505 " 0.8900 0.0000 0.6293 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
506 " 0.8900 -0.8900 1.2586 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
507 " 0.8900 0.8900 1.2586 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
508 " 1.7800 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
509 " 2.3733 -0.8900 0.2098 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
510 " 2.3733 0.8900 0.2098 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
511 " 1.4834 0.0000 -1.0489 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
512 " 0.8901 -0.8900 -1.2587 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
513 " 0.8901 0.8900 -1.2587 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
514 " 1 2 1 0 0 0 0" + NL +
515 " 1 3 1 0 0 0 0" + NL +
516 " 4 5 2 0 0 0 0" + NL +
517 " 4 6 1 0 0 0 0" + NL +
518 " 1 4 1 0 0 0 0" + NL +
519 " 7 8 1 0 0 0 0" + NL +
520 " 7 9 1 0 0 0 0" + NL +
521 " 1 7 1 0 0 0 0" + NL +
522 " 10 11 1 0 0 0 0" + NL +
523 " 10 12 1 0 0 0 0" + NL +
524 " 7 10 1 0 0 0 0" + NL +
525 " 13 14 1 0 0 0 0" + NL +
526 " 13 15 1 0 0 0 0" + NL +
527 " 10 13 1 0 0 0 0" + NL +
528 "M END" + NL;
529
530 assertTrue(this.tempDir.isDirectory(),"Should be a directory ");
531 String fileName = tempDir.getAbsolutePath() + SEP + "refMol.sdf";
532 DenoptimIO.writeData(fileName, refGeometry, false);
533
534 IAtomContainer refMol = DenoptimIO.readSDFFile(fileName).get(0);
535
536 KabschAlignment sa = null;
537 try {
538 sa = new KabschAlignment(refMol,mol);
539 sa.align();
540 } catch (CDKException e){
541 e.printStackTrace();
542 fail("KabschAlignment failed: "+e.getMessage());
543 }
544 assertTrue(sa.getRMSD()<0.0001,"RMSD between generated and expected "
545 + "geometry");
546
547 // This check is done ignoring AP order
548 Point3d[] expectedAPHeads = new Point3d[] {
549 new Point3d(-2.8954,1.1648,1.8510),
550 new Point3d(-1.4101,2.3385,0.1613),
551 new Point3d(2.3734,0.0000,-1.6782)};
553 {
554 Point3d apHead = new Point3d(ap.getDirectionVector());
555 boolean found = false;
556 double[] dists = new double[3];
557 for (int i=0; i<expectedAPHeads.length; i++)
558 {
559 Point3d expectedAPHead = expectedAPHeads[i];
560 double dist = apHead.distance(expectedAPHead);
561 dists[i] = dist;
562 if (dist<0.001)
563 {
564 found = true;
565 break;
566 }
567 }
568 assertTrue(found,"Inconsistent placement of outer AP (errors: "
569 + dists[0] + ", " + dists[1] + ", " + dists[2] + "). "
570 + "AP: "+ap);
571 }
572 }
573
574//------------------------------------------------------------------------------
575
577 {
578 Template v1 = null;
579 for (int i =0; i<10; i++)
580 {
581 if (v1 == null)
582 {
584 }
585 Vertex v2 = getCH2Fragment();
586 v2.setVertexId(100+i);
587 DGraph g = new DGraph();
588 g.addVertex(v1);
589 g.appendVertexOnAP(v1.getAP(0), v2.getAP(0));
591 t.setInnerGraph(g);
592 v1 = t;
593 }
594 return v1;
595 }
596
597//------------------------------------------------------------------------------
598
599 @Test
600 public void testGetIAtomContainer_DeepVertex() throws Exception
601 {
603
604 IAtomContainer mol = t.getIAtomContainer();
605
606 String[] elements = new String[]{"C", "H", "N", "O"};
607 int[] expected = new int[]{15, 28, 1, 1};
608 for (int i=0; i<elements.length; i++)
609 {
610 assertEquals(expected[i],
611 MoleculeUtils.countAtomsOfElement(mol, elements[i]),
612 "Number of '" + elements[i] + "'.");
613 }
614
615 String refGeometry = NL +
616 " CDK 02222322323D" + NL +
617 NL +
618 " 45 44 0 0 0 0 0 0 0 0999 V2000" + NL +
619 " 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
620 " 0.0000 -0.8900 -0.6293 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
621 " 0.0000 0.8900 -0.6293 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
622 " -1.0602 0.0000 0.7497 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
623 " -1.4136 -1.0211 1.3004 O 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
624 " -1.7681 1.1349 0.9158 N 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
625 " 0.8900 0.0000 0.6293 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
626 " 0.8900 -0.8900 1.2586 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
627 " 0.8900 0.8900 1.2586 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
628 " 1.7800 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
629 " 2.3733 -0.8900 0.2098 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
630 " 2.3733 0.8900 0.2098 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
631 " 1.4834 0.0000 -1.0489 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
632 " 0.8901 -0.8900 -1.2587 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
633 " 0.8901 0.8900 -1.2587 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
634 " -2.7511 1.1609 1.7313 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
635 " -2.4728 0.6487 2.6523 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
636 " -3.0101 2.1958 1.9552 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
637 " -1.4559 2.1845 0.2578 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
638 " -1.2473 1.9156 -0.7777 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
639 " -2.2838 2.8928 0.2896 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
640 " 2.3734 0.0000 -1.6782 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
641 " 2.3734 -0.8900 -2.3075 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
642 " 2.3734 0.8900 -2.3075 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
643 " -3.6091 0.6606 1.2823 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
644 " -4.2319 0.2324 2.0677 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
645 " -4.1916 1.3822 0.7094 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
646 " -0.5703 2.6407 0.7002 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
647 " 0.3217 2.1322 0.3340 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
648 " -0.5275 3.6941 0.4234 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
649 " 3.2634 0.0000 -1.0489 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
650 " 3.8567 -0.8900 -1.2587 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
651 " 3.8567 0.8900 -1.2587 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
652 " -3.2617 -0.1330 0.6208 C 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
653 " -4.0122 -0.9222 0.5749 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
654 " -3.0987 0.2719 -0.3780 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
655 " -0.6194 2.5519 1.7855 C 0 0 0 0 0 3 0 0 0 0 0 0" + NL +
656 " -0.2733 1.5626 2.0851 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
657 " 0.0148 3.3122 2.2413 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
658 " 2.9668 0.0000 0.0000 C 0 0 0 0 0 3 0 0 0 0 0 0" + NL +
659 " 3.3624 -0.8900 0.4894 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
660 " 3.3624 0.8900 0.4894 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
661 " -2.3270 -0.5423 1.0039 C 0 0 0 0 0 3 0 0 0 0 0 0" + NL +
662 " -2.2364 -1.5857 0.7018 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
663 " -1.4891 0.0267 0.6010 H 0 0 0 0 0 0 0 0 0 0 0 0" + NL +
664 " 1 2 1 0 0 0 0" + NL +
665 " 1 3 1 0 0 0 0" + NL +
666 " 4 5 2 0 0 0 0" + NL +
667 " 4 6 1 0 0 0 0" + NL +
668 " 1 4 1 0 0 0 0" + NL +
669 " 7 8 1 0 0 0 0" + NL +
670 " 7 9 1 0 0 0 0" + NL +
671 " 1 7 1 0 0 0 0" + NL +
672 " 10 11 1 0 0 0 0" + NL +
673 " 10 12 1 0 0 0 0" + NL +
674 " 7 10 1 0 0 0 0" + NL +
675 " 13 14 1 0 0 0 0" + NL +
676 " 13 15 1 0 0 0 0" + NL +
677 " 10 13 1 0 0 0 0" + NL +
678 " 16 17 1 0 0 0 0" + NL +
679 " 16 18 1 0 0 0 0" + NL +
680 " 6 16 1 0 0 0 0" + NL +
681 " 19 20 1 0 0 0 0" + NL +
682 " 19 21 1 0 0 0 0" + NL +
683 " 6 19 1 0 0 0 0" + NL +
684 " 22 23 1 0 0 0 0" + NL +
685 " 22 24 1 0 0 0 0" + NL +
686 " 13 22 1 0 0 0 0" + NL +
687 " 25 26 1 0 0 0 0" + NL +
688 " 25 27 1 0 0 0 0" + NL +
689 " 16 25 1 0 0 0 0" + NL +
690 " 28 29 1 0 0 0 0" + NL +
691 " 28 30 1 0 0 0 0" + NL +
692 " 19 28 1 0 0 0 0" + NL +
693 " 31 32 1 0 0 0 0" + NL +
694 " 31 33 1 0 0 0 0" + NL +
695 " 22 31 1 0 0 0 0" + NL +
696 " 34 35 1 0 0 0 0" + NL +
697 " 34 36 1 0 0 0 0" + NL +
698 " 25 34 1 0 0 0 0" + NL +
699 " 37 38 1 0 0 0 0" + NL +
700 " 37 39 1 0 0 0 0" + NL +
701 " 28 37 1 0 0 0 0" + NL +
702 " 40 41 1 0 0 0 0" + NL +
703 " 40 42 1 0 0 0 0" + NL +
704 " 31 40 1 0 0 0 0" + NL +
705 " 43 44 1 0 0 0 0" + NL +
706 " 43 45 1 0 0 0 0" + NL +
707 " 34 43 1 0 0 0 0" + NL +
708 "M END";
709
710 assertTrue(this.tempDir.isDirectory(),"Should be a directory ");
711 String fileName = tempDir.getAbsolutePath() + SEP + "refMol.sdf";
712 DenoptimIO.writeData(fileName, refGeometry, false);
713
714 IAtomContainer refMol = DenoptimIO.readSDFFile(fileName).get(0);
715
716 KabschAlignment sa = null;
717 try {
718 sa = new KabschAlignment(refMol, mol);
719 sa.align();
720 } catch (CDKException e){
721 e.printStackTrace();
722 fail("KabschAlignment failed: "+e.getMessage());
723 }
724 assertTrue(sa.getRMSD()<0.0001,"RMSD between generated and expected "
725 + "geometry");
726
727 // This check is done ignoring AP order
728 Point3d[] expectedAPHeads = new Point3d[] {
729 new Point3d(-1.6488,2.6919,2.1153),
730 new Point3d(1.8790, 0.0, 0.0700),
731 new Point3d(-2.3207,-0.4772,2.0919)};
733 {
734 Point3d apHead = new Point3d(ap.getDirectionVector());
735 boolean found = false;
736 double[] dists = new double[3];
737 for (int i=0; i<expectedAPHeads.length; i++)
738 {
739 Point3d expectedAPHead = expectedAPHeads[i];
740 double dist = apHead.distance(expectedAPHead);
741 dists[i] = dist;
742 if (dist<0.001)
743 {
744 found = true;
745 break;
746 }
747 }
748 assertTrue(found,"Inconsistent placement of outer AP (errors: "
749 + dists[0] + ", " + dists[1] + ", " + dists[2] + "). "
750 + "AP: "+ap);
751 }
752 }
753}
static APClass make(String ruleAndSubclass)
Creates an APClass if it does not exist already, or returns the reference to the existing instance.
Definition: APClass.java:136
An attachment point (AP) is a possibility to attach a Vertex onto the vertex holding the AP (i....
void setAPClass(String apClass)
Set the Attachment Point class.
APClass getAPClass()
Returns the Attachment Point class.
int getAtomPositionNumber()
The index of the source atom in the atom list of the fragment.
Container for the list of vertices and the edges that connect them.
Definition: DGraph.java:102
void addVertex(Vertex vertex)
Appends a vertex to this graph without creating any edge.
Definition: DGraph.java:1097
Vertex getVertexAtPosition(int pos)
Returns the vertex that is in the given position of the list of vertices belonging to this graph.
Definition: DGraph.java:2514
void appendVertexOnAP(AttachmentPoint srcAP, AttachmentPoint trgAP)
Append a vertex to this graph: adds the new vertex to the list of vertices belonging to the graph,...
Definition: DGraph.java:5776
List< Ring > getRings()
Definition: DGraph.java:771
void addRing(Ring ring)
Definition: DGraph.java:1030
An empty vertex has the behaviors of a vertex, but has no molecular structure.
void addAP()
Adds an attachment point with no APClass or other attribute.
Class representing a continuously connected portion of chemical object holding attachment points.
Definition: Fragment.java:61
void addAP(int atomPositionNumber)
Adds an attachment point with a dummy APClass.
Definition: Fragment.java:343
This class represents the closure of a ring in a spanning tree.
Definition: Ring.java:40
void setInnerGraph(DGraph innerGraph)
Definition: Template.java:298
boolean sameAs(Template other, StringBuilder reason)
Compares this and another template ignoring vertex IDs.
Definition: Template.java:956
boolean freezeTemplate()
Promotes the contract level of this template to the most constrained one (i.e., ContractLevel#FIXED),...
Definition: Template.java:231
ArrayList< AttachmentPoint > getAttachmentPoints()
Return the list of attachment points visible from outside the template, i.e., the so-called outer APs...
Definition: Template.java:458
void addRequiredAP(Point3d pt, APClass apClass)
Adds attachment point (AP) to the list of required APs on this template.
Definition: Template.java:935
IAtomContainer getIAtomContainer()
The molecular representation, if any, is generated by this method and stored until further changes in...
Definition: Template.java:715
Template clone()
Returns a deep copy of this template.
Definition: Template.java:243
Unit test for DENOPTIMTemplate.
void testGetAttachmentPoints_returnsAPsWithTemplateAsOwner()
static Template getTestAmideTemplate()
Builds a template object meant for tests.
void testAddAP_after_setInnerGraph_throwsException()
static Vertex getAmideFragment()
The coordinates hard coded in this method must not be changed because they are needed to reproduce re...
void testSetInnerGraph_throws_on_graph_incompatible_w_requiredAPs()
void testSameAPClass(Template t, DGraph innerGraph)
static IChemObjectBuilder chemBuilder
void testGetAttachmentPoints_returnsCorrectNumberOfAPs()
void testAtLeastSameNumberOfAPs(Template t, int expNumberOfAPs)
Template getNestedTemplate()
Creating a template that contains another template with the following structure: |-------------------...
static Vertex getCH2Fragment()
The coordinates hard coded in this method must not be changed because they are needed to reproduce re...
A vertex is a data structure that has an identity and holds a list of AttachmentPoints.
Definition: Vertex.java:61
void setVertexId(long vertexId2)
Definition: Vertex.java:261
void setAsRCV(boolean isRCV)
Definition: Vertex.java:254
abstract List< AttachmentPoint > getAttachmentPoints()
Object getProperty(Object property)
Definition: Vertex.java:1136
void setProperty(Object key, Object property)
Definition: Vertex.java:1148
AttachmentPoint getAP(int i)
Get attachment point i on this vertex.
Definition: Vertex.java:920
Utility methods for input/output.
static ArrayList< IAtomContainer > readSDFFile(String fileName)
Reads a file containing multiple molecules (multiple SD format))
static void writeData(String fileName, String data, boolean append)
Write text-like data file.
Utilities for graphs.
Definition: GraphUtils.java:40
static synchronized long getUniqueVertexIndex()
Unique counter for the number of graph vertices generated.
Definition: GraphUtils.java:97
Utilities for molecule conversion.
static int countAtomsOfElement(IAtomContainer mol, String symbol)
Count atoms with the given elemental symbol.
The type of building block.
Definition: Vertex.java:86