All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.openscience.cdk.graph.ConnectivityChecker Maven / Gradle / Ivy

There is a newer version: 2.9
Show newest version
/* Copyright (C) 1997-2007  The Chemistry Development Kit (CDK) project
 *
 * Contact: [email protected]
 *
 * 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.graph;

import java.util.HashMap;
import java.util.Map;

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.IChemObject;
import org.openscience.cdk.interfaces.IDoubleBondStereochemistry;
import org.openscience.cdk.interfaces.ILonePair;
import org.openscience.cdk.interfaces.ISingleElectron;
import org.openscience.cdk.interfaces.IStereoElement;
import org.openscience.cdk.interfaces.ITetrahedralChirality;
import org.openscience.cdk.stereo.ExtendedTetrahedral;

/**
 * Tool class for checking whether the (sub)structure in an
 * AtomContainer is connected.
 * To check whether an AtomContainer is connected this code
 * can be used:
 * 
 *  boolean isConnected = ConnectivityChecker.isConnected(atomContainer);
 * 
* *

A disconnected AtomContainer can be fragmented into connected * fragments by using code like: *

 *   MoleculeSet fragments = ConnectivityChecker.partitionIntoMolecules(disconnectedContainer);
 *   int fragmentCount = fragments.getAtomContainerCount();
 * 
* * @cdk.module standard * @cdk.githash * * @cdk.keyword connectivity */ public class ConnectivityChecker { /** * Check whether a set of atoms in an {@link IAtomContainer} is connected. * * @param atomContainer The {@link IAtomContainer} to be check for connectedness * @return true if the {@link IAtomContainer} is connected */ public static boolean isConnected(IAtomContainer atomContainer) { // with one atom or less, we define it to be connected, as there is no // partitioning needed if (atomContainer.getAtomCount() < 2) return true; ConnectedComponents cc = new ConnectedComponents(GraphUtil.toAdjList(atomContainer)); return cc.nComponents() == 1; } /** * Partitions the atoms in an AtomContainer into covalently connected components. * * @param container The AtomContainer to be partitioned into connected components, i.e. molecules * @return A MoleculeSet. * * @cdk.dictref blue-obelisk:graphPartitioning */ public static IAtomContainerSet partitionIntoMolecules(IAtomContainer container) { ConnectedComponents cc = new ConnectedComponents(GraphUtil.toAdjList(container)); return partitionIntoMolecules(container, cc.components()); } public static IAtomContainerSet partitionIntoMolecules(IAtomContainer container, int[] components) { int maxComponentIndex = 0; for (int component : components) if (component > maxComponentIndex) maxComponentIndex = component; IAtomContainer[] containers = new IAtomContainer[maxComponentIndex + 1]; Map componentsMap = new HashMap(2 * container.getAtomCount()); for (int i = 1; i < containers.length; i++) containers[i] = container.getBuilder().newInstance(IAtomContainer.class); IAtomContainerSet containerSet = container.getBuilder().newInstance(IAtomContainerSet.class); for (int i = 0; i < container.getAtomCount(); i++) { componentsMap.put(container.getAtom(i), containers[components[i]]); containers[components[i]].addAtom(container.getAtom(i)); } for (IBond bond : container.bonds()) { IAtomContainer begComp = componentsMap.get(bond.getBegin()); IAtomContainer endComp = componentsMap.get(bond.getEnd()); if (begComp == endComp) begComp.addBond(bond); } for (ISingleElectron electron : container.singleElectrons()) componentsMap.get(electron.getAtom()).addSingleElectron(electron); for (ILonePair lonePair : container.lonePairs()) componentsMap.get(lonePair.getAtom()).addLonePair(lonePair); for (IStereoElement stereo : container.stereoElements()) { IChemObject focus = stereo.getFocus(); if (focus instanceof IAtom) { if (componentsMap.containsKey(focus)) componentsMap.get(focus).addStereoElement(stereo); } else if (focus instanceof IBond) { if (componentsMap.containsKey(((IBond) focus).getBegin())) componentsMap.get(((IBond) focus).getBegin()).addStereoElement(stereo); } else { throw new IllegalStateException("New stereo element not using an atom/bond for focus?"); } } for (int i = 1; i < containers.length; i++) containerSet.addAtomContainer(containers[i]); return containerSet; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy