Logo Search packages:      
Sourcecode: cdk version File versions

AtomTypeFactory.java

/*  $RCSfile$
 *  $Author: egonw $
 *  $Date: 2007-01-04 18:46:10 +0100 (Thu, 04 Jan 2007) $
 *  $Revision: 7636 $
 *
 *  Copyright (C) 2001-2007  Christoph Steinbeck <steinbeck@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.config;

import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.exception.NoSuchAtomTypeException;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomType;
import org.openscience.cdk.interfaces.IChemObjectBuilder;
import org.openscience.cdk.interfaces.IPseudoAtom;
import org.openscience.cdk.tools.LoggingTool;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

/**
 *  General class for defining AtomTypes. This class itself does not define the
 *  items types; for this classes implementing the AtomTypeConfiguration
 *  interface are used.
 *
 *  <p>To see which AtomTypeConfigurator's CDK provides, one should check the
 *  AtomTypeConfigurator API.
 *
 *  <p>The AtomTypeFactory is a singleton class, which means that there exists
 *  only one instance of the class. Well, almost. For each atom type table,
 *  there is one AtomTypeFactory instance. An instance of this class is
 *  obtained with:
 *  <pre>
 *  AtomTypeFactory factory = AtomTypeFactory.getInstance(someChemObjectBuilder);
 *  </pre>
 *  For each atom type list a separate AtomTypeFactory is instantiated.
 *
 *  <p>To get all the atom types of an element from a specific list, this 
 *  code can be used:
 *  <pre>
 *  AtomTypeFactory factory = AtomTypeFactory.getInstance(
 *    "org/openscience/cdk/config/data/jmol_atomtypes.txt",
      someChemObjectBuilder
 *  );
 *  AtomType[] types = factory.getAtomTypes("C");
 *  </pre>
 *
 * @cdk.module core
 *
 * @author     steinbeck
 * @cdk.created    2001-08-29
 * @cdk.keyword    atom, type
 * @see        IAtomTypeConfigurator
 */
00075 public class AtomTypeFactory {

    /**
     *  Used as an ID to describe the atom type.
     */
00080     public final static String ATOMTYPE_ID_STRUCTGEN = "structgen";
    /**
     *  Used as an ID to describe the atom type.
     */
00084     public final static String ATOMTYPE_ID_MODELING = "modeling";
    // these are not available
    /**
     *  Used as an ID to describe the atom type.
     */
00089     public final static String ATOMTYPE_ID_JMOL = "jmol";
    
    private final static String TXT_EXTENSION = "txt";
    private final static String XML_EXTENSION = "xml";
    
    private static LoggingTool logger;
    private static Hashtable tables = null;
    private List atomTypes = null;

      /**
       * Private constructor for the AtomTypeFactory singleton.
       *
       *
       */
00103     private AtomTypeFactory(String configFile, IChemObjectBuilder builder) {
        if (logger == null) {
            logger = new LoggingTool(this);
        }
        atomTypes = new ArrayList(100);
        readConfiguration(configFile, builder);
    }

      /**
       * Private constructor for the AtomTypeFactory singleton.
       *
       */
00115     private AtomTypeFactory(InputStream ins, String format, IChemObjectBuilder builder) {
        if (logger == null) {
            logger = new LoggingTool(this);
        }
        atomTypes = new ArrayList(100);
        readConfiguration(ins, format, builder);
    }

    /**
     * Method to create a default AtomTypeFactory, using the given InputStream.
     * An AtomType of this kind is not cached.
     *
     * @see #getInstance(String, IChemObjectBuilder)
     * @param  ins                    InputStream containing the data
     * @param  format                 String representing the possible formats ('xml' and 'txt')
     * @param  builder                IChemObjectBuilder used to make IChemObject instances
     * @return                        The AtomTypeFactory for the given data file
     */
00133     public static AtomTypeFactory getInstance(InputStream ins, String format, IChemObjectBuilder builder) {
        return new AtomTypeFactory(ins, format, builder);
    }

    /**
     * Method to create a default AtomTypeFactory, using the structgen atom type list.
     *
     * @see #getInstance(String, IChemObjectBuilder)
     * @param  builder                IChemObjectBuilder used to make IChemObject instances
     * @return                        The AtomTypeFactory for the given data file
     */
00144     public static AtomTypeFactory getInstance(IChemObjectBuilder builder) {
        return getInstance("org/openscience/cdk/config/data/structgen_atomtypes.xml", builder);
    }

    /**
     * Method to create a specialized AtomTypeFactory. Available lists in CDK are:
     * <ul>
     *  <li>org/openscience/cdk/config/data/jmol_atomtypes.txt
     *  <li>org/openscience/cdk/config/data/mol2_atomtypes.xml
     *  <li>org/openscience/cdk/config/data/structgen_atomtypes.xml
     *  <li>org/openscience/cdk/config/data/valency_atomtypes.xml
     *  <li>org/openscience/cdk/config/data/mm2_atomtypes.xml
     *  <li>org/openscience/cdk/config/data/mmff94_atomtypes.xml
     * </ul>
     *
     * @param  configFile             String the name of the data file
     * @param  builder                IChemObjectBuilder used to make IChemObject instances
     * @return                        The AtomTypeFactory for the given data file
     */
00163     public static AtomTypeFactory getInstance(String configFile, IChemObjectBuilder builder) {
        if (tables == null) {
            tables = new Hashtable();
        }
        if (!(tables.containsKey(configFile))) {
            tables.put(configFile, new AtomTypeFactory(configFile, builder));
        }
        return (AtomTypeFactory)tables.get(configFile);
    }

      /**
       * Read the config from a text file.
       *
       * @param  fileName  name of the config file
     * @param  builder     IChemObjectBuilder used to make IChemObject instances
       */
00179       private void readConfiguration(String fileName, IChemObjectBuilder builder)
      {
            logger.info("Reading config file from ", fileName);

            InputStream ins;
            {
                  //try to see if this is a resource
                  ins = this.getClass().getClassLoader().getResourceAsStream(fileName);
                  if(ins==null){
                        // try to see if this configFile is an actual file
                        File file = new File(fileName);
                  if (file.exists()) {
                      logger.debug("configFile is a File");
                      // what's next?
                      try {
                          ins = new FileInputStream(file);
                      } catch (Exception exception) {
                          logger.error(exception.getMessage());
                          logger.debug(exception);
                      }
                  } else {
                        logger.error("no stream and no file");
                  }
            }
            }

        String format = XML_EXTENSION;
        if (fileName.endsWith(TXT_EXTENSION)) {
            format = TXT_EXTENSION;
        } else if (fileName.endsWith(XML_EXTENSION)) {
            format = XML_EXTENSION;
        }
        readConfiguration(ins, format, builder);
    }
    
    private IAtomTypeConfigurator constructConfigurator(String format) {
        try {
            if (format.equals(TXT_EXTENSION)) {
                return (IAtomTypeConfigurator) this.getClass().getClassLoader().
                    loadClass("org.openscience.cdk.config.TXTBasedAtomTypeConfigurator").
                    newInstance();
            } else if (format.equals(XML_EXTENSION)) {
                return (IAtomTypeConfigurator) this.getClass().getClassLoader().
                 loadClass("org.openscience.cdk.config.CDKBasedAtomTypeConfigurator").
                 newInstance();
            }
            } catch (Exception exc) {
                  logger.error("Could not get instance of AtomTypeConfigurator for format ", format);
            logger.debug(exc);
            }
        return null;
    }
    
    private void readConfiguration(InputStream ins, String format, IChemObjectBuilder builder) {
      IAtomTypeConfigurator atc = constructConfigurator(format);
            if (atc != null) {
                  atc.setInputStream(ins);
                  try
                  {
                        atomTypes = atc.readAtomTypes(builder);
                  } catch (Exception exc)
                  {
                        logger.error("Could not read AtomType's from file due to: ", exc.getMessage());
                logger.debug(exc);
                  }
            } else
            {
                  logger.debug("AtomTypeConfigurator was null!");
                  atomTypes = new ArrayList();
            }
      }


      /**
       * Returns the number of atom types in this list.
       *
       * @return    The number of atom types
       */
00257       public int getSize()
      {
            return atomTypes.size();
      }


      /**
       * Get an AtomType with the given ID.
       *
       * @param  identifier                   an ID for a particular atom type (like C$)
       * @return                              The AtomType for this id
       * @exception  NoSuchAtomTypeException  Thrown if the atom type does not exist.
       */
00270       public IAtomType getAtomType(String identifier) throws NoSuchAtomTypeException
      {
            IAtomType atomType;
            for (int f = 0; f < atomTypes.size(); f++)
            {
                  atomType = (IAtomType) atomTypes.get(f);
                  if (atomType.getAtomTypeName().equals(identifier)) {
                        return atomType;
                  }
            }
            throw new NoSuchAtomTypeException("The AtomType " + identifier + " could not be found");
      }


      /**
       * Get an array of all atomTypes known to the AtomTypeFactory for the given
       * element symbol and atomtype class.
       *
       * @param  symbol  An element symbol to search for
       * @return         An array of atomtypes that matches the given element symbol
       *                 and atomtype class
       */
00292       public IAtomType[] getAtomTypes(String symbol)
      {
        logger.debug("Request for atomtype for symbol ", symbol);
        List atomList = new ArrayList();
        IAtomType atomType;
        for (int f = 0; f < atomTypes.size(); f++)
        {
            atomType = (IAtomType) atomTypes.get(f);
            // logger.debug("  does symbol match for: ", atomType);
            if (atomType.getSymbol().equals(symbol)) {
                // logger.debug("Atom type found for symbol: ", atomType);
                  IAtomType clone;
                        try {
                              clone = (IAtomType)atomType.clone();
                      atomList.add(clone);
                        } catch (CloneNotSupportedException e) {
                              logger.error("Could not clone IAtomType: ", e.getMessage());
                              logger.debug(e);
                        }
            }
        }
        IAtomType[] atomTypes = (IAtomType[])atomList.toArray(new IAtomType[atomList.size()]);
        if (atomTypes.length > 0)
            logger.debug("Atomtype for symbol ", symbol, " has this number of types: " + atomTypes.length);
        else
            logger.debug("No atomtype for symbol ", symbol);
        return atomTypes;
      }


      /**
       * Gets the allAtomTypes attribute of the AtomTypeFactory object.
       *
       * @return    The allAtomTypes value
       */
00327       public IAtomType[] getAllAtomTypes()
      {
            logger.debug("Returning list of size: ", getSize());
            List atomtypeList = new ArrayList();
            IAtomType atomType;
            for (int f = 0; f < atomTypes.size(); f++)
            {
                  try {
                atomType = (IAtomType) ((IAtomType) atomTypes.get(f)).clone();
                        atomtypeList.add(atomType);
                  } catch (CloneNotSupportedException e) {
                        logger.error("Could not clone IAtomType: ", e.getMessage());
                        logger.debug(e);
                  }
            }
            return (IAtomType[])atomtypeList.toArray(new IAtomType[atomtypeList.size()]);
      }


      /**
       * Configures an atom. Finds the correct element type by looking at the Atom's
       * atom type name, and if that fails, picks the first atom type matching
     * the Atom's element symbol..
       *
       * @param  atom  The atom to be configured
       * @return       The configured atom
       * @throws       CDKException when it could not recognize and configure the 
       *               IAtom
       */
00356     public IAtom configure(IAtom atom) throws CDKException {
        if (atom instanceof IPseudoAtom) {
            // do not try to configure PseudoAtom's
            return atom;
        }
        try {
            IAtomType atomType;
            String atomTypeName = atom.getAtomTypeName();
            if (atomTypeName == null || atomTypeName.length() == 0) {
                logger.debug("Using atom symbol because atom type name is empty...");
                IAtomType[] types = getAtomTypes(atom.getSymbol());
                if (types.length > 0) {
                    logger.warn("Taking first atom type, but other may exist");
                    atomType = types[0];
                } else {
                    String message = "Could not configure atom with unknown ID: " +
                        atom.toString() + " + (id=" + atom.getAtomTypeName() + ")";
                    logger.warn(message);
                    throw new CDKException(message);
                }
            } else {
                atomType = getAtomType(atom.getAtomTypeName());
            }
            logger.debug("Configuring with atomtype: ", atomType);
            atom.setSymbol(atomType.getSymbol());
            atom.setMaxBondOrder(atomType.getMaxBondOrder());
            atom.setBondOrderSum(atomType.getBondOrderSum());
            atom.setVanderwaalsRadius(atomType.getVanderwaalsRadius());
            atom.setCovalentRadius(atomType.getCovalentRadius());
            atom.setHybridization(atomType.getHybridization());
            Object color = atomType.getProperty("org.openscience.cdk.renderer.color");
            if (color != null) {
                atom.setProperty("org.openscience.cdk.renderer.color", color);
            }
            if (atomType.getAtomicNumber() != 0) {
                atom.setAtomicNumber(atomType.getAtomicNumber());
            } else {
                logger.debug("Did not configure atomic number: AT.an=", atomType.getAtomicNumber());
            }
            if (atomType.getExactMass() > 0.0) {
                atom.setExactMass(atomType.getExactMass());
            } else {
                logger.debug("Did not configure mass: AT.mass=", atomType.getAtomicNumber());
            }
        } catch (Exception exception) {
            logger.warn("Could not configure atom with unknown ID: ", atom,
                        " + (id=", atom.getAtomTypeName(), ")");
            logger.debug(exception);
            throw new CDKException(exception.toString());
        }
        logger.debug("Configured: ", atom);
        return atom;
    }
}


Generated by  Doxygen 1.6.0   Back to index