Logo Search packages:      
Sourcecode: cdk version File versions  Download package

IMolecule org::openscience::cdk::io::MDLV2000Reader::readMolecule ( IMolecule  molecule  )  throws CDKException [inline, private]

Read a Molecule from a file in MDL sd format

Returns:
The Molecule that was read from the MDL file.

Definition at line 295 of file MDLV2000Reader.java.

References org::openscience::cdk::tools::LoggingTool::debug(), org::openscience::cdk::tools::LoggingTool::error(), org::openscience::cdk::interfaces::IElement::getAtomicNumber(), org::openscience::cdk::interfaces::IChemObject::getBuilder(), org::openscience::cdk::interfaces::IBond::getConnectedAtom(), org::openscience::cdk::interfaces::IBond::getOrder(), org::openscience::cdk::interfaces::IAtom::getPoint2d(), org::openscience::cdk::interfaces::IAtom::getPoint3d(), org::openscience::cdk::tools::LoggingTool::info(), org::openscience::cdk::tools::LoggingTool::isDebugEnabled(), org::openscience::cdk::io::setting::BooleanIOSetting::isSet(), org::openscience::cdk::interfaces::IChemObjectBuilder::newBond(), org::openscience::cdk::interfaces::IChemObjectBuilder::newPseudoAtom(), org::openscience::cdk::interfaces::IElement::setAtomicNumber(), org::openscience::cdk::interfaces::IBond::setAtoms(), org::openscience::cdk::interfaces::IChemObject::setFlag(), org::openscience::cdk::interfaces::IAtomType::setFormalCharge(), org::openscience::cdk::interfaces::IChemObject::setID(), org::openscience::cdk::interfaces::IIsotope::setMassNumber(), org::openscience::cdk::interfaces::IBond::setOrder(), org::openscience::cdk::interfaces::IAtom::setPoint2d(), org::openscience::cdk::interfaces::IAtom::setPoint3d(), org::openscience::cdk::interfaces::IChemObject::setProperty(), and org::openscience::cdk::tools::LoggingTool::warn().

Referenced by read(), and readChemFile().

                                                                             {
        logger.debug("Reading new molecule");
        int linecount = 0;
        int atoms = 0;
        int bonds = 0;
        int atom1 = 0;
        int atom2 = 0;
        int order = 0;
        int stereo = 0;
        int RGroupCounter=1;
        int Rnumber=0;
        String [] rGroup=null;
        double x = 0.0;
        double y = 0.0;
        double z = 0.0;
        double totalZ = 0.0;
        //int[][] conMat = new int[0][0];
        //String help;
        IBond bond;
        IAtom atom;
        String line = "";
        
        try {
            logger.info("Reading header");
            line = input.readLine(); linecount++;
            if (line == null) {
                return null;
            }
            logger.debug("Line " + linecount + ": " + line);

            if (line.startsWith("$$$$")) {
                logger.debug("File is empty, returning empty molecule");
                return molecule;
            }
            if (line.length() > 0) {
                molecule.setProperty(CDKConstants.TITLE, line);
            }
            line = input.readLine(); linecount++;
            logger.debug("Line " + linecount + ": " + line);
            line = input.readLine(); linecount++;
            logger.debug("Line " + linecount + ": " + line);
            if (line.length() > 0) {
                molecule.setProperty(CDKConstants.REMARK, line);
            }
            
            logger.info("Reading rest of file");
            line = input.readLine(); linecount++;
            logger.debug("Line " + linecount + ": " + line);
            atoms = Integer.valueOf(line.substring(0,3).trim()).intValue();
            logger.debug("Atomcount: " + atoms);
            bonds = Integer.valueOf(line.substring(3,6).trim()).intValue();
            logger.debug("Bondcount: " + bonds);
            
            // read ATOM block
            logger.info("Reading atom block");
            for (int f = 0; f < atoms; f++) {
                line = input.readLine(); linecount++;
                x = new Double(line.substring( 0,10).trim()).doubleValue();
                y = new Double(line.substring(10,20).trim()).doubleValue();
                z = new Double(line.substring(20,30).trim()).doubleValue();
                totalZ += Math.abs(z); // *all* values should be zero, not just the sum
                logger.debug("Coordinates: " + x + "; " + y + "; " + z);
                String element = line.substring(31,34).trim();

                logger.debug("Atom type: ", element);
                if (IsotopeFactory.getInstance(molecule.getBuilder()).isElement(element)) {
                    atom = IsotopeFactory.getInstance(molecule.getBuilder()).configure(molecule.getBuilder().newAtom(element));
                } else {
                    logger.debug("Atom ", element, " is not an regular element. Creating a PseudoAtom.");
                    //check if the element is R
                    rGroup=element.split("^R");
                    if (rGroup.length >1){
                        try{
                              Rnumber=new Integer(rGroup[(rGroup.length-1)]).intValue();
                              RGroupCounter=Rnumber;
                        }catch(Exception ex){
                              Rnumber=RGroupCounter;
                              RGroupCounter++;
                        }
                        element="R"+Rnumber;
                    }
                    atom = molecule.getBuilder().newPseudoAtom(element);
                }

                // store as 3D for now, convert to 2D (if totalZ == 0.0) later
                atom.setPoint3d(new Point3d(x, y, z));
                
                // parse further fields
                String massDiffString = line.substring(34,36).trim();
                logger.debug("Mass difference: ", massDiffString);
                if (!(atom instanceof IPseudoAtom)) {
                    try {
                        int massDiff = Integer.parseInt(massDiffString);
                        if (massDiff != 0) {
                            IIsotope major = IsotopeFactory.getInstance(molecule.getBuilder()).getMajorIsotope(element);
                            atom.setAtomicNumber(major.getAtomicNumber() + massDiff);
                        }
                    } catch (Exception exception) {
                        logger.error("Could not parse mass difference field");
                    }
                } else {
                    logger.error("Cannot set mass difference for a non-element!");
                }
                
                
                String chargeCodeString = line.substring(36,39).trim();
                logger.debug("Atom charge code: ", chargeCodeString);
                int chargeCode = Integer.parseInt(chargeCodeString);
                if (chargeCode == 0) {
                    // uncharged species
                } else if (chargeCode == 1) {
                    atom.setFormalCharge(+3);
                } else if (chargeCode == 2) {
                        atom.setFormalCharge(+2);
                } else if (chargeCode == 3) {
                        atom.setFormalCharge(+1);
                } else if (chargeCode == 4) {
                } else if (chargeCode == 5) {
                        atom.setFormalCharge(-1);
                } else if (chargeCode == 6) {
                        atom.setFormalCharge(-2);
                } else if (chargeCode == 7) {
                        atom.setFormalCharge(-3);
                }
                
                try {
                    // read the mmm field as position 61-63
                    String reactionAtomIDString = line.substring(60,63).trim();
                    logger.debug("Parsing mapping id: ", reactionAtomIDString);
                    try {
                        int reactionAtomID = Integer.parseInt(reactionAtomIDString);
                        if (reactionAtomID != 0) {
                            atom.setID(reactionAtomIDString);
                        }
                    } catch (Exception exception) {
                        logger.error("Mapping number ", reactionAtomIDString, " is not an integer.");
                        logger.debug(exception);
                    }
                } catch (Exception exception) {
                    // older mol files don't have all these fields...
                    logger.warn("A few fields are missing. Older MDL MOL file?");
                }
                
                //shk3: This reads shifts from after the molecule. I don't think this is an official format, but I saw it frequently 80=>78 for alk
                if(line.length()>=78){
                  double shift=Double.parseDouble(line.substring(69,80).trim());
                  atom.setProperty("first shift",new Double(shift));
                }
                if(line.length()>=87){
                  double shift=Double.parseDouble(line.substring(79,87).trim());
                  atom.setProperty("second shift",new Double(shift));
                }
                
                molecule.addAtom(atom);
            }
            
            // convert to 2D, if totalZ == 0
            if (totalZ == 0.0 && !forceReadAs3DCoords.isSet()) {
                logger.info("Total 3D Z is 0.0, interpreting it as a 2D structure");
                java.util.Iterator atomsToUpdate = molecule.atoms();
                while (atomsToUpdate.hasNext()) {
                    IAtom atomToUpdate = (IAtom)atomsToUpdate.next();
                    Point3d p3d = atomToUpdate.getPoint3d();
                    atomToUpdate.setPoint2d(new Point2d(p3d.x, p3d.y));
                    atomToUpdate.setPoint3d(null);
                }
            }
            
            // read BOND block
            logger.info("Reading bond block");
            for (int f = 0; f < bonds; f++) {
                line = input.readLine(); linecount++;
                atom1 = java.lang.Integer.valueOf(line.substring(0,3).trim()).intValue();
                atom2 = java.lang.Integer.valueOf(line.substring(3,6).trim()).intValue();
                order = java.lang.Integer.valueOf(line.substring(6,9).trim()).intValue();
                if (line.length() >= 12) {
                  if (line.length() > 12) {
                        stereo = java.lang.Integer.valueOf(line.substring(9,12).trim()).intValue();
                  } else {
                        stereo = java.lang.Integer.valueOf(line.substring(9).trim()).intValue();
                  }
                } else {
                  logger.warn("Missing expected stereo field at line: " + line);
                }
                if (logger.isDebugEnabled()) {
                    logger.debug("Bond: " + atom1 + " - " + atom2 + "; order " + order);
                }
                if (stereo == 1) {
                    // MDL up bond
                    stereo = CDKConstants.STEREO_BOND_UP;
                } else if (stereo == 6) {
                    // MDL down bond
                    stereo = CDKConstants.STEREO_BOND_DOWN;
                } else if (stereo == 4) {
                    //MDL bond undefined
                    stereo = CDKConstants.STEREO_BOND_UNDEFINED;
                }
                // interpret CTfile's special bond orders
                IAtom a1 = molecule.getAtom(atom1 - 1);
                IAtom a2 = molecule.getAtom(atom2 - 1);
                if (order == 4) {
                    // aromatic bond
                    bond = molecule.getBuilder().newBond(a1, a2, CDKConstants.BONDORDER_AROMATIC, stereo);
                    // mark both atoms and the bond as aromatic
                    bond.setFlag(CDKConstants.ISAROMATIC, true);
                    a1.setFlag(CDKConstants.ISAROMATIC, true);
                    a2.setFlag(CDKConstants.ISAROMATIC, true);
                    molecule.addBond(bond);
                } else {
                    bond = molecule.getBuilder().newBond(a1, a2, (double) order, stereo);
                    molecule.addBond(bond);
                }
            }
            
            // read PROPERTY block
            logger.info("Reading property block");
            while (true) {
                line = input.readLine(); linecount++;
                if (line == null) {
                    throw new CDKException("The expected property block is missing!");
                }
            if (line.startsWith("M  END")) break;
                
                boolean lineRead = false;
                if (line.startsWith("M  CHG")) {
                    // FIXME: if this is encountered for the first time, all
                    // atom charges should be set to zero first!
                    int infoCount = Integer.parseInt(line.substring(6,9).trim());
                    StringTokenizer st = new StringTokenizer(line.substring(9));
                    for (int i=1; i <= infoCount; i++) {
                        String token = st.nextToken();
                        int atomNumber = Integer.parseInt(token.trim());
                        token = st.nextToken();
                        int charge = Integer.parseInt(token.trim());
                        molecule.getAtom(atomNumber - 1).setFormalCharge(charge);
                    }
                }  else if (line.matches("^A    \\d+")) {
                        // Reads the pseudo atom property from the mol file
                  
                  // The atom number of the to replaced atom
                        int aliasAtomNumber = Integer.parseInt(line.replaceFirst("^A    ", "")) - RGroupCounter;
                        line = input.readLine(); linecount++;
                              String[] aliasArray = line.split("\\\\");
                              // name of the alias atom like R1 odr R2 etc. 
                              String alias = "";
                              for (int i = 0; i < aliasArray.length; i++) {
                                    alias += aliasArray[i];
                              }
                              IAtom aliasAtom = molecule.getAtom(aliasAtomNumber);
                              IAtom newPseudoAtom = molecule.getBuilder().newPseudoAtom(alias);
                              if(aliasAtom.getPoint2d() != null) {
                                    newPseudoAtom.setPoint2d(aliasAtom.getPoint2d());
                              }
                              if(aliasAtom.getPoint3d() != null) {
                                    newPseudoAtom.setPoint3d(aliasAtom.getPoint3d());
                              }
                              molecule.addAtom(newPseudoAtom);
                              java.util.List bondsOfAliasAtom = molecule.getConnectedBondsList(aliasAtom);
                              
                              for (int i = 0; i < bondsOfAliasAtom.size(); i++) {
                                    IBond bondOfAliasAtom = (IBond) bondsOfAliasAtom.get(i);
                                    IAtom connectedToAliasAtom = bondOfAliasAtom.getConnectedAtom(aliasAtom);
                                    IBond newBond = bondOfAliasAtom.getBuilder().newBond(); 
                                    newBond.setAtoms(new IAtom[] {connectedToAliasAtom, newPseudoAtom});
                                    newBond.setOrder(bondOfAliasAtom.getOrder());
                                    molecule.addBond(newBond);
                                    molecule.removeBond(aliasAtom, connectedToAliasAtom);
                              }
                              molecule.removeAtom(aliasAtom);
                              RGroupCounter++;

                } else if (line.startsWith("M  ISO")) {
                    try {
                        String countString = line.substring(6,9).trim();
                        int infoCount = Integer.parseInt(countString);
                        StringTokenizer st = new StringTokenizer(line.substring(9));
                        for (int i=1; i <= infoCount; i++) {
                            int atomNumber = Integer.parseInt(st.nextToken().trim());
                            int absMass = Integer.parseInt(st.nextToken().trim());
                            if (absMass != 0) { 
                                IAtom isotope = molecule.getAtom(atomNumber - 1);
                                isotope.setMassNumber(absMass);
                            }
                        }
                    } catch (NumberFormatException exception) {
                        String error = "Error (" + exception.getMessage() + ") while parsing line "
                                       + linecount + ": " + line + " in property block.";
                        logger.error(error);
                        throw new CDKException("NumberFormatException in isotope information on line: " + line, exception);
                    }
                } else if (line.startsWith("M  RAD")) {
                    try {
                        String countString = line.substring(6,9).trim();
                        int infoCount = Integer.parseInt(countString);
                        StringTokenizer st = new StringTokenizer(line.substring(9));
                        for (int i=1; i <= infoCount; i++) {
                            int atomNumber = Integer.parseInt(st.nextToken().trim());
                            int spinMultiplicity = Integer.parseInt(st.nextToken().trim());
                            if (spinMultiplicity > 1) {
                                IAtom radical = molecule.getAtom(atomNumber - 1);
                                for (int j=2; j <= spinMultiplicity; j++) {
                                    // 2 means doublet -> one unpaired electron
                                    // 3 means triplet -> two unpaired electron
                                    molecule.addSingleElectron(molecule.getBuilder().newSingleElectron(radical));
                                }
                            }
                        }
                    } catch (NumberFormatException exception) {
                        String error = "Error (" + exception.getMessage() + ") while parsing line "
                                       + linecount + ": " + line + " in property block.";
                        logger.error(error);
                        throw new CDKException("NumberFormatException in radical information on line: " + line, exception);
                    }
                } else if (line.startsWith("G  ")) {
                    try {
                        String atomNumberString = line.substring(3,6).trim();
                        int atomNumber = Integer.parseInt(atomNumberString);
                        //String whatIsThisString = line.substring(6,9).trim();
                    
                        String atomName = input.readLine();
                        
                        // convert Atom into a PseudoAtom
                        IAtom prevAtom = molecule.getAtom(atomNumber - 1);
                        IPseudoAtom pseudoAtom = molecule.getBuilder().newPseudoAtom(atomName);
                        if (prevAtom.getPoint2d() != null) {
                            pseudoAtom.setPoint2d(prevAtom.getPoint2d());
                        }
                        if (prevAtom.getPoint3d() != null) {
                            pseudoAtom.setPoint3d(prevAtom.getPoint3d());
                        }
                        AtomContainerManipulator.replaceAtomByAtom(molecule, prevAtom, pseudoAtom);
                    } catch (NumberFormatException exception) {
                        String error = "Error (" + exception.toString() + ") while parsing line "
                        + linecount + ": " + line + " in property block.";
                        logger.error(error);
                        throw new CDKException("NumberFormatException in group information on line: " + line, exception);
                    }
                }
                if (!lineRead) {
                    logger.warn("Skipping line in property block: ", line);
                }
            }
            } catch (CDKException exception) {
            String error = "Error while parsing line " + linecount + ": " + line + " -> " + exception.getMessage();
            logger.error(error);
            logger.debug(exception);
            throw exception;
            } catch (Exception exception) {
                  exception.printStackTrace();
            String error = "Error while parsing line " + linecount + ": " + line + " -> " + exception.getMessage();
            logger.error(error);
            logger.debug(exception);
            throw new CDKException(error, exception);
            }
            return molecule;
      }


Generated by  Doxygen 1.6.0   Back to index