diff --git a/src/main/org/openscience/cdk/layout/OverlapResolver.java b/src/main/org/openscience/cdk/layout/OverlapResolver.java index 7727910904a..7f8986bfcd1 100644 --- a/src/main/org/openscience/cdk/layout/OverlapResolver.java +++ b/src/main/org/openscience/cdk/layout/OverlapResolver.java @@ -129,7 +129,13 @@ public double displace(IAtomContainer ac, Vector overlappingAtoms, Vector overla v2 = new Vector2d(a2.getPoint2d()); v2.sub(v1); v2.normalize(); - v2.scale(bondLength / 20.0); + + if(Double.isNaN(v2.x)) + v2.x=0.01; + if(Double.isNaN(v2.y)) + v2.y=0.01; + + v2.scale(bondLength / 20.0); logger.debug("Calculation translation vector " + v2); choice = Math.random(); if (choice > 0.5) diff --git a/src/test/org/openscience/cdk/layout/StructureDiagramGeneratorTest.java b/src/test/org/openscience/cdk/layout/StructureDiagramGeneratorTest.java index 5dd8c71820b..9bf53bbdd36 100644 --- a/src/test/org/openscience/cdk/layout/StructureDiagramGeneratorTest.java +++ b/src/test/org/openscience/cdk/layout/StructureDiagramGeneratorTest.java @@ -1,6 +1,5 @@ -/* $Revision$ $Author$ $Date$ - * - * Copyright (C) 2003-2007 Christoph Steinbeck +/* Copyright (C) 2003-2007 Christoph Steinbeck + * 2009 Mark Rijnbeek * * Contact: cdk-devel@lists.sourceforge.net * @@ -29,6 +28,7 @@ import javax.vecmath.Vector2d; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.openscience.cdk.Atom; @@ -38,7 +38,9 @@ import org.openscience.cdk.Molecule; import org.openscience.cdk.CDKTestCase; import org.openscience.cdk.aromaticity.CDKHueckelAromaticityDetector; +import org.openscience.cdk.exception.InvalidSmilesException; import org.openscience.cdk.geometry.GeometryTools; +import org.openscience.cdk.interfaces.IAtom; import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IBond; import org.openscience.cdk.interfaces.IChemModel; @@ -843,5 +845,51 @@ public void testBug1784850InfiniteLoop() throws Exception { // test completed, no timeout occured } + /** + * For the SMILES compound below (the largest molecule in Chembl) a + * handful of atoms had invalid (NaN) Double coordinates. + * + * @cdk.bug 2843445 + */ + @Test (timeout=5000) + public void testBug2843445NaNCoords() throws Exception { + + SmilesParser sp = + new SmilesParser(NoNotificationChemObjectBuilder.getInstance()); + String smiles = + "CCCC[C@H](NC(=O)[C@H](CCC(O)=O)NC(=O)[C@@H](NC(=O)[C@@H](CCCC)NC" + + "(=O)[C@H](CC(N)=O)NC(=O)[C@H](CCC\\N=C(\\N)N)NC(=O)[C@H](CC(C)C)NC" + + "(=O)[C@H](CC(C)C)NC(=O)[C@H](CC1=CNC=N1)NC(=O)[C@H](CC1=CC=CC=C1" + + ")NC(=O)[C@@H](NC(=O)[C@H](CC(C)C)NC(=O)[C@H](CC(O)=O)NC(=O)[C@@H" + + "](NC(=O)[C@H](CO)NC(=O)[C@@H](NC(=O)[C@@H]1CCCN1C(=O)[C@@H]1CCCN" + + "1C(=O)[C@H](CC(O)=O)NC(=O)[C@H](CC(O)=O)NC(=O)[C@@H](N)CC(N)=O)[" + + "C@@H](C)CC)[C@@H](C)CC)[C@@H](C)O)[C@@H](C)CC)C(=O)N[C@@H](C)C(=" + + "O)N[C@@H](CCC\\N=C(\\N)N)C(=O)N[C@@H]([C@@H](C)CC)C(=O)N[C@@H](CCC" + + "(O)=O)C(=O)N[C@@H](CC(N)=O)C(=O)N[C@@H](CCC(=O)OC)C(=O)N[C@@H](C" + + "CC\\N=C(\\N)N)C(=O)N[C@@H](CCC(O)=O)C(=O)N[C@@H](CCC(O)=O)C(=O)N[C" + + "@@H](C)C(=O)NCC(=O)N[C@@H](CCCCN)C(=O)N[C@@H](CC(N)=O)C(=O)N[C@@" + + "H](CCC\\N=C(\\N)N)C(=O)N[C@@H](CCCCN)C(=O)N[C@@H](CC1=CC=C(O)C=C1)" + + "C(=O)N[C@@H](CC(C)C)C(=O)N[C@@H](CC(O)=O)C(=O)N[C@@H](CCC(O)=O)C" + + "(=O)N[C@@H](C(C)C)C(N)=O"; + IMolecule mol = sp.parseSmiles(smiles); + + StructureDiagramGenerator sdg = new StructureDiagramGenerator(); + sdg.setMolecule(mol); + sdg.generateCoordinates(new Vector2d(0, 1)); + mol = sdg.getMolecule(); + + int invalidCoordCount=0; + for (IAtom atom: mol.atoms()) { + if (Double.isNaN(atom.getPoint2d().x) || + Double.isNaN(atom.getPoint2d().y)) { + invalidCoordCount++; + } + } + Assert.assertEquals("No 2d coordinates should be NaN", + 0, invalidCoordCount + ); + } + + }