/**
  * 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;
  }
示例#3
0
  /**
   * 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;
  }