1 /* Copyright (C) 2011 Egon Willighagen <egonw@users.sf.net> 2 * 3 * Contact: cdk-devel@slists.sourceforge.net 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public License 7 * as published by the Free Software Foundation; either version 2.1 8 * of the License, or (at your option) any later version. 9 * All we ask is that proper credit is given for our work, which includes 10 * - but is not limited to - adding the above copyright notice to the beginning 11 * of your source code files, and to any copyright notice that you may distribute 12 * with programs based on this work. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22 */ 23 package org.openscience.cdk.io; 24 25 import java.io.ByteArrayInputStream; 26 import java.io.IOException; 27 import java.io.InputStream; 28 import java.io.InputStreamReader; 29 import java.util.List; 30 31 import org.junit.Assert; 32 import org.junit.BeforeClass; 33 import org.junit.Test; 34 import org.openscience.cdk.ChemFile; 35 import org.openscience.cdk.DefaultChemObjectBuilder; 36 import org.openscience.cdk.exception.CDKException; 37 import org.openscience.cdk.interfaces.IAtom; 38 import org.openscience.cdk.interfaces.IAtomContainer; 39 import org.openscience.cdk.interfaces.IBond; 40 import org.openscience.cdk.interfaces.IChemFile; 41 import org.openscience.cdk.tools.manipulator.ChemFileManipulator; 42 import org.openscience.cdk.tools.periodictable.PeriodicTable; 43 44 /** 45 * TestCase for reading CML files. 46 * 47 * @cdk.module test-io 48 */ 49 public class CMLReaderTest extends SimpleChemObjectReaderTest { 50 51 @BeforeClass setup()52 public static void setup() { 53 setSimpleChemObjectReader(new CMLReader(), "data/cml/3.cml"); 54 } 55 56 @Test testAccepts()57 public void testAccepts() { 58 Assert.assertTrue(chemObjectIO.accepts(ChemFile.class)); 59 } 60 61 @Test(expected = CDKException.class) 62 @Override testSetReader_Reader()63 public void testSetReader_Reader() throws Exception { 64 InputStream ins = ChemObjectReaderTest.class.getClassLoader().getResourceAsStream(testFile); 65 chemObjectIO.setReader(new InputStreamReader(ins)); 66 } 67 68 /** 69 * Ensure stereoBond content is read if the usual "dictRef" attribute is not 70 * supplied 71 * 72 * @cdk.bug 1248 73 */ 74 @Test testBug1248()75 public void testBug1248() throws IOException, CDKException { 76 77 InputStream in = getClass().getResourceAsStream("/data/cml/(1R)-1-aminoethan-1-ol.cml"); 78 CMLReader reader = new CMLReader(in); 79 try { 80 IChemFile cfile = reader.read(DefaultChemObjectBuilder.getInstance().newInstance(IChemFile.class)); 81 82 Assert.assertNotNull("ChemFile was Null", cfile); 83 84 List<IAtomContainer> containers = ChemFileManipulator.getAllAtomContainers(cfile); 85 86 Assert.assertEquals("Expected a single atom container", 1, containers.size()); 87 88 IAtomContainer container = containers.get(0); 89 90 Assert.assertNotNull("Null atom container read", container); 91 92 IBond bond = container.getBond(2); 93 94 Assert.assertNotNull("Null bond", bond); 95 96 Assert.assertEquals("Expected Wedge (Up) Bond", IBond.Stereo.UP, bond.getStereo()); 97 98 } finally { 99 reader.close(); 100 } 101 102 } 103 104 /** 105 * Ensure correct atomic numbers are read and does not default to 1 106 * 107 * @cdk.bug 1245 108 */ 109 @Test testBug1245()110 public void testBug1245() throws IOException, CDKException { 111 112 InputStream in = getClass().getResourceAsStream("/data/cml/(1R)-1-aminoethan-1-ol.cml"); 113 CMLReader reader = new CMLReader(in); 114 try { 115 IChemFile cfile = reader.read(DefaultChemObjectBuilder.getInstance().newInstance(IChemFile.class)); 116 117 Assert.assertNotNull("ChemFile was Null", cfile); 118 119 List<IAtomContainer> containers = ChemFileManipulator.getAllAtomContainers(cfile); 120 121 Assert.assertEquals("Expected a single atom container", 1, containers.size()); 122 123 IAtomContainer container = containers.get(0); 124 125 Assert.assertNotNull("Null atom container read", container); 126 127 for (IAtom atom : container.atoms()) { 128 Assert.assertEquals("Incorrect atomic number", PeriodicTable.getAtomicNumber(atom.getSymbol()), 129 atom.getAtomicNumber()); 130 } 131 132 } finally { 133 reader.close(); 134 } 135 } 136 137 /** 138 * Ensures that when multiple stereo is set the dictRef is favoured 139 * and the charContent is not used. Here is an example of what we expect 140 * to read. 141 * 142 * <pre>{@code 143 * <bond atomRefs2="a1 a4" order="1"> 144 * <bondStereo dictRef="cml:W"/> <!-- should be W --> 145 * </bond> 146 * 147 * <bond atomRefs2="a1 a4" order="1"> 148 * <bondStereo>W</bondStereo> <!-- should be W --> 149 * </bond> 150 * 151 * <bond atomRefs2="a1 a4" order="1"> 152 * <bondStereo dictRef="cml:W">W</bondStereo> <!-- should be W --> 153 * </bond> 154 * 155 * <bond atomRefs2="a1 a4" order="1"> 156 * <bondStereo dictRef="cml:W">H</bondStereo> <!-- should be W --> 157 * </bond> 158 * }</pre> 159 * 160 * @cdk.bug 1274 161 * @see #testBug1248() 162 */ 163 @Test testBug1274()164 public void testBug1274() throws CDKException, IOException { 165 166 InputStream in = getClass().getResourceAsStream("/data/cml/(1R)-1-aminoethan-1-ol-multipleBondStereo.cml"); 167 CMLReader reader = new CMLReader(in); 168 try { 169 IChemFile cfile = reader.read(DefaultChemObjectBuilder.getInstance().newInstance(IChemFile.class)); 170 171 Assert.assertNotNull("ChemFile was null", cfile); 172 173 List<IAtomContainer> containers = ChemFileManipulator.getAllAtomContainers(cfile); 174 175 Assert.assertEquals("expected a single atom container", 1, containers.size()); 176 177 IAtomContainer container = containers.get(0); 178 179 Assert.assertNotNull("null atom container read", container); 180 181 // we check here that the charContent is not used and also that more then 182 // one stereo isn't set 183 Assert.assertEquals("expected non-stereo bond", IBond.Stereo.NONE, container.getBond(0).getStereo()); 184 Assert.assertEquals("expected Hatch (Down) Bond", IBond.Stereo.DOWN, container.getBond(1).getStereo()); 185 Assert.assertEquals("expected non-stereo bond", IBond.Stereo.NONE, container.getBond(2).getStereo()); 186 187 } finally { 188 reader.close(); 189 } 190 } 191 192 /** 193 * Ensures that {@code <bondStereo dictRef="cml:"/>} doesn't cause an exception 194 * 195 * @cdk.bug 1275 196 */ 197 @Test testBug1275()198 public void testBug1275() throws CDKException, IOException { 199 200 InputStream in = getClass().getResourceAsStream("/data/cml/(1R)-1-aminoethan-1-ol-malformedDictRef.cml"); 201 CMLReader reader = new CMLReader(in); 202 try { 203 IChemFile cfile = reader.read(DefaultChemObjectBuilder.getInstance().newInstance(IChemFile.class)); 204 205 Assert.assertNotNull("ChemFile was null", cfile); 206 207 List<IAtomContainer> containers = ChemFileManipulator.getAllAtomContainers(cfile); 208 209 Assert.assertEquals("expected a single atom container", 1, containers.size()); 210 211 IAtomContainer container = containers.get(0); 212 213 Assert.assertNotNull("null atom container read", container); 214 215 // we check here that the malformed dictRef doesn't throw an exception 216 Assert.assertEquals("expected non-stereo bond", IBond.Stereo.NONE, container.getBond(0).getStereo()); 217 Assert.assertEquals("expected Wedge (Up) Bond", IBond.Stereo.UP, container.getBond(1).getStereo()); 218 Assert.assertEquals("expected non-stereo bond", IBond.Stereo.NONE, container.getBond(2).getStereo()); 219 220 } finally { 221 reader.close(); 222 } 223 224 } 225 226 @Test testWedgeBondParsing()227 public void testWedgeBondParsing() throws CDKException, IOException { 228 InputStream in = getClass().getResourceAsStream("/data/cml/AZD5423.xml"); 229 CMLReader reader = new CMLReader(in); 230 try { 231 IChemFile cfile = reader.read(DefaultChemObjectBuilder.getInstance().newInstance(IChemFile.class)); 232 Assert.assertNotNull("ChemFile was null", cfile); 233 List<IAtomContainer> containers = ChemFileManipulator.getAllAtomContainers(cfile); 234 Assert.assertEquals("expected a single atom container", 1, containers.size()); 235 IAtomContainer container = containers.get(0); 236 Assert.assertNotNull("null atom container read", container); 237 238 // we check here that the malformed dictRef doesn't throw an exception 239 for (int i = 0; i < 19; i++) { 240 Assert.assertEquals( 241 "found an unexpected wedge bond for " + i + ": " + container.getBond(i).getStereo(), 242 IBond.Stereo.NONE, container.getBond(i).getStereo()); 243 } 244 Assert.assertEquals("expected a wedge bond", IBond.Stereo.DOWN, container.getBond(19).getStereo()); 245 for (int i = 20; i < 30; i++) { 246 Assert.assertEquals( 247 "found an unexpected wedge bond for " + i + ": " + container.getBond(i).getStereo(), 248 IBond.Stereo.NONE, container.getBond(i).getStereo()); 249 } 250 Assert.assertEquals("expected a wedge bond", IBond.Stereo.UP, container.getBond(30).getStereo()); 251 for (int i = 31; i <= 37; i++) { 252 Assert.assertEquals( 253 "found an unexpected wedge bond for " + i + ": " + container.getBond(i).getStereo(), 254 IBond.Stereo.NONE, container.getBond(i).getStereo()); 255 } 256 } finally { 257 reader.close(); 258 } 259 } 260 261 @Test testSFBug1085912_1()262 public void testSFBug1085912_1() throws Exception { 263 String cmlContent = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" 264 + "<molecule convention=\"PDB\" dictRef=\"pdb:model\" xmlns=\"http://www.xml-cml.org/schema\">" 265 + " <molecule dictRef=\"pdb:sequence\" id=\"ALAA116\">" 266 + " <atomArray>" 267 + " <atom id=\"a9794931\" elementType=\"N\" x3=\"-10.311\" y3=\"2.77\" z3=\"-9.837\" formalCharge=\"0\">" 268 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 269 + " </atom>" 270 + " <atom id=\"a5369354\" elementType=\"C\" x3=\"-9.75\" y3=\"4.026\" z3=\"-9.35\" formalCharge=\"0\">" 271 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 272 + " </atom>" 273 + " <atom id=\"a14877152\" elementType=\"C\" x3=\"-10.818\" y3=\"5.095\" z3=\"-9.151\" formalCharge=\"0\">" 274 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 275 + " </atom>" 276 + " <atom id=\"a26221736\" elementType=\"O\" x3=\"-11.558\" y3=\"5.433\" z3=\"-10.074\" formalCharge=\"0\">" 277 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 278 + " </atom>" 279 + " <atom id=\"a4811470\" elementType=\"C\" x3=\"-8.678\" y3=\"4.536\" z3=\"-10.304\" formalCharge=\"0\">" 280 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 281 + " </atom>" 282 + " <atom id=\"a211489\" elementType=\"H\" x3=\"-10.574\" y3=\"2.695\" z3=\"-10.778\" formalCharge=\"0\">" 283 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 284 + " </atom>" 285 + " <atom id=\"a31287617\" elementType=\"H\" x3=\"-9.279\" y3=\"3.829\" z3=\"-8.398\" formalCharge=\"0\">" 286 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 287 + " </atom>" 288 + " <atom id=\"a19487109\" elementType=\"H\" x3=\"-8.523\" y3=\"3.813\" z3=\"-11.09\" formalCharge=\"0\">" 289 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 290 + " </atom>" 291 + " <atom id=\"a28589522\" elementType=\"H\" x3=\"-8.994\" y3=\"5.477\" z3=\"-10.737\" formalCharge=\"0\">" 292 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 293 + " </atom>" 294 + " <atom id=\"a4638116\" elementType=\"H\" x3=\"-7.754\" y3=\"4.682\" z3=\"-9.763\" formalCharge=\"0\">" 295 + " <scalar dictRef=\"cdk:partialCharge\" dataType=\"xsd:double\">0.0</scalar>" 296 + " </atom>" + " </atomArray>" + " </molecule>" + "</molecule>"; 297 CMLReader reader = new CMLReader(new ByteArrayInputStream(cmlContent.getBytes())); 298 try { 299 IChemFile cfile = reader.read(DefaultChemObjectBuilder.getInstance().newInstance(IChemFile.class)); 300 Assert.assertNotNull("ChemFile was null", cfile); 301 List<IAtomContainer> containers = ChemFileManipulator.getAllAtomContainers(cfile); 302 Assert.assertEquals("expected a single atom container", 1, containers.size()); 303 IAtomContainer container = containers.get(0); 304 Assert.assertNotNull("null atom container read", container); 305 306 // OK, now test that the residue identifier is properly read 307 Assert.assertEquals("ALAA116", container.getID()); 308 } finally { 309 reader.close(); 310 } 311 } 312 313 @Test testMixedNamespaces()314 public void testMixedNamespaces() throws Exception { 315 InputStream in = getClass().getResourceAsStream("US06358966-20020319-C00001-enr.cml"); 316 CMLReader reader = new CMLReader(in); 317 try { 318 IChemFile cfile = reader.read(DefaultChemObjectBuilder.getInstance().newInstance(IChemFile.class)); 319 Assert.assertEquals(34, ChemFileManipulator.getAtomCount(cfile)); 320 Assert.assertEquals(39, ChemFileManipulator.getBondCount(cfile)); 321 } finally { 322 reader.close(); 323 } 324 325 } 326 } 327