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

IsotopePatternGenerator.java

/* $Revision$ $Author$ $Date$
 *
 * Copyright (C) 2007  Miguel Rojasch <miguelrojasch@users.sf.net>
 * 
 * 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.
 * 
 * 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.formula;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.config.IsotopeFactory;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.interfaces.IIsotope;
import org.openscience.cdk.interfaces.IMolecularFormula;
import org.openscience.cdk.tools.LoggingTool;
import org.openscience.cdk.tools.manipulator.MolecularFormulaManipulator;

/**
 * Generates all Combinatorial chemical isotopes given a structure.
 * 
 * @cdk.module  formula
 * @author      Miguel Rojas Cherto
 * @cdk.created 2007-11-20
 * @cdk.githash
 *
 * @cdk.keyword isotope pattern
 * 
 */
@TestClass("org.openscience.cdk.formula.IsotopePatternGeneratorTest")
00047 public class IsotopePatternGenerator{

      private IChemObjectBuilder builder = null;
      private IsotopeFactory isoFactory;
      private IsotopePattern abundance_Mass = null;
      
      private LoggingTool logger = new LoggingTool(IsotopePatternGenerator.class);
      
      /** Minimal abundance of the isotopes to be added in the combinatorial search.*/
00056       private double minAbundance = .1;

      /**
       *  Constructor for the IsotopeGenerator.
       */
00061       public IsotopePatternGenerator(){
            this(0.1);
      }
      
      /**
       * Constructor for the IsotopeGenerator.
       * 
       * @param minAb Minimal abundance of the isotopes to be added 
       *                      in the combinatorial search
       * 
       */
00072       public IsotopePatternGenerator(double minAb){
            minAbundance = minAb;
            logger.info("Generating all Isotope structures with IsotopeGenerator");
      }
      /**
       * Get all combinatorial chemical isotopes given a structure. 
       * 
       * @param molFor  The IMolecularFormula to start
       * @return        A IsotopePattern object containing the different combinations
       */
00082       public IsotopePattern getIsotopes(IMolecularFormula molFor){
      
            if(builder==null){
                  try {
                        isoFactory = IsotopeFactory.getInstance(molFor.getBuilder());
                        builder = molFor.getBuilder();
                  } catch (Exception e) {
                        e.printStackTrace();
                  }
            }
      String mf = MolecularFormulaManipulator.getString(molFor,true);
      
            // Divide the chemical formula into tokens (element and coefficients)
            HashMap<String, Integer> tokens = new HashMap<String, Integer>();
            IMolecularFormula molecularFormula = MolecularFormulaManipulator.getMajorIsotopeMolecularFormula(mf, builder);
            for(IIsotope isos :molecularFormula.isotopes())
                  tokens.put(isos.getSymbol(), molecularFormula.getIsotopeCount(isos));

            int atomCount;
            for(IIsotope isos : molecularFormula.isotopes()){
                  String elementSymbol = isos.getSymbol();
                  atomCount = tokens.get(elementSymbol);
                  
                  for (int i = 0; i < atomCount; i++) {
                        if (!calculateAbundanceAndMass(elementSymbol)) {
                        }
                  }
            }
            
            IsotopePattern isoP = IsotopePatternManipulator.sortAndNormalizedByIntensity(abundance_Mass);
            isoP = cleanAbundance(isoP, minAbundance);
            IsotopePattern isoPattern = IsotopePatternManipulator.sortByMass(isoP);
      
            return isoPattern;

      }
      /**
       * Calculates the mass and abundance of all isotopes generated by adding one
       * atom. Receives the periodic table element and calculate the isotopes, if
       * there exist a previous calculation, add these new isotopes. In the
       * process of adding the new isotopes, remove those that has an abundance
       * less than setup parameter minAbundance, and remove duplicated masses.
       * 
       * @param elementSymbol  The chemical element symbol
       * @return               
       */
00128       private boolean calculateAbundanceAndMass(String elementSymbol) {

            IIsotope[] isotopes = isoFactory.getIsotopes(elementSymbol);

            if (isotopes == null)
                  return false;

            if (isotopes.length == 0)
                  return false;

            double mass, previousMass, abundance, totalAbundance, newAbundance;

            HashMap<Double, Double> isotopeMassAndAbundance = new HashMap<Double, Double>();
            IsotopePattern currentISOPattern = new IsotopePattern();

            // Generate isotopes for the current atom (element)
            for (int i = 0; i < isotopes.length; i++) {
                  mass = isotopes[i].getExactMass();
                  abundance = isotopes[i].getNaturalAbundance();
                  currentISOPattern.addIsotope(new IsotopeContainer(mass, abundance));
            }

            
            // Verify if there is a previous calculation. If it exists, add the new
            // isotopes
            if (abundance_Mass == null) {

                  abundance_Mass = currentISOPattern;
                  return true;

            } else {
                  for (int i = 0; i < abundance_Mass.getNumberOfIsotopes(); i++) {
                        totalAbundance = abundance_Mass.getIsotopes().get(i).getIntensity();

                        if (totalAbundance == 0)
                              continue;

                        for (int j = 0; j < currentISOPattern.getNumberOfIsotopes(); j++) {

                              abundance = currentISOPattern.getIsotopes().get(j).getIntensity();
                              mass = abundance_Mass.getIsotopes().get(i).getMass();

                              if (abundance == 0)
                                    continue;

                              newAbundance = totalAbundance * abundance * 0.01f;
                              mass += currentISOPattern.getIsotopes().get(j).getMass();

                              // Filter duplicated masses
                              previousMass = searchMass(isotopeMassAndAbundance.keySet(),
                                          mass);
                              if (isotopeMassAndAbundance.containsKey(previousMass)) {
                                    newAbundance += isotopeMassAndAbundance
                                                .get(previousMass);
                                    mass = previousMass;
                              }

                              // Filter isotopes too small
                              if (isNotZero(newAbundance)) {
                                    isotopeMassAndAbundance.put(mass, newAbundance);
                              }
                              previousMass = 0;
                        }
                  }

                  Iterator<Double> itr = isotopeMassAndAbundance.keySet().iterator();
                  int i = 0;
                  abundance_Mass = new IsotopePattern();
                  while (itr.hasNext()) {
                        mass = itr.next();
                        abundance_Mass.addIsotope(new IsotopeContainer(mass, isotopeMassAndAbundance.get(mass)));
                        i++;
                  }
            }

            return true;

      }

      /**
       * Search the key mass in this Set.
       * 
       * @param keySet  The Set object
       * @param mass    The mass to look for
       * @return        The key value
       */
00214       private double searchMass(Set<Double> keySet, double mass) {
            double TOLERANCE = 0.00005f;
            double diff;
            for (double key : keySet) {
                  diff = Math.abs(key - mass);
                  if (diff < TOLERANCE)
                        return key;
            }

            return 0.0d;
      }

      /**
       * Detection if the value is zero.
       * 
       * @param number The number to analyze
       * @return       TRUE, if it zero
       */
00232       private boolean isNotZero(double number) {
            double pow = (double) Math.pow(10, 6);
            int fraction = (int) (number * pow);

            if (fraction <= 0)
                  return false;

            return true;
      }

      /**
       * Normalize the intensity (relative abundance) of all isotopes in relation
       * of the most abundant isotope.
       * 
       * @param isopattern   The IsotopePattern object
       * @param minAbundance The minimum abundance
       * @return             The IsotopePattern cleaned
       */
00250       private IsotopePattern cleanAbundance(IsotopePattern isopattern,
                  double minAbundance) {

            double intensity, biggestIntensity = 0.0f;

            for (IsotopeContainer sc : isopattern.getIsotopes()) {

                  intensity = sc.getIntensity();
                  if (intensity > biggestIntensity)
                        biggestIntensity = intensity;

            }

            for (IsotopeContainer sc : isopattern.getIsotopes()) {

                  intensity = sc.getIntensity();
                  intensity /= biggestIntensity;
                  if (intensity < 0)
                        intensity = 0;

                  sc.setIntensity(intensity);

            }

            IsotopePattern sortedIsoPattern = new IsotopePattern();
            sortedIsoPattern.setMonoIsotope(new IsotopeContainer(isopattern.getIsotopes().get(0).getMass(),isopattern.getIsotopes().get(0).getIntensity()));
            for (int i = 1; i < isopattern.getNumberOfIsotopes();i++) {
                  if (isopattern.getIsotopes().get(i).getIntensity() >= (minAbundance ))
                        sortedIsoPattern.addIsotope(new IsotopeContainer(isopattern.getIsotopes().get(i).getMass(),isopattern.getIsotopes().get(i).getIntensity()));
            }
            return sortedIsoPattern;

      }
}

Generated by  Doxygen 1.6.0   Back to index