org.openscience.cdk.graph.ConnectivityChecker Maven / Gradle / Ivy
/* 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