21import static denoptim.utils.MoleculeUtils.getPoint3d;
22import static org.junit.jupiter.api.Assertions.assertEquals;
23import static org.junit.jupiter.api.Assertions.assertFalse;
24import static org.junit.jupiter.api.Assertions.assertNotNull;
25import static org.junit.jupiter.api.Assertions.assertTrue;
27import java.util.HashMap;
28import java.util.HashSet;
32import java.util.logging.Logger;
34import javax.vecmath.Point2d;
35import javax.vecmath.Point3d;
37import org.junit.jupiter.api.Test;
38import org.openscience.cdk.Atom;
39import org.openscience.cdk.Bond;
40import org.openscience.cdk.interfaces.IAtom;
41import org.openscience.cdk.interfaces.IAtomContainer;
42import org.openscience.cdk.interfaces.IBond;
43import org.openscience.cdk.interfaces.IChemObjectBuilder;
44import org.openscience.cdk.silent.SilentChemObjectBuilder;
54 private IChemObjectBuilder
builder = SilentChemObjectBuilder.getInstance();
66 a.setPoint2d(
new Point2d(2.6, -4.2));
71 a.setPoint3d(
new Point3d(2.6, -4.2, 6.4));
83 double delta = 0.0000001;
84 return Math.abs(a-b) <= delta;
92 IAtomContainer mol =
builder.newAtomContainer();
93 mol.addAtom(
new Atom(
"H",
new Point3d(1.2,-2.9,2.5)));
94 mol.addAtom(
new Atom(
"H",
new Point3d(2.3,-4.8,4.2)));
95 mol.addAtom(
new Atom(
"H",
new Point3d(4.5,2.6,-5.4)));
109 IAtomContainer
template =
builder.newAtomContainer();
110 IAtom o1 =
new Atom(
"O",
new Point3d(0.0, 0.0, 0.0));
111 IAtom h1 =
new Atom(
"H",
new Point3d(1.0, 0.0, 0.0));
112 IAtom h2 =
new Atom(
"H",
new Point3d(0.0, 1.0, 0.0));
113 template.addAtom(o1);
114 template.addAtom(h1);
115 template.addAtom(h2);
116 template.addBond(
new Bond(o1, h1));
117 template.addBond(
new Bond(o1, h2));
120 IAtomContainer mol =
builder.newAtomContainer();
121 IAtom o2 =
new Atom(
"O",
new Point3d(0.0, 0.0, 0.0));
122 IAtom h3 =
new Atom(
"H",
new Point3d(1.0, 0.0, 0.0));
123 IAtom h4 =
new Atom(
"H",
new Point3d(0.1, 0.995, 0.0));
127 mol.addBond(
new Bond(o2, h3));
128 mol.addBond(
new Bond(o2, h4));
131 Map<IAtom, IAtom> mapping =
new HashMap<>();
141 assertTrue(score < 10.0,
"Bond angle agreement score should be small for similar structures");
142 assertTrue(score >= 0.0,
"Score should be non-negative");
145 IAtomContainer mol2 =
builder.newAtomContainer();
146 IAtom o3 =
new Atom(
"O",
new Point3d(0.0, 0.0, 0.0));
147 IAtom h5 =
new Atom(
"H",
new Point3d(1.0, 0.0, 0.0));
148 IAtom h6 =
new Atom(
"H",
new Point3d(0.0, 1.0, 0.0));
152 mol2.addBond(
new Bond(o3, h5));
153 mol2.addBond(
new Bond(o3, h6));
155 Map<IAtom, IAtom> mapping2 =
new HashMap<>();
156 mapping2.put(o1, o3);
157 mapping2.put(h1, h5);
158 mapping2.put(h2, h6);
162 assertTrue(score2 < 0.1,
"Identical structures should have very low score");
165 Map<IAtom, IAtom> incompleteMapping =
new HashMap<>();
166 incompleteMapping.put(o1, o2);
171 assertEquals(Double.MAX_VALUE, score3,
"Incomplete mapping should return MAX_VALUE, but got " + score3);
176 IAtomContainer ch4Template =
builder.newAtomContainer();
177 IAtom cTemplate =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
179 double sqrt3 = Math.sqrt(1.0/3.0);
180 IAtom h1Template =
new Atom(
"H",
new Point3d(sqrt3, sqrt3, sqrt3));
181 IAtom h2Template =
new Atom(
"H",
new Point3d(sqrt3, -sqrt3, -sqrt3));
182 IAtom h3Template =
new Atom(
"H",
new Point3d(-sqrt3, sqrt3, -sqrt3));
183 IAtom h4Template =
new Atom(
"H",
new Point3d(-sqrt3, -sqrt3, sqrt3));
184 ch4Template.addAtom(cTemplate);
185 ch4Template.addAtom(h1Template);
186 ch4Template.addAtom(h2Template);
187 ch4Template.addAtom(h3Template);
188 ch4Template.addAtom(h4Template);
189 ch4Template.addBond(
new Bond(cTemplate, h1Template));
190 ch4Template.addBond(
new Bond(cTemplate, h2Template));
191 ch4Template.addBond(
new Bond(cTemplate, h3Template));
192 ch4Template.addBond(
new Bond(cTemplate, h4Template));
195 IAtomContainer ch4Target =
builder.newAtomContainer();
196 IAtom cTarget =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
197 IAtom h1Target =
new Atom(
"H",
new Point3d(sqrt3, sqrt3, sqrt3));
198 IAtom h2Target =
new Atom(
"H",
new Point3d(sqrt3, -sqrt3, -sqrt3));
199 IAtom h3Target =
new Atom(
"H",
new Point3d(-sqrt3, sqrt3, -sqrt3));
200 IAtom h4Target =
new Atom(
"H",
new Point3d(-sqrt3, -sqrt3, sqrt3));
201 ch4Target.addAtom(cTarget);
202 ch4Target.addAtom(h1Target);
203 ch4Target.addAtom(h2Target);
204 ch4Target.addAtom(h3Target);
205 ch4Target.addAtom(h4Target);
206 ch4Target.addBond(
new Bond(cTarget, h1Target));
207 ch4Target.addBond(
new Bond(cTarget, h2Target));
208 ch4Target.addBond(
new Bond(cTarget, h3Target));
209 ch4Target.addBond(
new Bond(cTarget, h4Target));
212 Map<IAtom, IAtom> correctMapping =
new HashMap<>();
213 correctMapping.put(cTemplate, cTarget);
214 correctMapping.put(h1Template, h1Target);
215 correctMapping.put(h2Template, h2Target);
216 correctMapping.put(h3Template, h3Target);
217 correctMapping.put(h4Template, h4Target);
221 assertTrue(identicalMappingScore < 0.1,
"Correct mapping should have very low score: " + identicalMappingScore);
224 Map<IAtom, IAtom> swappedMapping =
new HashMap<>();
225 swappedMapping.put(cTemplate, cTarget);
226 swappedMapping.put(h1Template, h2Target);
227 swappedMapping.put(h2Template, h1Target);
228 swappedMapping.put(h3Template, h3Target);
229 swappedMapping.put(h4Template, h4Target);
234 assertTrue(swappedScore > identicalMappingScore,
235 "Swapped mapping should give higher score than identical mapping (> "
236 + identicalMappingScore +
"): " + swappedScore);
244 Logger logger = Logger.getLogger(
"TestLogger");
247 IAtomContainer substructure =
builder.newAtomContainer();
248 IAtom c1 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
249 IAtom c2 =
new Atom(
"C",
new Point3d(1.5, 0.0, 0.0));
250 substructure.addAtom(c1);
251 substructure.addAtom(c2);
252 substructure.addBond(
new Bond(c1, c2));
255 IAtomContainer mol =
builder.newAtomContainer();
256 IAtom h1 =
new Atom(
"H",
new Point3d(-1.0, 0.0, 0.0));
257 IAtom c3 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
258 IAtom c4 =
new Atom(
"C",
new Point3d(1.5, 0.0, 0.0));
259 IAtom c5 =
new Atom(
"C",
new Point3d(3.0, 0.0, 0.0));
260 IAtom h2 =
new Atom(
"H",
new Point3d(4.0, 0.0, 0.0));
266 mol.addBond(
new Bond(h1, c3));
267 mol.addBond(
new Bond(c3, c4));
268 mol.addBond(
new Bond(c4, c5));
269 mol.addBond(
new Bond(c5, h2));
275 assertNotNull(mapping,
"Mapping should not be null");
276 assertEquals(2, mapping.size(),
"Mapping should contain 2 atoms");
277 assertTrue(mapping.containsKey(c1),
"Mapping should contain first carbon");
278 assertTrue(mapping.containsKey(c2),
"Mapping should contain second carbon");
281 IAtom mappedC1 = mapping.get(c1);
282 IAtom mappedC2 = mapping.get(c2);
283 assertNotNull(mappedC1,
"Mapped atom should not be null");
284 assertNotNull(mappedC2,
"Mapped atom should not be null");
285 assertEquals(
"C", mappedC1.getSymbol(),
"Mapped atom should be carbon");
286 assertEquals(
"C", mappedC2.getSymbol(),
"Mapped atom should be carbon");
289 IBond bond = mol.getBond(mappedC1, mappedC2);
290 assertNotNull(bond,
"Mapped atoms should be bonded");
298 Logger logger = Logger.getLogger(
"TestLogger");
302 IAtomContainer chiralTemplate =
builder.newAtomContainer();
303 IAtom cTemplate =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
305 double sqrt3 = Math.sqrt(1.0/3.0);
306 IAtom hTemplate =
new Atom(
"H",
new Point3d(sqrt3, sqrt3, sqrt3));
307 IAtom fTemplate =
new Atom(
"F",
new Point3d(sqrt3, -sqrt3, -sqrt3));
308 IAtom cl1Template =
new Atom(
"Cl",
new Point3d(-sqrt3, sqrt3, -sqrt3));
309 IAtom cl2Template =
new Atom(
"Cl",
new Point3d(-sqrt3, -sqrt3, sqrt3));
310 chiralTemplate.addAtom(cTemplate);
311 chiralTemplate.addAtom(hTemplate);
312 chiralTemplate.addAtom(fTemplate);
313 chiralTemplate.addAtom(cl1Template);
314 chiralTemplate.addAtom(cl2Template);
315 chiralTemplate.addBond(
new Bond(cTemplate, hTemplate));
316 chiralTemplate.addBond(
new Bond(cTemplate, fTemplate));
317 chiralTemplate.addBond(
new Bond(cTemplate, cl1Template));
318 chiralTemplate.addBond(
new Bond(cTemplate, cl2Template));
321 IAtomContainer chiralTarget =
builder.newAtomContainer();
322 IAtom cTarget =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
323 IAtom hTarget =
new Atom(
"H",
new Point3d(sqrt3, sqrt3, sqrt3));
324 IAtom fTarget =
new Atom(
"F",
new Point3d(sqrt3, -sqrt3, -sqrt3));
325 IAtom cl1Target =
new Atom(
"Cl",
new Point3d(-sqrt3, sqrt3, -sqrt3));
326 IAtom cl2Target =
new Atom(
"Cl",
new Point3d(-sqrt3, -sqrt3, sqrt3));
327 chiralTarget.addAtom(cTarget);
328 chiralTarget.addAtom(hTarget);
329 chiralTarget.addAtom(fTarget);
330 chiralTarget.addAtom(cl1Target);
331 chiralTarget.addAtom(cl2Target);
332 chiralTarget.addBond(
new Bond(cTarget, hTarget));
333 chiralTarget.addBond(
new Bond(cTarget, fTarget));
334 chiralTarget.addBond(
new Bond(cTarget, cl1Target));
335 chiralTarget.addBond(
new Bond(cTarget, cl2Target));
341 assertNotNull(mapping,
"Mapping should not be null");
342 assertEquals(5, mapping.size(),
"Mapping should contain all 5 atoms");
345 assertEquals(hTarget, mapping.get(hTemplate),
"H should map to H");
346 assertEquals(fTarget, mapping.get(fTemplate),
"F should map to F");
348 assertTrue(mapping.get(cl1Template).getSymbol().equals(
"Cl"),
"cl1Template should map to Cl");
349 assertTrue(mapping.get(cl2Template).getSymbol().equals(
"Cl"),
"cl2Template should map to Cl");
352 IAtomContainer enantiomerTarget =
builder.newAtomContainer();
353 IAtom cEnantiomer =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
354 IAtom hEnantiomer =
new Atom(
"H",
new Point3d(sqrt3, sqrt3, sqrt3));
355 IAtom fEnantiomer =
new Atom(
"F",
new Point3d(sqrt3, -sqrt3, -sqrt3));
357 IAtom cl1Enantiomer =
new Atom(
"Cl",
new Point3d(-sqrt3, -sqrt3, sqrt3));
358 IAtom cl2Enantiomer =
new Atom(
"Cl",
new Point3d(-sqrt3, sqrt3, -sqrt3));
359 enantiomerTarget.addAtom(cEnantiomer);
360 enantiomerTarget.addAtom(hEnantiomer);
361 enantiomerTarget.addAtom(fEnantiomer);
362 enantiomerTarget.addAtom(cl1Enantiomer);
363 enantiomerTarget.addAtom(cl2Enantiomer);
364 enantiomerTarget.addBond(
new Bond(cEnantiomer, hEnantiomer));
365 enantiomerTarget.addBond(
new Bond(cEnantiomer, fEnantiomer));
366 enantiomerTarget.addBond(
new Bond(cEnantiomer, cl1Enantiomer));
367 enantiomerTarget.addBond(
new Bond(cEnantiomer, cl2Enantiomer));
371 chiralTemplate, enantiomerTarget, logger);
374 assertNotNull(enantiomerMapping,
"Enantiomer mapping should not be null");
375 assertEquals(5, enantiomerMapping.size(),
"Enantiomer mapping should contain all 5 atoms");
378 assertEquals(hEnantiomer, enantiomerMapping.get(hTemplate),
"H should map to H");
379 assertEquals(fEnantiomer, enantiomerMapping.get(fTemplate),
"F should map to F");
381 assertEquals(cl1Enantiomer, enantiomerMapping.get(cl2Template),
382 "cl2Template should map to cl1Enantiomer (swapped due to opposite chirality)");
383 assertEquals(cl2Enantiomer, enantiomerMapping.get(cl1Template),
384 "cl1Template should map to cl2Enantiomer (swapped due to opposite chirality)");
387 Map<IAtom, IAtom> correctMapping =
new HashMap<>();
388 correctMapping.put(cTemplate, cTarget);
389 correctMapping.put(hTemplate, hTarget);
390 correctMapping.put(fTemplate, fTarget);
391 correctMapping.put(cl1Template, cl1Target);
392 correctMapping.put(cl2Template, cl2Target);
395 Map<IAtom, IAtom> swappedClMapping =
new HashMap<>();
396 swappedClMapping.put(cTemplate, cTarget);
397 swappedClMapping.put(hTemplate, hTarget);
398 swappedClMapping.put(fTemplate, fTarget);
399 swappedClMapping.put(cl1Template, cl2Target);
400 swappedClMapping.put(cl2Template, cl1Target);
403 Map<IAtom, IAtom> enantiomerMappingForScore =
new HashMap<>();
404 enantiomerMappingForScore.put(cTemplate, cEnantiomer);
405 enantiomerMappingForScore.put(hTemplate, hEnantiomer);
406 enantiomerMappingForScore.put(fTemplate, fEnantiomer);
407 enantiomerMappingForScore.put(cl1Template, cl1Enantiomer);
408 enantiomerMappingForScore.put(cl2Template, cl2Enantiomer);
411 chiralTemplate, chiralTarget, correctMapping);
414 chiralTemplate, chiralTarget, swappedClMapping);
417 chiralTemplate, enantiomerTarget, enantiomerMappingForScore);
421 assertTrue(swappedClScore > correctScore,
422 "Swapped Cl mapping should have higher score due to opposite chirality. " +
423 "Correct: " + correctScore +
", Swapped: " + swappedClScore);
426 assertTrue(enantiomerScore > correctScore,
427 "Enantiomer mapping should have higher score due to opposite chirality. " +
428 "Correct: " + correctScore +
", Enantiomer: " + enantiomerScore);
436 Logger logger = Logger.getLogger(
"TestLogger");
439 IAtomContainer substructure =
builder.newAtomContainer();
440 IAtom n1 =
new Atom(
"N",
new Point3d(0.0, 0.0, 0.0));
441 IAtom n2 =
new Atom(
"N",
new Point3d(1.5, 0.0, 0.0));
442 substructure.addAtom(n1);
443 substructure.addAtom(n2);
444 substructure.addBond(
new Bond(n1, n2));
447 IAtomContainer mol =
builder.newAtomContainer();
448 IAtom c1 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
449 IAtom c2 =
new Atom(
"C",
new Point3d(1.5, 0.0, 0.0));
452 mol.addBond(
new Bond(c1, c2));
457 assertNotNull(mapping,
"Mapping should not be null");
458 assertTrue(mapping.isEmpty(),
"Mapping should be empty when no match found");
466 Logger logger = Logger.getLogger(
"TestLogger");
469 IAtomContainer substructure =
builder.newAtomContainer();
470 IAtom c1 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
471 IAtom c2 =
new Atom(
"C",
new Point3d(1.5, 0.0, 0.0));
472 substructure.addAtom(c1);
473 substructure.addAtom(c2);
474 substructure.addBond(
new Bond(c1, c2));
478 IAtomContainer mol =
builder.newAtomContainer();
479 IAtom c3 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
480 IAtom c4 =
new Atom(
"C",
new Point3d(1.5, 0.0, 0.0));
481 IAtom c5 =
new Atom(
"C",
new Point3d(3.0, 0.0, 0.0));
482 IAtom c6 =
new Atom(
"C",
new Point3d(4.5, 0.0, 0.0));
487 mol.addBond(
new Bond(c3, c4));
488 mol.addBond(
new Bond(c4, c5));
489 mol.addBond(
new Bond(c5, c6));
494 assertNotNull(mapping,
"Mapping should not be null");
495 assertEquals(2, mapping.size(),
"Mapping should contain 2 atoms");
496 assertTrue(mapping.containsKey(c1),
"Mapping should contain first carbon");
497 assertTrue(mapping.containsKey(c2),
"Mapping should contain second carbon");
500 IAtom mappedC1 = mapping.get(c1);
501 IAtom mappedC2 = mapping.get(c2);
502 IBond bond = mol.getBond(mappedC1, mappedC2);
503 assertNotNull(bond,
"Mapped atoms should be bonded");
511 Logger logger = Logger.getLogger(
"TestLogger");
514 IAtomContainer substructure =
builder.newAtomContainer();
515 IAtom c1 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
516 IAtom c2 =
new Atom(
"C",
new Point3d(1.5, 0.0, 0.0));
517 substructure.addAtom(c1);
518 substructure.addAtom(c2);
519 substructure.addBond(
new Bond(c1, c2));
526 IAtomContainer mol =
builder.newAtomContainer();
527 IAtom c3 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
528 IAtom c4 =
new Atom(
"C",
new Point3d(1.5, 0.0, 0.0));
529 IAtom c5 =
new Atom(
"C",
new Point3d(3.0, 0.0, 0.0));
530 IAtom c6 =
new Atom(
"C",
new Point3d(4.5, 0.0, 0.0));
535 mol.addBond(
new Bond(c3, c4));
536 mol.addBond(
new Bond(c4, c5));
537 mol.addBond(
new Bond(c5, c6));
541 substructure, mol, logger);
544 assertNotNull(mappings,
"Mappings list should not be null");
545 assertTrue(mappings.size() > 1,
546 "Should find more than one mapping when substructure appears multiple times. " +
547 "Found: " + mappings.size());
550 for (Map<IAtom, IAtom> mapping : mappings)
552 assertEquals(2, mapping.size(),
553 "Each mapping should contain exactly 2 atoms");
554 assertTrue(mapping.containsKey(c1),
555 "Each mapping should contain the first carbon from substructure");
556 assertTrue(mapping.containsKey(c2),
557 "Each mapping should contain the second carbon from substructure");
560 IAtom mappedC1 = mapping.get(c1);
561 IAtom mappedC2 = mapping.get(c2);
562 assertNotNull(mappedC1,
"Mapped atom should not be null");
563 assertNotNull(mappedC2,
"Mapped atom should not be null");
564 assertEquals(
"C", mappedC1.getSymbol(),
"Mapped atom should be carbon");
565 assertEquals(
"C", mappedC2.getSymbol(),
"Mapped atom should be carbon");
567 IBond bond = mol.getBond(mappedC1, mappedC2);
568 assertNotNull(bond,
"Mapped atoms should be bonded in the target molecule");
573 Set<String> uniquePairs =
new HashSet<>();
574 for (Map<IAtom, IAtom> mapping : mappings)
576 IAtom mappedC1 = mapping.get(c1);
577 IAtom mappedC2 = mapping.get(c2);
579 String pairId = mappedC1.getIndex() < mappedC2.getIndex()
580 ? mappedC1.getIndex() +
"-" + mappedC2.getIndex()
581 : mappedC2.getIndex() +
"-" + mappedC1.getIndex();
582 uniquePairs.add(pairId);
585 assertTrue(uniquePairs.size() > 1,
586 "Should have multiple distinct atom pair mappings. " +
587 "Found " + uniquePairs.size() +
" unique pairs");
595 IChemObjectBuilder
builder = SilentChemObjectBuilder.getInstance();
598 IAtomContainer mol =
builder.newAtomContainer();
599 IAtom c1 =
new Atom(
"C",
new Point3d(0.0, 0.0, 0.0));
600 IAtom c2 =
new Atom(
"C",
new Point3d(1.0, 0.0, 0.0));
601 IAtom c3 =
new Atom(
"C",
new Point3d(2.0, 0.0, 0.0));
602 IAtom c4 =
new Atom(
"C",
new Point3d(3.0, 0.0, 0.0));
603 IAtom c5 =
new Atom(
"C",
new Point3d(4.0, 0.0, 0.0));
609 mol.addBond(
new Bond(c1, c2));
610 mol.addBond(
new Bond(c2, c3));
611 mol.addBond(
new Bond(c3, c4));
612 mol.addBond(
new Bond(c4, c5));
615 Map<IAtom, Long> atomToVertexId =
new HashMap<>();
616 atomToVertexId.put(c1, 1L);
617 atomToVertexId.put(c2, 1L);
618 atomToVertexId.put(c3, 1L);
619 atomToVertexId.put(c4, 1L);
620 atomToVertexId.put(c5, 1L);
624 assertNotNull(path,
"Path should not be null");
625 assertEquals(5, path.size(),
"Path should contain 5 atoms");
626 assertEquals(c1, path.get(0),
"First atom should be c1");
627 assertEquals(c2, path.get(1),
"Second atom should be c2");
628 assertEquals(c3, path.get(2),
"Third atom should be c3");
629 assertEquals(c4, path.get(3),
"Fourth atom should be c4");
630 assertEquals(c5, path.get(4),
"Fifth atom should be c5");
634 assertNotNull(path2,
"Path should not be null");
635 assertEquals(3, path2.size(),
"Path should contain 3 atoms");
636 assertEquals(c2, path2.get(0),
"First atom should be c2");
637 assertEquals(c3, path2.get(1),
"Second atom should be c3");
638 assertEquals(c4, path2.get(2),
"Third atom should be c4");
642 assertNotNull(path3,
"Path should not be null");
643 assertTrue(path3.isEmpty(),
"Path from atom to itself should be empty");
646 Map<IAtom, Long> atomToVertexId2 =
new HashMap<>();
647 atomToVertexId2.put(c1, 1L);
648 atomToVertexId2.put(c2, 1L);
649 atomToVertexId2.put(c3, 2L);
650 atomToVertexId2.put(c4, 2L);
651 atomToVertexId2.put(c5, 2L);
655 assertNotNull(path4,
"Path should not be null");
656 assertEquals(5, path4.size(),
"Path should contain 5 atoms even with different vertex IDs");
Utilities for molecule conversion.
static double[] calculateBondAngleAgreement(IAtomContainer templateMol, IAtomContainer mol, Map< IAtom, IAtom > templateToMolMap)
Calculates bond angle agreement and returns raw data.
static double normalizeBondAngleScore(double[] rawData)
Normalizes the raw bond angle agreement data to a single score.
static Map< IAtom, IAtom > findBestAtomMapping(IAtomContainer substructure, IAtomContainer mol, Logger logger)
Finds the maximum common substructure (MCS) between two molecules.
static List< Map< IAtom, IAtom > > findUniqueAtomMappings(IAtomContainer substructure, IAtomContainer mol, Logger logger)
Finds the maximum common substructure (MCS) between two molecules.
static Point3d calculateCentroid(IAtomContainer mol)
Calculated the centroid of the given molecule.
static List< IAtom > findShortestPath(IAtomContainer mol, IAtom start, IAtom end, Map< IAtom, Long > atomToVertexId)
Finds the shortest path between two atoms in a molecule using BFS.
Unit test for DENOPTIMMoleculeUtils.
void testFindShortestPath()
IChemObjectBuilder builder
void testCalculateBondAngleAgreement()
void testFindUniqueAtomMappingsMultipleOccurrences()
void testFindAtomMappingWithMultipleMatches()
boolean areCloseEnough(double a, double b)
void testFindAtomMappingChiral()
void testCalculateCentroid()
void testFindAtomMappingNoMatch()
void testFindAtomMapping()