📄 mdlreader.java
字号:
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; } /** * Read a Molecule from a file in MDL sd format * *@return The Molecule that was read from the MDL file. */ private IMolecule readMolecule(IMolecule molecule) throws CDKException { 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) { stereo = java.lang.Integer.valueOf(line.substring(9,12).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); } } } 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; } public void close() throws IOException { input.close(); } private void initIOSettings() { forceReadAs3DCoords = new BooleanIOSetting("ForceReadAs3DCoordinates", IOSetting.LOW, "Should coordinates always be read as 3D?", "false"); } public void customizeJob() { fireIOSettingQuestion(forceReadAs3DCoords); } public IOSetting[] getIOSettings() { IOSetting[] settings = new IOSetting[1]; settings[0] = forceReadAs3DCoords; return settings; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -