/** * Takes an object which subclasses IChemObject, e.g.Molecule, and will read this (from file, * database, internet etc). If the specific implementation does not support a specific IChemObject * it will throw an Exception. * * @param object The object that subclasses IChemObject * @return The IChemObject read * @exception CDKException */ public IChemObject read(IChemObject object) throws CDKException { if (object instanceof IReaction) { return (IChemObject) readReaction(object.getBuilder()); } else if (object instanceof IReactionSet) { IReactionSet reactionSet = object.getBuilder().newReactionSet(); reactionSet.addReaction(readReaction(object.getBuilder())); return reactionSet; } else if (object instanceof IChemModel) { IChemModel model = object.getBuilder().newChemModel(); IReactionSet reactionSet = object.getBuilder().newReactionSet(); reactionSet.addReaction(readReaction(object.getBuilder())); model.setReactionSet(reactionSet); return model; } else if (object instanceof IChemFile) { IChemFile chemFile = object.getBuilder().newChemFile(); IChemSequence sequence = object.getBuilder().newChemSequence(); sequence.addChemModel((IChemModel) read(object.getBuilder().newChemModel())); chemFile.addChemSequence(sequence); return chemFile; } else { throw new CDKException( "Only supported are Reaction and ChemModel, and not " + object.getClass().getName() + "."); } }
private IChemFile readChemFile() throws CDKException { IChemSequence seq = file.getBuilder().newChemSequence(); IChemModel model = file.getBuilder().newChemModel(); IMoleculeSet containerSet = file.getBuilder().newMoleculeSet(); IMolecule container = file.getBuilder().newMolecule(); int lineNumber = 0; try { String line = input.readLine(); while (input.ready() && line != null) { logger.debug((lineNumber++) + ": ", line); String command = null; if (isCommand(line)) { command = getCommand(line); int lineCount = getContentLinesCount(line); if ("ATOMS".equals(command)) { processAtomsBlock(lineCount, container); } else if ("BONDS".equals(command)) { processBondsBlock(lineCount, container); } else if ("IDENT".equals(command)) { processIdentBlock(lineCount, container); } else if ("NAME".equals(command)) { processNameBlock(lineCount, container); } else { // skip lines logger.warn("Dropping block: ", command); for (int i = 0; i < lineCount; i++) input.readLine(); } } else { logger.warn("Unexpected content at line: ", lineNumber); } line = input.readLine(); } containerSet.addAtomContainer(container); model.setMoleculeSet(containerSet); seq.addChemModel(model); file.addChemSequence(seq); } catch (Exception exception) { String message = "Error while parsing CTX file: " + exception.getMessage(); logger.error(message); logger.debug(exception); throw new CDKException(message, exception); } return file; }
/** * Read a ChemFile from a file in MDL SDF format. * * @return The ChemFile that was read from the MDL file. */ private IChemFile readChemFile(IChemFile chemFile) throws CDKException { IChemSequence chemSequence = chemFile.getBuilder().newInstance(IChemSequence.class); IChemModel chemModel = chemFile.getBuilder().newInstance(IChemModel.class); IAtomContainerSet setOfMolecules = chemFile.getBuilder().newInstance(IAtomContainerSet.class); IAtomContainer m = readAtomContainer(chemFile.getBuilder().newInstance(IAtomContainer.class)); if (m != null && m instanceof IAtomContainer) { setOfMolecules.addAtomContainer((IAtomContainer) m); } chemModel.setMoleculeSet(setOfMolecules); chemSequence.addChemModel(chemModel); setOfMolecules = chemFile.getBuilder().newInstance(IAtomContainerSet.class); chemModel = chemFile.getBuilder().newInstance(IChemModel.class); String str; try { String line; while ((line = input.readLine()) != null) { logger.debug("line: ", line); // apparently, this is a SDF file, continue with // reading mol files str = new String(line); if (str.equals("$$$$")) { m = readAtomContainer(chemFile.getBuilder().newInstance(IAtomContainer.class)); if (m != null && m instanceof IAtomContainer) { setOfMolecules.addAtomContainer((IAtomContainer) m); chemModel.setMoleculeSet(setOfMolecules); chemSequence.addChemModel(chemModel); setOfMolecules = chemFile.getBuilder().newInstance(IAtomContainerSet.class); chemModel = chemFile.getBuilder().newInstance(IChemModel.class); } } else { // here the stuff between 'M END' and '$$$$' if (m != null) { // ok, the first lines should start with '>' String fieldName = null; if (str.startsWith("> ")) { // ok, should extract the field name str.substring(2); // String content = int index = str.indexOf("<"); if (index != -1) { int index2 = str.substring(index).indexOf(">"); if (index2 != -1) { fieldName = str.substring(index + 1, index + index2); } } } if (line == null) { throw new CDKException("Expecting data line here, but found null!"); } StringBuilder data = new StringBuilder(); int dataLineCount = 0; boolean lineIsContinued = false; while ((line = input.readLine()) != null) { if (line.equals(" ") && dataLineCount == 0) { // apparently a file can have a field whose value is a single space. Moronic // we check for it *before* trimming it. ideally we should check for any length // of whitespace // In adition some SD files have the blank line after the value line contain // a space, rather than being a true blank line. So we only store a blank value // line if it's the first line after the key line data.append(line); lineIsContinued = false; dataLineCount++; if (!lineIsContinued && dataLineCount > 1) data.append(System.getProperty("line.separator")); continue; } line = line.trim(); if (line.length() == 0) break; if (line.equals("$$$$")) { logger.error("Expecting data line here, but found end of molecule: ", line); break; } logger.debug("data line: ", line); lineIsContinued = false; // reset property dataLineCount++; // preserve newlines, unless the line is exactly 80 chars; // in that case it is assumed to continue on the next line. // See MDL documentation. if (!lineIsContinued && dataLineCount > 1) data.append(System.getProperty("line.separator")); // add the data line data.append(line); // check if the line will be continued on the next line if (line.length() == 80) lineIsContinued = true; } if (fieldName != null) { logger.info("fieldName, data: ", fieldName, ", ", data); m.setProperty(fieldName, data.toString()); } } } } } catch (CDKException cdkexc) { throw cdkexc; } catch (Exception exception) { String error = "Error while parsing SDF"; logger.error(error); logger.debug(exception); throw new CDKException(error, exception); } try { input.close(); } catch (Exception exc) { String error = "Error while closing file: " + exc.getMessage(); logger.error(error); throw new CDKException(error, exc); } chemFile.addChemSequence(chemSequence); return chemFile; }