MDLV2000Writer extends DefaultChemObjectWriter { @Override public void write(IChemObject object) throws CDKException { customizeJob(); try { if (object instanceof IChemFile) { writeChemFile((IChemFile) object); return; } else if (object instanceof IChemModel) { IChemFile file = object.getBuilder().newInstance(IChemFile.class); IChemSequence sequence = object.getBuilder().newInstance(IChemSequence.class); sequence.addChemModel((IChemModel) object); file.addChemSequence(sequence); writeChemFile((IChemFile) file); return; } else if (object instanceof IAtomContainer) { writeMolecule((IAtomContainer) object); return; } } catch (Exception ex) { logger.error(ex.getMessage()); logger.debug(ex); throw new CDKException("Exception while writing MDL file: " + ex.getMessage(), ex); } throw new CDKException("Only supported is writing of IChemFile, " + "IChemModel, and IAtomContainer objects."); } MDLV2000Writer(Writer out);  MDLV2000Writer(OutputStream output);  MDLV2000Writer(); @Override IResourceFormat getFormat(); @Override void setWriter(Writer out); @Override void setWriter(OutputStream output); @Override void close(); @Override boolean accepts(Class<? extends IChemObject> classObject); @Override void write(IChemObject object); void writeMolecule(IAtomContainer container); void setWriteAromaticBondTypes(boolean val); void customizeJob(); static final String OptForceWriteAs2DCoordinates; static final String OptWriteMajorIsotopes; static final String OptWriteAromaticBondTypes; static final String OptWriteQueryFormatValencies; static final String OptWriteDefaultProperties; static final String OptProgramName; }
@Test public void testSgroupAtomListWrapping() throws Exception { IAtomContainer mol = TestMoleculeFactory.makeEthylPropylPhenantren(); Sgroup sgroup = new Sgroup(); for (IAtom atom : mol.atoms()) sgroup.addAtom(atom); mol.setProperty(CDKConstants.CTAB_SGROUPS, Collections.singletonList(sgroup)); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); String output = sw.toString(); assertThat(output, containsString("M SAL 1 15")); assertThat(output, containsString("M SAL 1 4")); } }
@Test public void sgroupRepeatUnitRoundTrip() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/sgroup-sru.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("M STY 1 1 SRU")); assertThat(output, containsString("M SMT 1 n")); assertThat(output, containsString("M SCN 1 1 HT")); } }
@Test public void sgroupBracketStylesRoundTrip() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/sgroup-sru-bracketstyles.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("M STY 2 1 SRU 2 SRU")); assertThat(output, containsString("M SBT 1 1 1")); } }
@Test public void sgroupUnorderedMixtureRoundTrip() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/sgroup-unord-mixture.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("M STY 3 1 COM 2 COM 3 MIX")); assertThat(output, containsString("M SPL 2 1 3 2 3")); } }
@Test public void sgroupCopolymerRoundTrip() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/sgroup-ran-copolymer.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("M SST 1 1 RAN")); assertThat(output, containsString("M STY 3 1 COP 2 SRU 3 SRU")); } }
@Test public void sgroupExpandedAbbreviationRoundTrip() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/triphenyl-phosphate-expanded.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("M STY 3 1 SUP 2 SUP 3 SUP\n")); assertThat(output, containsString("M SDS EXP 1 1")); } }
@Test public void sgroupParentAtomListRoundTrip() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/ChEBI_81539.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("M STY 5 1 MUL 2 SRU")); assertThat(output, containsString("M SPA 1 12")); } }
@Test public void sgroupOrderedMixtureRoundTrip() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/sgroup-ord-mixture.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("M STY 3 1 COM 2 COM 3 FOR")); assertThat(output, containsString("M SNC 1 1 1")); assertThat(output, containsString("M SNC 1 2 2")); } }
@Test public void roundtripAtomParityExpH() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/tetrahedral-parity-withExpH.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString(" 0.0000 0.0000 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0\n")); } }
@Test public void roundtripAtomParityImplH() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/tetrahedral-parity-withImplH.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString(" 0.0000 0.0000 0.0000 C 0 0 1 0 0 0 0 0 0 0 0 0\n")); } }
@Test public void roundtripAtomParityImplModified() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/tetrahedral-parity-withImplH.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { AtomContainer mol = mdlr.read(new AtomContainer()); ITetrahedralChirality tc = (ITetrahedralChirality) mol.stereoElements().iterator().next(); tc.setStereo(tc.getStereo().invert()); mdlw.write(mol); String output = sw.toString(); assertThat(output, containsString(" 0.0000 0.0000 0.0000 C 0 0 2 0 0 0 0 0 0 0 0 0\n")); } }
@Test(expected = CDKException.class) public void aromaticBondTypes() throws Exception { IAtomContainer mol = builder.newInstance(IAtomContainer.class); mol.addAtom(builder.newInstance(IAtom.class, "C")); mol.addAtom(builder.newInstance(IAtom.class, "C")); IBond bond = builder.newInstance(IBond.class, mol.getAtom(0), mol.getAtom(1), Order.UNSET); bond.setIsAromatic(true); mol.addBond(bond); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } }
@Test public void writeDimensionField() throws Exception { IAtomContainer mol = builder.newAtomContainer(); IAtom atom = builder.newAtom(); atom.setSymbol("C"); atom.setImplicitHydrogenCount(4); atom.setPoint2d(new Point2d(0.5, 0.5)); mol.addAtom(atom); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } assertThat(sw.toString(), containsString("2D")); }
@Test public void writeDimensionField3D() throws Exception { IAtomContainer mol = builder.newAtomContainer(); IAtom atom = builder.newAtom(); atom.setSymbol("C"); atom.setImplicitHydrogenCount(4); atom.setPoint3d(new Point3d(0.5, 0.5, 0.1)); mol.addAtom(atom); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } assertThat(sw.toString(), containsString("3D")); }
@Test public void writeMoreThan8Radicals() throws Exception { IAtomContainer mol = builder.newAtomContainer(); for (int i = 0; i < 20; i++) { IAtom atom = builder.newAtom(); atom.setSymbol("C"); mol.addAtom(atom); mol.addSingleElectron(builder.newInstance(ISingleElectron.class, atom)); } StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } assertThat(sw.toString(), containsString("M RAD 8 9 2 10 2 11 2 12 2 13 2 14 2 15 2 16 2")); }
@Test public void writeCarbon12() throws Exception { IAtomContainer mol = builder.newAtomContainer(); IAtom atom = builder.newAtom(); atom.setSymbol("C"); atom.setMassNumber(12); mol.addAtom(atom); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } assertThat(sw.toString(), containsString("M ISO 1 1 12")); }
@Test public void ignoreCarbon12() throws Exception { IAtomContainer mol = builder.newAtomContainer(); IAtom atom = builder.newAtom(); atom.setSymbol("C"); atom.setMassNumber(12); mol.addAtom(atom); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.getSetting(MDLV2000Writer.OptWriteMajorIsotopes) .setSetting("false"); mdlw.write(mol); } assertThat(sw.toString(), not(containsString("M ISO 1 1 12"))); }
@Test public void writeCarbon13AtomProps() throws Exception { IAtomContainer mol = builder.newAtomContainer(); IAtom atom = builder.newAtom(); atom.setSymbol("C"); atom.setMassNumber(13); mol.addAtom(atom); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } assertThat(sw.toString(), containsString("C 1")); }
@Test public void writeChargeAtomProps() throws Exception { IAtomContainer mol = builder.newAtomContainer(); IAtom atom = builder.newAtom(); atom.setSymbol("C"); atom.setFormalCharge(+1); mol.addAtom(atom); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } assertThat(sw.toString(), containsString("C 0 3")); }
@Test public void skipDefaultProps() throws Exception { StringWriter sw = new StringWriter(); try (MDLV2000Reader mdlr = new MDLV2000Reader(getClass().getResourceAsStream("/data/mdl/tetrahedral-parity-withImplH.mol")); MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.getSetting(MDLV2000Writer.OptWriteDefaultProperties) .setSetting("false"); mdlw.write(mdlr.read(new AtomContainer())); String output = sw.toString(); assertThat(output, containsString("\n" + " 5 4 0 0 1 0 0 0 0 0999 V2000\n" + " 0.0000 0.0000 0.0000 C 0 0 1 0 0 0\n" + " 0.0000 0.0000 0.0000 C 0 0\n" + " 0.0000 0.0000 0.0000 C 0 0\n" + " 0.0000 0.0000 0.0000 O 0 0\n" + " 0.0000 0.0000 0.0000 C 0 0\n" + " 1 2 1 0\n" + " 2 3 1 0\n" + " 1 4 1 0\n" + " 1 5 1 0\n" + "M END")); } }
@Test public void writeParentAtomSgroupAsList() throws Exception{ IAtomContainer mol = builder.newAtomContainer(); IAtom atom = builder.newAtom(); atom.setSymbol("C"); mol.addAtom(atom); Sgroup sgroup = new Sgroup(); sgroup.setType(SgroupType.CtabMultipleGroup); sgroup.addAtom(atom); List<IAtom> patoms = new ArrayList<>(); patoms.add(atom); sgroup.putValue(SgroupKey.CtabParentAtomList, patoms); mol.setProperty(CDKConstants.CTAB_SGROUPS, Collections.singletonList(sgroup)); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } assertThat(sw.toString(), containsString("SPA 1 1")); }
@Test public void roundTripWithNotAtomList() throws Exception { try (InputStream in = getClass().getResourceAsStream("query_notatomlist.mol"); MDLV2000Reader mdlr = new MDLV2000Reader(in)) { IAtomContainer mol = mdlr.read(SilentChemObjectBuilder.getInstance().newAtomContainer()); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } String writtenMol = sw.toString(); assertThat(writtenMol, containsString( " 1 T 3 9 7 8\n" + "M ALS 1 3 T F N O")); } }
@Test public void roundTripWithAtomList() throws Exception { try (InputStream in = getClass().getResourceAsStream("query_atomlist.mol"); MDLV2000Reader mdlr = new MDLV2000Reader(in)) { IAtomContainer mol = mdlr.read(SilentChemObjectBuilder.getInstance().newAtomContainer()); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } String writtenMol = sw.toString(); assertThat(writtenMol, containsString( " 1 F 3 9 7 8\n"+ "M ALS 1 3 F F N O")); } }
@Test public void roundTripWithMultipleLegacyAtomLists() throws Exception { try (InputStream in = getClass().getResourceAsStream("query_manylegacyatomlist.mol"); MDLV2000Reader mdlr = new MDLV2000Reader(in)) { IAtomContainer mol = mdlr.read(SilentChemObjectBuilder.getInstance().newAtomContainer()); StringWriter sw = new StringWriter(); try (MDLV2000Writer mdlw = new MDLV2000Writer(sw)) { mdlw.write(mol); } String writtenMol = sw.toString(); assertThat(writtenMol, containsString( " 4 F 2 8 7\n" + " 5 F 2 7 8\n" + " 6 F 2 7 8\n"+ "M ALS 4 2 F O N \n" + "M ALS 5 2 F N O \n" + "M ALS 6 2 F N O")); } }
@Test public void dataSgroupRoundTrip() { String path = "/data/mdl/hbr_acoh_mix.mol"; try (InputStream in = getClass().getResourceAsStream(path)) { MDLV2000Reader mdlr = new MDLV2000Reader(in); IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance(); IAtomContainer mol = mdlr.read(builder.newAtomContainer()); try (StringWriter sw = new StringWriter(); MDLV2000Writer writer = new MDLV2000Writer(sw)) { writer.write(mol); String output = sw.toString(); assertThat(output, CoreMatchers.containsString("M SDT 3 WEIGHT_PERCENT N %")); assertThat(output, CoreMatchers.containsString("M SED 3 33%")); } } catch (IOException | CDKException e) { Assert.fail(e.getMessage()); } }