⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 structurediagramgenerator.java

📁 化学图形处理软件
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/*  $Revision: 9065 $ $Author: egonw $ $Date: 2007-10-14 22:04:57 +0200 (Sun, 14 Oct 2007) $ * *  Copyright (C) 1997-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. *  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.layout;import java.util.Iterator;import java.util.List;import javax.vecmath.Point2d;import javax.vecmath.Vector2d;import org.openscience.cdk.CDKConstants;import org.openscience.cdk.exception.CDKException;import org.openscience.cdk.geometry.GeometryToolsInternalCoordinates;import org.openscience.cdk.graph.ConnectivityChecker;import org.openscience.cdk.interfaces.IAtom;import org.openscience.cdk.interfaces.IAtomContainer;import org.openscience.cdk.interfaces.IAtomContainerSet;import org.openscience.cdk.interfaces.IBond;import org.openscience.cdk.interfaces.IMolecule;import org.openscience.cdk.interfaces.IRing;import org.openscience.cdk.interfaces.IRingSet;import org.openscience.cdk.ringsearch.RingPartitioner;import org.openscience.cdk.ringsearch.SSSRFinder;import org.openscience.cdk.tools.LoggingTool;import org.openscience.cdk.tools.manipulator.AtomContainerSetManipulator;import org.openscience.cdk.tools.manipulator.RingSetManipulator;/** * Generates 2D coordinates for a molecule for which only connectivity is known * or the coordinates have been discarded for some reason. Usage: Create an * instance of this class, thereby assigning a molecule, call * generateCoordinates() and get your molecule back: * <pre> * StructureDiagramGenerator sdg = new StructureDiagramGenerator(); * sdg.setMolecule(someMolecule); * sdg.generateCoordinates(); * Molecule layedOutMol = sdg.getMolecule(); * </pre> * * <p>The method will fail if the molecule is disconnected. The * partitionIntoMolecules(AtomContainer) can help here. * * @author      steinbeck * @cdk.created 2004-02-02 * @see         org.openscience.cdk.graph.ConnectivityChecker#partitionIntoMolecules(IAtomContainer) * @cdk.keyword Layout * @cdk.keyword Structure Diagram Generation (SDG) * @cdk.keyword 2D coordinates * @cdk.keyword Coordinate generation, 2D * @cdk.dictref blue-obelisk:layoutMolecule * @cdk.module  sdg * @cdk.bug     1610997 * @cdk.bug     1536561 */public class StructureDiagramGenerator{	private LoggingTool logger = new LoggingTool(StructureDiagramGenerator.class);	private static TemplateHandler DEFAULT_TEMPLATE_HANDLER = null;	private IMolecule molecule;	private IRingSet sssr;	private double bondLength = 1.5;	private Vector2d firstBondVector;	private RingPlacer ringPlacer = new RingPlacer();	private AtomPlacer atomPlacer = new AtomPlacer();	private List ringSystems = null;	private final String disconnectedMessage = "Molecule not connected. Use ConnectivityChecker.partitionIntoMolecules() and do the layout for every single component.";	private TemplateHandler templateHandler = null;	private boolean useTemplates = true;					/** Atoms of the molecule that mapped a template */	private IAtomContainerSet mappedSubstructures;	/**	 *  The empty constructor.	 */	public StructureDiagramGenerator()	{	}	/**	 *  Creates an instance of this class while assigning a molecule to be layed	 *  out.	 *	 *  @param  molecule  The molecule to be layed out.	 */	public StructureDiagramGenerator(IMolecule molecule) {		this();		setMolecule(molecule, false);		templateHandler = new TemplateHandler(molecule.getBuilder());	}	/**	 *  Assings a molecule to be layed out. Call generateCoordinates() to do the	 *  actual layout.	 *	 *  @param  mol    the molecule for which coordinates are to be generated.	 *  @param  clone  Should the whole process be performed with a cloned copy?	 */	public void setMolecule(IMolecule mol, boolean clone) {		templateHandler = new TemplateHandler(mol.getBuilder());		IAtom atom = null;		if (clone)		{			try {				this.molecule = (IMolecule) mol.clone();			} catch (CloneNotSupportedException e) {				logger.error("Should clone, but exception occured: ", e.getMessage());				logger.debug(e);			}		} else		{			this.molecule = mol;		}		for (int f = 0; f < molecule.getAtomCount(); f++)		{			atom = molecule.getAtom(f);			atom.setPoint2d(null);			atom.setFlag(CDKConstants.ISPLACED, false);			atom.setFlag(CDKConstants.VISITED, false);			atom.setFlag(CDKConstants.ISINRING, false);			atom.setFlag(CDKConstants.ISALIPHATIC, false);		}		atomPlacer.setMolecule(this.molecule);		ringPlacer.setMolecule(this.molecule);		ringPlacer.setAtomPlacer(this.atomPlacer);	}	/**	 *  Sets whether to use templates or not. Some complicated ring systems	 *  like adamantane are only nicely layouted when using templates. This	 *  option is by default set true.	 *	 *@param  useTemplates  set true to use templates, false otherwise	 */	public void setUseTemplates(boolean useTemplates)	{		this.useTemplates = useTemplates;	}	/**	 *  Returns whether the use of templates is enabled or disabled.	 *	 *  @return    true, when the use of templates is enables, false otherwise	 */	public boolean getUseTemplates()	{		return useTemplates;	}	/**	 *  Sets the templateHandler attribute of the StructureDiagramGenerator object	 *	 *  @param  templateHandler  The new templateHandler value	 */	public void setTemplateHandler(TemplateHandler templateHandler)	{		this.templateHandler = templateHandler;	}	/**	 *  Gets the templateHandler attribute of the StructureDiagramGenerator object	 *	 *  @return    The templateHandler value	 */	public TemplateHandler getTemplateHandler()	{		if (templateHandler == null)		{			return DEFAULT_TEMPLATE_HANDLER;		}		else		{			return templateHandler;		}  	}	/**	 *  Assings a molecule to be layed out. Call generateCoordinates() to do the	 *  actual layout.	 *	 *  @param  molecule  the molecule for which coordinates are to be generated.	 */	public void setMolecule(IMolecule molecule)	{		setMolecule(molecule, true);	}	/**	 *  Returns the molecule, usually used after a call of generateCoordinates()	 *	 *  @return    The molecule with new coordinates (if generateCoordinates() had	 *             been called)	 */	public IMolecule getMolecule()	{		return molecule;	}	/**	 *  This method uses generateCoordinates, but it removes the hydrogens first,	 *  lays out the structuren and then adds them again.	 *	 *  @throws  java.lang.Exception  if an error occurs	 *  @see     #generateCoordinates	 */	public void generateExperimentalCoordinates() throws java.lang.Exception	{		generateExperimentalCoordinates(new Vector2d(0, 1));	}	/**	 * Generates 2D coordinates on the non-hydrogen skeleton, after which	 * coordinates for the hydrogens are calculated.	 * 	 * @param firstBondVector the vector of the first bond to lay out	 * @throws java.lang.Exception if an error occurs	 */	public void generateExperimentalCoordinates(Vector2d firstBondVector) throws java.lang.Exception {		// first make a shallow copy: Atom/Bond references are kept		IMolecule original = molecule;		IMolecule shallowCopy = molecule.getBuilder().newMolecule(molecule);		// ok, delete H's from 		//IAtom[] atoms = shallowCopy.getAtoms();		for (int i = 0; i < shallowCopy.getAtomCount(); i++) {			IAtom curAtom = shallowCopy.getAtom(i);				if (curAtom.getSymbol().equals("H")) {						shallowCopy.removeAtomAndConnectedElectronContainers(curAtom);						curAtom.setPoint2d(null);				}		}		// do layout on the shallow copy		molecule = shallowCopy;		generateCoordinates(firstBondVector);		double bondLength = GeometryToolsInternalCoordinates.getBondLengthAverage(molecule);		// ok, now create the coordinates for the hydrogens		HydrogenPlacer hPlacer = new HydrogenPlacer();		molecule = original;		hPlacer.placeHydrogens2D(molecule, bondLength);	}	/**	 *  The main method of this StructurDiagramGenerator. Assign a molecule to the	 *  StructurDiagramGenerator, call the generateCoordinates() method and get	 *  your molecule back.	 *	 *  @param  firstBondVector          The vector of the first bond to lay out	 *  @throws  java.lang.Exception     if an error occurs	 */	public void generateCoordinates(Vector2d firstBondVector) throws java.lang.Exception	{		int safetyCounter = 0;		/*		 *  if molecule contains only one Atom, don't fail, simply		 *  set coordinates to simplest: 0,0. See bug #780545		 */		logger.debug("Entry point of generateCoordinates()");		logger.debug("We have a molecules with " + molecule.getAtomCount() + " atoms.");		if (molecule.getAtomCount() == 1)		{			molecule.getAtom(0).setPoint2d(new Point2d(0, 0));			return;		}		if (!ConnectivityChecker.isConnected(molecule))		{			logger.debug("Molecule is not connected. Throwing exception.");			throw new CDKException(disconnectedMessage);		} else		{			logger.debug("Molecule is connected.");		}		/*		 *  compute the minimum number of rings as		 *  given by Frerejacque, Bull. Soc. Chim. Fr., 5, 1008 (1939)		 */		int nrOfEdges = molecule.getBondCount();		//Vector2d ringSystemVector = null;		//Vector2d newRingSystemVector = null;		this.firstBondVector = firstBondVector;		boolean templateMapped = false;		double angle;		/*		 *  First we check if we can map any templates with predefined coordinates		 *  Those are stored as MDL molfiles in data/templates		 */		if (useTemplates && (System.getProperty("java.version").indexOf("1.3.") == -1))		{			logger.debug("Initializing TemplateHandler");			logger.debug("TemplateHander initialized");			logger.debug("Now starting Template Detection in Molecule...");			mappedSubstructures = getTemplateHandler().getMappedSubstructures(molecule);			templateMapped = mappedSubstructures.getAtomContainerCount() > 0;			logger.debug("Template Detection finished");			logger.debug("Number of found templates: " + mappedSubstructures.getAtomContainerCount());		}										int expectedRingCount = nrOfEdges - molecule.getAtomCount() + 1;		if (expectedRingCount > 0)		{			logger.debug("*** Start of handling rings. ***");			/*			 *  Get the smallest set of smallest rings on this molecule			 */												SSSRFinder sssrf = new SSSRFinder(molecule);			sssr = sssrf.findSSSR();			if (sssr.getAtomContainerCount() < 1)			{				return;			}															/*			 * Order the rings because SSSRFinder.findSSSR() returns rings in an			 * undeterministic order.			 */			AtomContainerSetManipulator.sort(sssr);															/*			 *  Mark all the atoms from the ring system as "ISINRING"			 */			markRingAtoms(sssr);			/*			 *  Give a handle of our molecule to the ringPlacer			 */			ringPlacer.setMolecule(molecule);			ringPlacer.checkAndMarkPlaced(sssr);			/*			 *  Partition the smallest set of smallest rings into disconnected ring system.			 *  The RingPartioner returns a Vector containing RingSets. Each of the RingSets contains			 *  rings that are connected to each other either as bridged ringsystems, fused rings or			 *  via spiro connections.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -