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

ModelBuilder3D.java

/*  $Revision$ $Author$ $Date$
 *
 *  Copyright (C) 2005-2007  Christian Hoppe <chhoppe@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.
 *  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.modeling.builder3d;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

import org.openscience.cdk.CDKConstants;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.exception.NoSuchAtomTypeException;
import org.openscience.cdk.geometry.GeometryTools;
import org.openscience.cdk.graph.ConnectivityChecker;
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IMolecule;
import org.openscience.cdk.interfaces.IRingSet;
import org.openscience.cdk.layout.AtomPlacer;
import org.openscience.cdk.ringsearch.RingPartitioner;
import org.openscience.cdk.tools.LoggingTool;
import org.openscience.cdk.tools.manipulator.RingSetManipulator;

/**
 *  The main class to generate the 3D coordinates of a molecule ModelBuilder3D.
 *  Its use looks like:
 *  <pre>
 *  ModelBuilder3D mb3d = ModelBuilder3D.getInstance();
 *  IMolecule molecule = mb3d.generate3DCoordinates(molecule, false);
 *  </pre>
 *
 *  <p>Standing problems:
 *  <ul>
 *    <li>condensed ring systems which are unknown for the template class 
 *    <li>vdWaals clashes
 *    <li>stereochemistry
 *    <li>chains running through ring systems
 *  </ul>
 *
 * @author      cho
 * @author      steinbeck
 * @cdk.created 2004-09-07
 * @cdk.module  builder3d
 * @cdk.githash
 * @cdk.keyword 3D coordinates
 * @cdk.keyword coordinate generation, 3D
 */
00074 public class ModelBuilder3D {

      private static Map<String,ModelBuilder3D> memyselfandi = new HashMap<String,ModelBuilder3D>();
      
      private TemplateHandler3D templateHandler = null;
            
      private Map parameterSet = null;

      private final ForceFieldConfigurator ffc = new ForceFieldConfigurator();

      String forceFieldName = "mm2";
      
      private LoggingTool logger = new LoggingTool(ModelBuilder3D.class);
      
      /**
       * Constructor for the ModelBuilder3D object.
       *     
       * @param  templateHandler  templateHandler Object
       * @param  ffname           name of force field
       */
00094       private ModelBuilder3D(TemplateHandler3D templateHandler, String ffname) throws CDKException {
            setTemplateHandler(templateHandler);
            setForceField(ffname);
      }

      public static ModelBuilder3D getInstance(TemplateHandler3D templateHandler, String ffname) throws CDKException {
            if (ffname == null || ffname.length() == 0) throw new CDKException("The given ffname is null or empty!");
            if (templateHandler == null) throw new CDKException("The given template handler is null!");
            
            String builderCode = templateHandler.getClass().getName()+ "#" + ffname;
            if (!memyselfandi.containsKey(builderCode)) {
                  ModelBuilder3D builder = new ModelBuilder3D(
                        templateHandler, ffname
                  );
                  memyselfandi.put(builderCode, builder);
                  return builder;
            }
            return memyselfandi.get(builderCode);
      }

      public static ModelBuilder3D getInstance() throws CDKException {
            return getInstance(TemplateHandler3D.getInstance(), "mm2");
      }

      /**
       * Gives a list of possible force field types.
       *
       * @return                the list
       */
00123   public String[] getFfTypes(){
    return ffc.getFfTypes();
  }


      /**
       * Sets the forceField attribute of the ModelBuilder3D object.
       *
       * @param  ffname  forceField name
       */
00133       private void setForceField(String ffname) throws CDKException {
            if (ffname == null) {
                  ffname = "mm2";
            }
            try {
                  forceFieldName = ffname;
                  ffc.setForceFieldConfigurator(ffname);
                  parameterSet = ffc.getParameterSet();
            } catch (CDKException ex1) {
                  logger.error("Problem with ForceField configuration due to>" + ex1.getMessage());
                  logger.debug(ex1);
                  throw new CDKException("Problem with ForceField configuration due to>" + ex1.getMessage(), ex1);
            }
      }


      /**
       * Generate 3D coordinates with force field information.
       */
00152       public IMolecule generate3DCoordinates(IMolecule molecule, boolean clone)
          throws CDKException, NoSuchAtomTypeException,
                 CloneNotSupportedException, IOException{
          String[] originalAtomTypeNames = new String[molecule.getAtomCount()];
          for (int i=0; i<originalAtomTypeNames.length; i++) {
              originalAtomTypeNames[i] = molecule.getAtom(i).getAtomTypeName();
          }

            logger.debug("******** GENERATE COORDINATES ********");
            for(int i=0;i<molecule.getAtomCount();i++){
                  molecule.getAtom(i).setFlag(CDKConstants.ISPLACED,false);
                  molecule.getAtom(i).setFlag(CDKConstants.VISITED,false);
            }
            //CHECK FOR CONNECTIVITY!
            logger.debug("#atoms>"+molecule.getAtomCount());
            if (!ConnectivityChecker.isConnected(molecule)) {
                  throw new CDKException("Molecule is NOT connected, could not layout.");
            }
            
            // setup helper classes
            AtomPlacer atomPlacer = new AtomPlacer();
            AtomPlacer3D ap3d = new AtomPlacer3D();
            AtomTetrahedralLigandPlacer3D atlp3d = new AtomTetrahedralLigandPlacer3D();
            ap3d.initilize(parameterSet);
            atlp3d.setParameterSet(parameterSet);
            
            if (clone) molecule = (IMolecule)molecule.clone();
            atomPlacer.setMolecule(molecule);
            
            if (ap3d.numberOfUnplacedHeavyAtoms(molecule) == 1) {
                  logger.debug("Only one Heavy Atom");
                  molecule.getAtom(0).setPoint3d(new Point3d(0.0, 0.0, 0.0));
                  try {
                        atlp3d.add3DCoordinatesForSinglyBondedLigands(molecule);
                  } catch (CDKException ex3) {
                        logger.error("PlaceSubstitutensERROR: Cannot place substitutents due to:" + ex3.getMessage());
                        logger.debug(ex3);
                        throw new CDKException("PlaceSubstitutensERROR: Cannot place substitutents due to:" + ex3.getMessage(), ex3);
                  }
                  return molecule;
            }
            //Assing Atoms to Rings,Aliphatic and Atomtype
            IRingSet ringSetMolecule = ffc.assignAtomTyps(molecule);
            List ringSystems = null;
            IRingSet largestRingSet = null;
            double NumberOfRingAtoms = 0;

            if (ringSetMolecule.getAtomContainerCount() > 0) {
                  if(templateHandler==null){
                        throw new CDKException("You are trying to generate coordinates for a molecule with rings, but you have no template handler set. Please do setTemplateHandler() before generation!");
                  }
                  ringSystems = RingPartitioner.partitionRings(ringSetMolecule);
                  largestRingSet = RingSetManipulator.getLargestRingSet(ringSystems);
                  IAtomContainer largestRingSetContainer = RingSetManipulator.getAllInOneContainer(largestRingSet);
                  NumberOfRingAtoms = (double)largestRingSetContainer.getAtomCount();
                  templateHandler.mapTemplates(largestRingSetContainer, NumberOfRingAtoms);
                  if (!checkAllRingAtomsHasCoordinates(largestRingSetContainer)) {
                        throw new CDKException("RingAtomLayoutError: Not every ring atom is placed! Molecule cannot be layout.");
                  }

                  setAtomsToPlace(largestRingSetContainer);
                  searchAndPlaceBranches(molecule, largestRingSetContainer, ap3d, atlp3d, atomPlacer);
                  largestRingSet = null;
            } else {
                  //logger.debug("****** Start of handling aliphatic molecule ******");
                  IAtomContainer ac = null;

                  ac = atomPlacer.getInitialLongestChain(molecule);
                  setAtomsToUnVisited(molecule);
                  setAtomsToUnPlaced(molecule);
                  ap3d.placeAliphaticHeavyChain(molecule, ac);
                  //ZMatrixApproach
                  ap3d.zmatrixChainToCartesian(molecule, false);
                  searchAndPlaceBranches(molecule, ac, ap3d, atlp3d, atomPlacer);
            }
            layoutMolecule(ringSystems, molecule, ap3d, atlp3d, atomPlacer);
            //logger.debug("******* PLACE SUBSTITUENTS ******");
            try {
                  atlp3d.add3DCoordinatesForSinglyBondedLigands(molecule);
            } catch (CDKException ex3) {
                  logger.error("PlaceSubstitutensERROR: Cannot place substitutents due to:" + ex3.getMessage());
                  logger.debug(ex3);
                  throw new CDKException("PlaceSubstitutensERROR: Cannot place substitutents due to:" + ex3.getMessage(), ex3);
            }
            // restore the original atom type names
    for (int i=0; i<originalAtomTypeNames.length; i++) {
        molecule.getAtom(i).setAtomTypeName(originalAtomTypeNames[i]);
    }

            return molecule;
      }



      /**
       * Gets the ringSetOfAtom attribute of the ModelBuilder3D object.
       *
       *@return              The ringSetOfAtom value
       */
00251       private IRingSet getRingSetOfAtom(List ringSystems, IAtom atom) {
            IRingSet ringSetOfAtom = null;
            for (int i = 0; i < ringSystems.size(); i++) {
                  if (((IRingSet) ringSystems.get(i)).contains(atom)) {
                        return (IRingSet) ringSystems.get(i);
                  }
            }
            return ringSetOfAtom;
      }


      /**
       * Layout the molecule, starts with ring systems and than aliphatic chains.
       *
       *@param  ringSetMolecule  ringSystems of the molecule
       */
00267       private void layoutMolecule(List ringSetMolecule, IMolecule molecule, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer) throws CDKException, IOException, CloneNotSupportedException {
            //logger.debug("****** LAYOUT MOLECULE MAIN *******");
            IAtomContainer ac = null;
            int safetyCounter = 0;
            IAtom atom = null;
            //Place rest Chains/Atoms
            do {
                  safetyCounter++;
                  atom = ap3d.getNextPlacedHeavyAtomWithUnplacedRingNeighbour(molecule);
                  if (atom != null) {
                        //logger.debug("layout RingSystem...");
                        IAtom unplacedAtom = ap3d.getUnplacedRingHeavyAtom(molecule, atom);
                        IRingSet ringSetA = getRingSetOfAtom(ringSetMolecule, unplacedAtom);
                        IAtomContainer ringSetAContainer = RingSetManipulator.getAllInOneContainer(ringSetA);
                        templateHandler.mapTemplates(ringSetAContainer, (double)ringSetAContainer.getAtomCount());

                        if (checkAllRingAtomsHasCoordinates(ringSetAContainer)) {
                        } else {
                              throw new IOException("RingAtomLayoutError: Not every ring atom is placed! Molecule cannot be layout.Sorry");
                        }

                        Point3d firstAtomOriginalCoord = unplacedAtom.getPoint3d();
                        Point3d centerPlacedMolecule = ap3d.geometricCenterAllPlacedAtoms(molecule);

                        setBranchAtom(molecule, unplacedAtom, atom, ap3d.getPlacedHeavyAtoms(molecule, atom), ap3d, atlp3d);
                        layoutRingSystem(firstAtomOriginalCoord, unplacedAtom, ringSetA, centerPlacedMolecule, atom, ap3d);
                        searchAndPlaceBranches(molecule, ringSetAContainer, ap3d, atlp3d, atomPlacer);
                        //logger.debug("Ready layout Ring System");
                        ringSetA = null;
                        unplacedAtom = null;
                        firstAtomOriginalCoord = null;
                        centerPlacedMolecule = null;
                  } else {
                        //logger.debug("layout chains...");
                        setAtomsToUnVisited(molecule);
                        atom = ap3d.getNextPlacedHeavyAtomWithUnplacedAliphaticNeighbour(molecule);
                        if (atom != null) {
                              ac = atom.getBuilder().newAtomContainer();
                              ac.addAtom(atom);
                              searchAndPlaceBranches(molecule, ac, ap3d, atlp3d, atomPlacer);
                              ac = null;
                        }
                  }
            } while (!ap3d.allHeavyAtomsPlaced(molecule) || safetyCounter > molecule.getAtomCount());
      }


      /**
       * Layout the ring system, rotate and translate the template.
       *
       *@param  originalCoord         coordinates of the placedRingAtom from the template 
       *@param  placedRingAtom        placedRingAtom
       *@param  ringSet               ring system which placedRingAtom is part of
       *@param  centerPlacedMolecule  the geometric center of the already placed molecule
       *@param  atomB                 placed neighbour atom of  placedRingAtom
       */
00323       private void layoutRingSystem(Point3d originalCoord, IAtom placedRingAtom, IRingSet ringSet, Point3d centerPlacedMolecule, IAtom atomB, AtomPlacer3D ap3d) {
            //logger.debug("****** Layout ring System ******");System.out.println(">around atom:"+molecule.getAtomNumber(placedRingAtom));
            IAtomContainer ac = RingSetManipulator.getAllInOneContainer(ringSet);
            Point3d newCoord = placedRingAtom.getPoint3d();
            Vector3d axis = new Vector3d(atomB.getPoint3d().x - newCoord.x, atomB.getPoint3d().y - newCoord.y, atomB.getPoint3d().z - newCoord.z);
            translateStructure(originalCoord, newCoord, ac);
            //Rotate Ringsystem to farthest possible point
            Vector3d startAtomVector = new Vector3d(newCoord.x - atomB.getPoint3d().x, newCoord.y - atomB.getPoint3d().y, newCoord.z - atomB.getPoint3d().z);
            IAtom farthestAtom = ap3d.getFarthestAtom(placedRingAtom.getPoint3d(), ac);
            Vector3d farthestAtomVector = new Vector3d(farthestAtom.getPoint3d().x - newCoord.x, farthestAtom.getPoint3d().y - newCoord.y, farthestAtom.getPoint3d().z - newCoord.z);
            Vector3d n1 = new Vector3d();
            n1.cross(axis, farthestAtomVector);
            n1.normalize();
            double lengthFarthestAtomVector = farthestAtomVector.length();
            Vector3d farthestVector = new Vector3d(startAtomVector);
            farthestVector.normalize();
            farthestVector.scale((startAtomVector.length() + lengthFarthestAtomVector));
            double dotProduct = farthestAtomVector.dot(farthestVector);
            double angle = Math.acos(dotProduct / (farthestAtomVector.length() * farthestVector.length()));
            Vector3d ringCenter = new Vector3d();

            for (int i = 0; i < ac.getAtomCount(); i++) {
                  if (!(ac.getAtom(i).getFlag(CDKConstants.ISPLACED))) {
                        ringCenter.x = (ac.getAtom(i).getPoint3d()).x - newCoord.x;
                        ringCenter.y = (ac.getAtom(i).getPoint3d()).y - newCoord.y;
                        ringCenter.z = (ac.getAtom(i).getPoint3d()).z - newCoord.z;
                        ringCenter = AtomTetrahedralLigandPlacer3D.rotate(ringCenter, n1, angle);
                        ac.getAtom(i).setPoint3d(
                              new Point3d(
                                    ringCenter.x + newCoord.x,
                                    ringCenter.y + newCoord.y,
                                    ringCenter.z + newCoord.z
                              )
                        );
                        //ac.getAtomAt(i).setFlag(CDKConstants.ISPLACED, true);
                  }
            }

            //Rotate Ring so that geometric center is max from placed center
            //logger.debug("Rotate RINGSYSTEM");
            Point3d pointRingCenter = GeometryTools.get3DCenter(ac);
            double distance = 0;
            double rotAngleMax = 0;
            angle = 1 / 180 * Math.PI;
            ringCenter = new Vector3d(pointRingCenter.x, pointRingCenter.y, pointRingCenter.z);
            ringCenter.x = ringCenter.x - newCoord.x;
            ringCenter.y = ringCenter.y - newCoord.y;
            ringCenter.z = ringCenter.z - newCoord.z;
            for (int i = 1; i < 360; i++) {
                  ringCenter = AtomTetrahedralLigandPlacer3D.rotate(ringCenter, axis, angle);
                  if (centerPlacedMolecule.distance(new Point3d(ringCenter.x, ringCenter.y, ringCenter.z)) > distance) {
                        rotAngleMax = i;
                        distance = centerPlacedMolecule.distance(new Point3d(ringCenter.x, ringCenter.y, ringCenter.z));
                  }
            }

            //rotate ring around axis with best angle
            rotAngleMax = (rotAngleMax / 180) * Math.PI;
            for (int i = 0; i < ac.getAtomCount(); i++) {
                  if (!(ac.getAtom(i).getFlag(CDKConstants.ISPLACED))) {
                        ringCenter.x = (ac.getAtom(i).getPoint3d()).x;
                        ringCenter.y = (ac.getAtom(i).getPoint3d()).y;
                        ringCenter.z = (ac.getAtom(i).getPoint3d()).z;
                        ringCenter = AtomTetrahedralLigandPlacer3D.rotate(ringCenter, axis, rotAngleMax);
                        ac.getAtom(i).setPoint3d(
                              new Point3d(
                                    ringCenter.x,
                                    ringCenter.y,
                                    ringCenter.z
                              )
                        );
                        ac.getAtom(i).setFlag(CDKConstants.ISPLACED, true);
                  }
            }
      }


      /**
       * Sets a branch atom to a ring or aliphatic chain.
       *
       *@param  unplacedAtom    The new branchAtom 
       *@param  atomA           placed atom to which the unplaced satom is connected
       *@param  atomNeighbours  placed atomNeighbours of atomA
       */
00407       private void setBranchAtom(IMolecule molecule, IAtom unplacedAtom, IAtom atomA, IAtomContainer atomNeighbours, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d) throws CDKException {
            //logger.debug("****** SET Branch Atom ****** >"+molecule.getAtomNumber(unplacedAtom));
            IAtomContainer noCoords = molecule.getBuilder().newAtomContainer();
            noCoords.addAtom(unplacedAtom);
            Point3d centerPlacedMolecule = ap3d.geometricCenterAllPlacedAtoms(molecule);
            IAtom atomB = atomNeighbours.getAtom(0);

        String atypeNameA = atomA.getAtomTypeName();
        String atypeNameB = atomB.getAtomTypeName();
        String atypeNameUnplaced = unplacedAtom.getAtomTypeName();

        double length = ap3d.getBondLengthValue(atypeNameA, atypeNameUnplaced);
        double angle = (ap3d.getAngleValue(atypeNameB, atypeNameA, atypeNameUnplaced)) * Math.PI / 180;
            /*
             *  System.out.println("A:"+atomA.getSymbol()+" "+atomA.getAtomTypeName()+" B:"+atomB.getSymbol()+" "+atomB.getAtomTypeName()
             *  +" unplaced Atom:"+unplacedAtom.getAtomTypeName()+" BL:"+length+" Angle:"+angle
             *  +" FormalNeighbour:"+atomA.getFormalNeighbourCount()+" HYB:"+atomA.getFlag(CDKConstants.HYBRIDIZATION_SP2)
             *  +" #Neigbhours:"+atomNeighbours.getAtomCount());
             */
            IAtom atomC = ap3d.getPlacedHeavyAtom(molecule, atomB, atomA);

            Point3d[] branchPoints = atlp3d.get3DCoordinatesForLigands(atomA, noCoords, atomNeighbours, atomC
                        , (atomA.getFormalNeighbourCount() - atomNeighbours.getAtomCount())
                        , length, angle);
            double distance = 0;
            int farthestPoint = 0;
            for (int i = 0; i < branchPoints.length; i++) {
                  if (Math.abs(branchPoints[i].distance(centerPlacedMolecule)) > Math.abs(distance)) {
                        distance = branchPoints[i].distance(centerPlacedMolecule);
                        farthestPoint = i;
                  }
            }

            int stereo = -1;
            if (atomA.getStereoParity() != CDKConstants.UNSET && atomA.getStereoParity() != 0 ||
                        (Math.abs((molecule.getBond(atomA, unplacedAtom)).getStereo()) < 2
                         && Math.abs((molecule.getBond(atomA, unplacedAtom)).getStereo()) != 0)
                         && molecule.getMaximumBondOrder(atomA) == IBond.Order.SINGLE) {
                  if (atomNeighbours.getAtomCount() > 1) {
                        stereo = atlp3d.makeStereocenter(atomA.getPoint3d(), molecule.getBond(atomA, unplacedAtom), (atomNeighbours.getAtom(0)).getPoint3d(), (atomNeighbours.getAtom(1)).getPoint3d(), branchPoints);
                  }
            }
            if (stereo != -1) {
                  farthestPoint = stereo;
            }
            unplacedAtom.setPoint3d(branchPoints[farthestPoint]);
            unplacedAtom.setFlag(CDKConstants.ISPLACED, true);
      }


      /**
       * Search and place branches of a chain or ring.
       *
       *@param  chain          AtomContainer if atoms in an aliphatic chain or ring system 
       */
00462       private void searchAndPlaceBranches(IMolecule molecule, IAtomContainer chain, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer) throws CDKException {
            //logger.debug("****** SEARCH AND PLACE ****** Chain length: "+chain.getAtomCount());
            java.util.List atoms = null;
            IAtomContainer branchAtoms = molecule.getBuilder().newAtomContainer();
            IAtomContainer connectedAtoms = molecule.getBuilder().newAtomContainer();
            for (int i = 0; i < chain.getAtomCount(); i++) {
                  atoms = molecule.getConnectedAtomsList(chain.getAtom(i));
                  for (int j = 0; j < atoms.size(); j++) {
                        IAtom atom = (IAtom)atoms.get(j);
                        if (!(atom.getSymbol()).equals("H") & !(atom.getFlag(CDKConstants.ISPLACED)) & !(atom.getFlag(CDKConstants.ISINRING))) {
                              //logger.debug("SEARCH PLACE AND FOUND Branch Atom "+molecule.getAtomNumber(chain.getAtomAt(i))+
                              //          " New Atom:"+molecule.getAtomNumber(atoms[j])+" -> STORE");
                              connectedAtoms.add(ap3d.getPlacedHeavyAtoms(molecule, chain.getAtom(i)));
                              //logger.debug("Connected atom1:"+molecule.getAtomNumber(connectedAtoms.getAtomAt(0))+" atom2:"+
                              //molecule.getAtomNumber(connectedAtoms.getAtomAt(1))+ " Length:"+connectedAtoms.getAtomCount());
                              try {
                                    setBranchAtom(molecule, atom, chain.getAtom(i), connectedAtoms, ap3d, atlp3d);
                              } catch (CDKException ex2) {
                                    logger.error("SearchAndPlaceBranchERROR: Cannot find enough neighbour atoms due to" + ex2.toString());
                                    throw new CDKException("SearchAndPlaceBranchERROR: Cannot find enough neighbour atoms: " + ex2.getMessage(), ex2);
                              }
                              branchAtoms.addAtom(atom);
                              connectedAtoms.removeAllElements();
                        }
                  }

            }//for ac.getAtomCount
            placeLinearChains3D(molecule, branchAtoms, ap3d, atlp3d, atomPlacer);
      }


      /**
       * Layout all aliphatic chains with ZMatrix.
       *
       *@param  startAtoms     AtomContainer of possible start atoms for a chain
       */
00498       private void placeLinearChains3D(IMolecule molecule, IAtomContainer startAtoms, AtomPlacer3D ap3d, AtomTetrahedralLigandPlacer3D atlp3d, AtomPlacer atomPlacer) throws CDKException {
            //logger.debug("****** PLACE LINEAR CHAINS ******");
            IAtom dihPlacedAtom = null;
            IAtom thirdPlacedAtom = null;
            IAtomContainer longestUnplacedChain = molecule.getBuilder().newAtomContainer();
            if (startAtoms.getAtomCount() == 0) {
                  //no branch points ->linear chain
                  //logger.debug("------ LINEAR CHAIN - FINISH ------");
            } else {
                  for (int i = 0; i < startAtoms.getAtomCount(); i++) {
                        //logger.debug("FOUND BRANCHED ALKAN");
                        //logger.debug("Atom NOT NULL:" + molecule.getAtomNumber(startAtoms.getAtomAt(i)));
                        thirdPlacedAtom = ap3d.getPlacedHeavyAtom(molecule, startAtoms.getAtom(i));
                        dihPlacedAtom = ap3d.getPlacedHeavyAtom(molecule, thirdPlacedAtom, startAtoms.getAtom(i));
                        longestUnplacedChain.addAtom(dihPlacedAtom);
                        longestUnplacedChain.addAtom(thirdPlacedAtom);
                        longestUnplacedChain.addAtom(startAtoms.getAtom(i));

                        longestUnplacedChain.add(atomPlacer.getLongestUnplacedChain(molecule, startAtoms.getAtom(i)));
                        setAtomsToUnVisited(molecule);
                        
                        if (longestUnplacedChain.getAtomCount() < 4) {
                              //di,third,sec
                              //logger.debug("------ SINGLE BRANCH METHYLTYP ------");
                              //break;
                        } else {
                              //logger.debug("LongestUnchainLength:"+longestUnplacedChain.getAtomCount());
                              ap3d.placeAliphaticHeavyChain(molecule, longestUnplacedChain);
                              ap3d.zmatrixChainToCartesian(molecule, true);
                              searchAndPlaceBranches(molecule, longestUnplacedChain, ap3d, atlp3d, atomPlacer);
                        }
                        longestUnplacedChain.removeAllElements();
                  }//for

            }
            //logger.debug("****** HANDLE ALIPHATICS END ******");
      }


      /**
       * Translates the template ring system to new coordinates.
       *
       *@param  originalCoord  original coordinates of the placed ring atom from template
       *@param  newCoord       new coordinates from branch placement
       *@param  ac             AtomContainer contains atoms of ring system 
       */
00544       private void translateStructure(Point3d originalCoord, Point3d newCoord, IAtomContainer ac) {
            Point3d transVector = new Point3d(originalCoord);
            transVector.sub(newCoord);
            for (int i = 0; i < ac.getAtomCount(); i++) {
                  if (!(ac.getAtom(i).getFlag(CDKConstants.ISPLACED))) {
                        ac.getAtom(i).getPoint3d().sub(transVector);
                        //ac.getAtomAt(i).setFlag(CDKConstants.ISPLACED, true);
                  }
            }
      }


      /**
       * Returns the largest (number of atoms) ring set in a molecule.
       *
       *@param  ac  AtomContainer
       *@return     boolean
       */
00562       private boolean checkAllRingAtomsHasCoordinates(IAtomContainer ac) {
            for (int i = 0; i < ac.getAtomCount(); i++) {
                  if (ac.getAtom(i).getPoint3d() != null && ac.getAtom(i).getFlag(CDKConstants.ISINRING)) {
                  } else if (!ac.getAtom(i).getFlag(CDKConstants.ISINRING)) {
                  } else {
                        return false;
                  }
            }
            return true;
      }


      /**
       * Sets the atomsToPlace attribute of the ModelBuilder3D object.
       *
       *@param  ac  The new atomsToPlace value
       */
00579       private void setAtomsToPlace(IAtomContainer ac) {
            for (int i = 0; i < ac.getAtomCount(); i++) {
                  ac.getAtom(i).setFlag(CDKConstants.ISPLACED, true);
            }
      }


      /**
       * Sets the atomsToUnPlaced attribute of the ModelBuilder3D object.
       */
00589       private void setAtomsToUnPlaced(IMolecule molecule) {
            for (int i = 0; i < molecule.getAtomCount(); i++) {
                  molecule.getAtom(i).setFlag(CDKConstants.ISPLACED, false);
            }
      }


      /**
       * Sets the atomsToUnVisited attribute of the ModelBuilder3D object.
       */
00599       private void setAtomsToUnVisited(IMolecule molecule) {
            for (int i = 0; i < molecule.getAtomCount(); i++) {
                  molecule.getAtom(i).setFlag(CDKConstants.VISITED, false);
            }
      }

      /**
       * Sets the templateHandler attribute of the ModelBuilder3D object.
       *
       * @param  templateHandler  The new templateHandler value
       */
00610       private void setTemplateHandler(TemplateHandler3D templateHandler) throws CDKException {
            if (templateHandler == null) throw new NullPointerException("The given template handler is null!");
            
            this.templateHandler = templateHandler;
      }

      /**
       * Returns the number of loaded templates. Note that it may return 0 because
       * templates are lazy loaded, that is upon the first ring being layed out.
       * 
       * @return 0, if not templates are loaded
       */
00622       public int getTemplateCount() {
            return this.templateHandler.getTemplateCount();
      }
      
}


Generated by  Doxygen 1.6.0   Back to index