diff --git a/src/test/org/openscience/cdk/ringsearch/SSSRFinderTest.java b/src/test/org/openscience/cdk/ringsearch/SSSRFinderTest.java index 30fd99f3191..2a381eb303d 100644 --- a/src/test/org/openscience/cdk/ringsearch/SSSRFinderTest.java +++ b/src/test/org/openscience/cdk/ringsearch/SSSRFinderTest.java @@ -1,6 +1,7 @@ /* $Revision$ $Author$ $Date$ * * Copyright (C) 2007 Egon Willighagen + * 2009 Mark Rijnbeek * * Contact: cdk-devel@lists.sourceforge.net * @@ -21,14 +22,18 @@ package org.openscience.cdk.ringsearch; import java.io.InputStream; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; import org.junit.Assert; import org.junit.Test; import org.openscience.cdk.CDKConstants; import org.openscience.cdk.CDKTestCase; import org.openscience.cdk.DefaultChemObjectBuilder; +import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.interfaces.IAtom; +import org.openscience.cdk.interfaces.IAtomContainer; import org.openscience.cdk.interfaces.IChemObject; import org.openscience.cdk.interfaces.IMolecule; import org.openscience.cdk.interfaces.IRing; @@ -242,6 +247,124 @@ private String toString(IRing ring, IMolecule molecule) throws Exception } return str; } + + /** + * Method findRelevantRings() computes the rings (cycles) that are contained + * in *some* SSSR (minimum cycle basis). + */ + @Test public void testBuckyballRelevantRings() throws Exception { + IMolecule buckyball = createBuckyBall(); + IRingSet ringSetRelevant = new SSSRFinder(buckyball).findRelevantRings(); + ringCount(ringSetRelevant,6,20); + ringCount(ringSetRelevant,5,12); + + Assert.assertFalse("Duplicate rings exist", + checkForDuplicateRingsInSet(ringSetRelevant)); + } + + /** + * Method findSSSR() computes one (of possibly several) SSSRs. + */ + @Test public void testBuckyballSSSR() throws Exception { + IMolecule buckyball = createBuckyBall(); + IRingSet ringSetSSSR = new SSSRFinder(buckyball).findSSSR(); + ringCount(ringSetSSSR,6,19); + ringCount(ringSetSSSR,5,12); + Assert.assertFalse("Duplicate rings exist", + checkForDuplicateRingsInSet(ringSetSSSR)); + } + + + /** + * Method findEssentialRings() computes the rings (cycles) contained + * in *any* SSSR (minimum cycle basis). A SSSR for the bucky ball has + * 19 6-rings; by symmetry, this means that any 19 out of the 20 6-rings + * can be chosen for a SSSR. In other words, none of the 20 6-rings + * is essential. + */ + @Test public void testBuckyballEssentialRings() throws Exception { + IMolecule buckyball = createBuckyBall(); + IRingSet ringSetEssential = + new SSSRFinder(buckyball).findEssentialRings(); + ringCount(ringSetEssential,6,0); + ringCount(ringSetEssential,5,12); + Assert.assertFalse("Duplicate rings exist", + checkForDuplicateRingsInSet(ringSetEssential)); + } + + /** + * Creates a bucky ball molecule. + * @return bucky ball molecule + */ + private IMolecule createBuckyBall () throws CDKException { + IMolecule molecule = null; + String filename = "data/mdl/buckyball.mol"; + InputStream ins = + this.getClass().getClassLoader().getResourceAsStream(filename); + MDLV2000Reader reader = new MDLV2000Reader(ins, Mode.STRICT); + molecule = (IMolecule)reader.read(new org.openscience.cdk.Molecule()); + Assert.assertTrue("Atom count is 60 ", molecule.getAtomCount()==60 ); + Assert.assertTrue("Bond count is 90 ", molecule.getBondCount()==90 ); + return molecule; + } + + + /** + * Validates that the SSSR has found the expected number of rings + * of a particular size. + * @param ringSet constructed by SSSR. + * @param ringSizeForCounting particular ring size to count + * @param expectedNumOfRings the expected number of rings + */ + private void ringCount + (IRingSet ringSet, int ringSizeForCounting, int expectedNumOfRings) { + int ringCount = 0; + for (IAtomContainer ring : ringSet.atomContainers() ) { + if (ring.getAtomCount() == ringSizeForCounting) { + ringCount++; + } + } + Assert.assertTrue("Counting rings of size "+ringSizeForCounting, + expectedNumOfRings ==ringCount); + } + + + /** + * Checks if the ringSet (created by SSSR) contains rings with + * exactly the same atoms. + */ + static boolean checkForDuplicateRingsInSet(IRingSet ringset) { + // Make a list of rings + List ringList=new ArrayList (); + for (IAtomContainer atCont : ringset.atomContainers() ) { + ringList.add(atCont); + } + //Outer loop over rings + for (IAtomContainer ring : ringList) { + // Inner loop over rings + for (IAtomContainer otherRing : ringList) { + if (otherRing.hashCode() != ring.hashCode() && + otherRing.getAtomCount()==ring.getAtomCount()) { + + // check if the two rings have all the same atoms in them - + // this should not happen (="duplicate" rings) + boolean sameAtoms=true; + DUP_LOOP: + for (IAtom at : ring.atoms() ) { + if (!otherRing.contains(at)) { + sameAtoms=false; + break DUP_LOOP; + } + } + if (sameAtoms) { + return true; + } + } + } + } + return false; + } + }