📄 mfanalyser.java
字号:
/* $Revision: 8197 $ $Author: egonw $ $Date: 2007-04-15 11:06:53 +0200 (Sun, 15 Apr 2007) $ * * Copyright (C) 1997-2007 The Chemistry Development Kit (CDK) project * * Contact: cdk-devel@lists.sourceforge.net * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * All we ask is that proper credit is given for our work, which includes * - but is not limited to - adding the above copyright notice to the beginning * of your source code files, and to any copyright notice that you may distribute * with programs based on this work. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */package org.openscience.cdk.tools;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.SortedMap;import java.util.TreeMap;import java.util.TreeSet;import org.openscience.cdk.config.AtomTypeFactory;import org.openscience.cdk.config.IsotopeFactory;import org.openscience.cdk.exception.CDKException;import org.openscience.cdk.interfaces.IAtom;import org.openscience.cdk.interfaces.IAtomContainer;import org.openscience.cdk.interfaces.IAtomType;import org.openscience.cdk.interfaces.IBond;import org.openscience.cdk.interfaces.IElement;import org.openscience.cdk.interfaces.IIsotope;import org.openscience.cdk.interfaces.IMolecule;import org.openscience.cdk.tools.manipulator.AtomContainerManipulator;/** * Analyses a molecular formula given in String format and builds * an AtomContainer with the Atoms in the molecular formula. * * About implict H handling: By default the methods to calculate formula, natural and canonical mass * use the explicit Hs and only the explicit Hs if there is at least one in the molecule, implicit Hs are * ignored. If there is no explicit H and only then the implicit Hs are used. If you use the constructor * MFAnalyser(IAtomContainer ac, boolean useboth) and set useboth to true, all explicit Hs and all implicit Hs are used, * the implicit ones also on atoms with explicit Hs. * * @author seb * @cdk.created 13. April 2005 * @cdk.module standard * @cdk.keyword molecule, molecular mass * @cdk.keyword molecule, molecular formula * @cdk.keyword molecule, double bond equivalents * @cdk.bug 1647096 */public class MFAnalyser { private final static String H_ELEMENT_SYMBOL = "H"; private String MF; private IAtomContainer atomContainer; private int HCount = 0; static HashMap massMap=new HashMap(); private boolean useboth=false; private LoggingTool logger = new LoggingTool(MFAnalyser.class); static{ massMap.put("1","1.00794"); massMap.put("2","4.002602"); massMap.put("3","6.941"); massMap.put("4","9.012182"); massMap.put("5","10.811"); massMap.put("6","12.0107"); massMap.put("7","14.0067"); massMap.put("8","15.9994"); massMap.put("9","18.9984032"); massMap.put("10","20.1797"); massMap.put("11","22.989770"); massMap.put("12","24.3050"); massMap.put("13","26.981538"); massMap.put("14","28.0855"); massMap.put("15","30.973761"); massMap.put("16","32.065"); massMap.put("17","35.453"); massMap.put("18","39.948"); massMap.put("19","39.0983"); massMap.put("20","40.078"); massMap.put("21","44.955910"); massMap.put("22","47.867"); massMap.put("23","50.9415"); massMap.put("24","51.9961"); massMap.put("25","54.938049"); massMap.put("26","55.845"); massMap.put("27","58.933200"); massMap.put("28","58.6934"); massMap.put("29"," 63.546"); massMap.put("30","65.409"); massMap.put("31","69.723"); massMap.put("32","72.64"); massMap.put("33","74.92160"); massMap.put("34","78.96"); massMap.put("35","79.904"); massMap.put("36","83.798"); massMap.put("37","85.4678"); massMap.put("38","87.62"); massMap.put("39","88.90585"); massMap.put("40","91.224"); massMap.put("41","92.90638"); massMap.put("42","95.94"); massMap.put("43","98"); massMap.put("44","101.07"); massMap.put("45","102.90550"); massMap.put("46","106.42"); massMap.put("47","107.8682"); massMap.put("48","112.411"); massMap.put("49","114.818"); massMap.put("50","118.710"); massMap.put("51","121.760"); massMap.put("52","127.60"); massMap.put("53","126.90447"); massMap.put("54","131.293"); massMap.put("55","132.90545"); massMap.put("56","137.327"); massMap.put("57","138.9055"); massMap.put("58","140.116"); massMap.put("59","140.90765"); massMap.put("60","144.24"); massMap.put("61","145"); massMap.put("62","150.36"); massMap.put("63","151.964"); massMap.put("64","157.25"); massMap.put("65","158.92534"); massMap.put("66","162.500"); massMap.put("67","164.93032"); massMap.put("68","167.259"); massMap.put("69","168.93421"); massMap.put("70","173.04"); massMap.put("71","174.967"); massMap.put("72","178.49"); massMap.put("73","180.9479"); massMap.put("74","183.84"); massMap.put("75","186.207"); massMap.put("76","190.23"); massMap.put("77","192.217"); massMap.put("78","195.078"); massMap.put("79","196.96655"); massMap.put("80","200.59"); massMap.put("81","204.3833"); massMap.put("82","207.2"); massMap.put("83","208.98038"); massMap.put("84","209"); massMap.put("85","210"); massMap.put("86","222"); massMap.put("87","223"); massMap.put("88","226"); massMap.put("89","227"); massMap.put("90","232.0381"); massMap.put("91","231.03588"); massMap.put("92","238.02891"); massMap.put("93","237"); massMap.put("94","244"); massMap.put("95","243"); massMap.put("96","247"); massMap.put("97","247"); massMap.put("98","251"); massMap.put("99","252"); massMap.put("100","257"); massMap.put("101","258"); massMap.put("102","259"); massMap.put("103","262"); massMap.put("104","261"); massMap.put("105","262"); massMap.put("106","266"); massMap.put("107","264"); massMap.put("108","277"); massMap.put("109","268"); massMap.put("110","281"); massMap.put("111","272"); massMap.put("112","285"); massMap.put("113","284"); massMap.put("114","289"); massMap.put("115","288"); massMap.put("116","292"); } /** * Construct an instance of MFAnalyser, initialized with a molecular * formula string. The string is immediatly analysed and a set of Nodes * is built based on this analysis * * @param MF Description of the Parameter * @param target TODO */ public MFAnalyser(String MF, IAtomContainer target) { this.MF = MF; this.atomContainer = analyseMF(MF, target); } /** * Construct an instance of MFAnalyser, initialized with a set of Nodes * The set is analysed and a molecular formular is constructed * based on this analysis * * @param ac Description of the Parameter */ public MFAnalyser(IAtomContainer ac) { this(ac,false); } /** * Construct an instance of MFAnalyser, initialized with a set of Nodes * The set is analysed and a molecular formular is constructed * based on this analysis * * @param ac Description of the Parameter * @param useboth true=implicit and explicit hs will be used, false=explicit used, implicit only if no explicit */ public MFAnalyser(IAtomContainer ac, boolean useboth) { this.useboth=useboth; this.atomContainer = ac; this.MF = analyseAtomContainer(ac); } /** * returns the complete set of Nodes, as implied by the molecular * formula, including all the hydrogens. * * @return The atomContainer value */ public IAtomContainer getAtomContainer() { return atomContainer; } /** * Returns the complete set of Nodes, as implied by the molecular * formula, including all the hydrogens. * * @return The molecularFormula value * @see #getHTMLMolecularFormula() */ public String getMolecularFormula() { return MF; } /** * Returns the string representation of the molecule formula with * numbers wrapped in <sub></sub> tags. Useful for displaying * formulae in Swing components or on the web. * * @return A HTML representation of the molecular formula. */ public String getHTMLMolecularFormula() { boolean lastCharacterWasDigit = false; boolean currentCharacterIsDigit; StringBuffer htmlString = new StringBuffer(MF); for (int characterCounter = 0; characterCounter <= htmlString.length(); characterCounter++) { try { currentCharacterIsDigit = Character.isDigit(htmlString.charAt(characterCounter)); } catch (StringIndexOutOfBoundsException oobe) { currentCharacterIsDigit = false; } if (currentCharacterIsDigit && !lastCharacterWasDigit) { //Insert an opening sub and move the counter beyond it htmlString.insert(characterCounter, "<sub>"); characterCounter += 5; } else if (lastCharacterWasDigit && !currentCharacterIsDigit) { //Insert a closing sub and move the counter beyond it htmlString.insert(characterCounter, "</sub>"); characterCounter += 6; } lastCharacterWasDigit = currentCharacterIsDigit; } return htmlString.toString(); } /** * Returns the number of double bond equivalents in this molecule. * * @return The number of DBEs * @cdk.keyword DBE * @cdk.keyword double bond equivalent */ public float getDBE() throws IOException, ClassNotFoundException, CDKException{ int valencies[]=new int[5]; AtomTypeFactory factory = AtomTypeFactory.getInstance("org/openscience/cdk/config/data/structgen_atomtypes.xml", getAtomContainer().getBuilder()); IAtomContainer ac = getAtomContainer(); for (int f = 0; f < ac.getAtomCount(); f++) { IAtomType[] types = factory.getAtomTypes(ac.getAtom(f).getSymbol()); if(types.length==0) throw new CDKException("Calculation of double bond equivalents not possible due to problems with element "+ac.getAtom(f).getSymbol()); valencies[(int)types[0].getBondOrderSum()+ac.getAtom(f).getFormalCharge()]++; } return 1 + (valencies[4]) + (valencies[3] /2) - (valencies[1] /2); } /** * returns the exact mass for a given molecular formula, using major isotope for each element. * * @return The mass value */ public float getMass() { float mass = 0; IIsotope i; IsotopeFactory si = null; try { si = IsotopeFactory.getInstance(getAtomContainer().getBuilder()); } catch (Exception exception) { System.err.println("Could not instantiate the IsotopeFactory: " + exception.getMessage()); } IAtomContainer ac = getAtomContainer(); IIsotope h = si.getMajorIsotope(H_ELEMENT_SYMBOL); for (int f = 0; f < ac.getAtomCount(); f++) { i = si.getMajorIsotope(ac.getAtom(f).getSymbol()); if (i != null) { mass += i.getExactMass(); } else { return 0; } mass += ac.getAtom(f).getHydrogenCount() * h.getExactMass(); } return mass; } /** * Gets the natural mass of this element, defined as average of masses of isotopes, weighted by abundance. * * @param element Description of the Parameter * @return The natural mass value * @exception java.io.IOException Description of the Exception * @exception ClassNotFoundException Description of the Exception */ public static double getNaturalMass(IElement element) throws java.io.IOException, ClassNotFoundException { IIsotope[] isotopes = IsotopeFactory.getInstance(element.getBuilder()).getIsotopes(element.getSymbol()); double summedAbundances = 0; double summedWeightedAbundances = 0; double getNaturalMass = 0; for (int i = 0; i < isotopes.length; i++) { summedAbundances += isotopes[i].getNaturalAbundance(); summedWeightedAbundances += isotopes[i].getNaturalAbundance() * isotopes[i].getExactMass(); getNaturalMass = summedWeightedAbundances / summedAbundances; } return getNaturalMass; } public static double getCanonicalMass(IElement element){ return Double.parseDouble((String)massMap.get(element.getAtomicNumber()+"")); } /** * returns the exact mass for a given molecular formula, using using IUPAC official masses published in Pure Appl. Chem., (2003) 75, 1107-1122. * * @return The naturalMass value * @exception java.io.IOException Description of the Exception * @exception ClassNotFoundException Description of the Exception */ public float getCanonicalMass() throws java.io.IOException, ClassNotFoundException { float mass = 0; IsotopeFactory si = null; try { si = IsotopeFactory.getInstance(getAtomContainer().getBuilder()); } catch (Exception exception) { System.err.println("Could not instantiate the IsotopeFactory: " + exception.getMessage()); } IAtomContainer ac = getAtomContainer(); IIsotope h = si.getMajorIsotope("H"); Map symbols=this.getSymolMap(ac); Iterator it = symbols.keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); if (key.equals("H")){ if(useboth){ mass += getCanonicalMass(h)*HCount; }else{ if (symbols.get(key) != null) { mass += getCanonicalMass(h)*((Integer)symbols.get(key)).intValue(); } else { mass += getCanonicalMass(h)*HCount; } } }else{ IElement i = si.getElement(key); mass += getCanonicalMass(i)*((Integer)symbols.get(key)).intValue(); } } return mass; } /** * returns the exact mass for a given molecular formula, using weighted average of isotopes. * * @return The naturalMass value * @exception java.io.IOException Description of the Exception * @exception ClassNotFoundException Description of the Exception */ public float getNaturalMass() throws java.io.IOException, ClassNotFoundException { float mass = 0; IsotopeFactory si = null; try { si = IsotopeFactory.getInstance(getAtomContainer().getBuilder()); } catch (Exception exception) { System.err.println("Could not instantiate the IsotopeFactory: " + exception.getMessage()); } IAtomContainer ac = getAtomContainer(); IIsotope h = si.getMajorIsotope("H"); Map symbols=this.getSymolMap(ac); Iterator it = symbols.keySet().iterator(); while (it.hasNext()) { String key = (String)it.next(); if (key.equals("H")){ if(useboth){ mass += this.getNaturalMass(h)*HCount; }else{ if (symbols.get(key) != null) { mass += getNaturalMass(h)*((Integer)symbols.get(key)).intValue(); } else { mass += getNaturalMass(h)*HCount;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -