/* $RCSfile$
* $Author$
* $Date$
* $Revision$
*
* Copyright (C) 2004-2007 The Chemistry Development Kit (CDK) project
*
* 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.tools.manipulator;
import org.openscience.cdk.annotations.TestClass;
import org.openscience.cdk.annotations.TestMethod;
import org.openscience.cdk.interfaces.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
/**
* @cdk.module standard
* @cdk.githash
*/
@TestClass("org.openscience.cdk.tools.manipulator.RingSetManipulatorTest")
public class RingSetManipulator {
/**
* Return the total number of atoms over all the rings in the colllection.
*
* @param set The collection of rings
* @return The total number of atoms
*/
@TestMethod("testGetAtomCount_IRingSet")
public static int getAtomCount(IRingSet set) {
int count = 0;
for (IAtomContainer atomContainer : set.atomContainers()) {
count += atomContainer.getAtomCount();
}
return count;
}
/**
* Puts all rings of a ringSet in a single atomContainer
*
* @param ringSet The ringSet to use
* @return The produced atomContainer
*/
@TestMethod("testGetAllInOneContainer_IRingSet")
public static IAtomContainer getAllInOneContainer(IRingSet ringSet) {
IAtomContainer resultContainer = ringSet.getBuilder().newAtomContainer();
Iterator<IAtomContainer> containers = RingSetManipulator.getAllAtomContainers(ringSet).iterator();
while (containers.hasNext()) {
resultContainer.add(containers.next());
}
return resultContainer;
}
/**
* Returns the largest (number of atoms) ring set in a molecule
*
*@param ringSystems RingSystems of a molecule
*@return The largestRingSet
*/
@TestMethod("testGetLargestRingSet_List_IRingSet")
public static IRingSet getLargestRingSet(List<IRingSet> ringSystems) {
IRingSet largestRingSet = null;
int atomNumber = 0;
IAtomContainer container = null;
for (int i = 0; i < ringSystems.size(); i++) {
container = RingSetManipulator.getAllInOneContainer(ringSystems.get(i));
if (atomNumber < container.getAtomCount()) {
atomNumber = container.getAtomCount();
largestRingSet = ringSystems.get(i);
}
}
return largestRingSet;
}
/**
* Return the total number of bonds over all the rings in the colllection.
*
* @param set The collection of rings
* @return The total number of bonds
*/
@TestMethod("testGetBondCount")
public static int getBondCount(IRingSet set) {
int count = 0;
for (IAtomContainer atomContainer : set.atomContainers()) {
count += atomContainer.getBondCount();
}
return count;
}
/**
* Returns all the AtomContainer's in a RingSet.
* @param set The collection of rings
* @return A list of IAtomContainer objects corresponding to individual rings
*/
@TestMethod("testGetAllAtomContainers_IRingSet")
public static List<IAtomContainer> getAllAtomContainers(IRingSet set) {
List<IAtomContainer> atomContainerList = new ArrayList<IAtomContainer>();
for (IAtomContainer atomContainer : set.atomContainers()) {
atomContainerList.add(atomContainer);
}
return atomContainerList;
}
/**
* Sorts the rings in the set by size. The smallest ring comes
* first.
* @param ringSet The collection of rings
*/
@TestMethod("testSort_IRingSet")
public static void sort(IRingSet ringSet) {
List<IRing> ringList = new ArrayList<IRing>();
for (IAtomContainer atomContainer : ringSet.atomContainers()) {
ringList.add((IRing) atomContainer);
}
Collections.sort(ringList, new RingSizeComparator(RingSizeComparator.SMALL_FIRST));
ringSet.removeAllAtomContainers();
for (IAtomContainer aRingList : ringList) ringSet.addAtomContainer(aRingList);
}
/**
* We define the heaviest ring as the one with the highest number of double bonds.
* Needed for example for the placement of in-ring double bonds.
*
* @param ringSet The collection of rings
* @param bond A bond which must be contained by the heaviest ring
* @return The ring with the higest number of double bonds connected to a given bond
*/
@TestMethod("testGetHeaviestRing_IRingSet_IBond")
public static IRing getHeaviestRing(IRingSet ringSet, IBond bond)
{
IRingSet rings = ringSet.getRings(bond);
IRing ring = null;
int maxOrderSum = 0;
for (Object ring1 : rings.atomContainers()) {
if (maxOrderSum < ((IRing) ring1).getBondOrderSum()) {
ring = (IRing) ring1;
maxOrderSum = ring.getBondOrderSum();
}
}
return ring;
}
/**
* Returns the ring with the highest numbers of other rings attached to it.
*
* @param ringSet The collection of rings
* @return the ring with the highest numbers of other rings attached to it.
*/
@TestMethod("testGetMostComplexRing_IRingSet")
public static IRing getMostComplexRing(IRingSet ringSet)
{
int[] neighbors = new int[ringSet.getAtomContainerCount()];
IRing ring1, ring2;
IAtom atom1, atom2;
int mostComplex = 0, mostComplexPosition = 0;
/* for all rings in this RingSet */
for (int i = 0; i < ringSet.getAtomContainerCount(); i++)
{
/* Take each ring */
ring1 = (IRing)ringSet.getAtomContainer(i);
/* look at each Atom in this ring whether it is part of any other ring */
for (int j = 0; j < ring1.getAtomCount(); j++)
{
atom1 = ring1.getAtom(j);
/* Look at each of the other rings in the ringset */
for (int k = i + 1; k < ringSet.getAtomContainerCount(); k++)
{
ring2 = (IRing)ringSet.getAtomContainer(k);
if (ring1 != ring2)
{
for (int l = 0; l < ring2.getAtomCount(); l++)
{
atom2 = ring2.getAtom(l);
if (atom1 == atom2)
{
neighbors[i]++;
neighbors[k]++;
break;
}
}
}
}
}
}
for (int i = 0; i < neighbors.length; i++)
{
if (neighbors[i] > mostComplex)
{
mostComplex = neighbors[i];
mostComplexPosition = i;
}
}
return (IRing) ringSet.getAtomContainer(mostComplexPosition);
}
/**
* Checks if <code>atom1</code> and <code>atom2</code> share membership in the same ring or ring system.
* Membership in the same ring is checked if the RingSet contains the SSSR of a molecule; membership in
* the same ring or same ring system is checked if the RingSet contains all rings of a molecule.<BR><BR>
*
* <p><B>Important:</B> This method only returns meaningful results if <code>atom1</code> and
* <code>atom2</code> are members of the same molecule for which the RingSet was calculated!
*
* @param ringSet The collection of rings
* @param atom1 The first atom
* @param atom2 The second atom
* @return boolean true if <code>atom1</code> and <code>atom2</code> share membership of at least one ring or ring system, false otherwise
*/
@TestMethod("testIsSameRing_IRingSet_IAtom_IAtom")
public static boolean isSameRing(IRingSet ringSet, IAtom atom1, IAtom atom2)
{
for (IAtomContainer atomContainer : ringSet.atomContainers()) {
IRing ring = (IRing) atomContainer;
if (ring.contains(atom1) && ring.contains(atom2)) return true;
}
return false;
}
/**
* Checks - and returns 'true' - if a certain ring is already
* stored in the ringset. This is not a test for equality of Ring
* objects, but compares all Bond objects of the ring.
*
* @param newRing The ring to be tested if it is already stored
* @param ringSet The collection of rings
* @return true if it is already stored
*/
@TestMethod("testRingAlreadyInSet_IRing_IRingSet")
public static boolean ringAlreadyInSet(IRing newRing, IRingSet ringSet) {
IRing ring;
// IBond[] bonds;
// IBond[] newBonds;
// IBond bond;
int equalCount;
boolean equals;
for (int f = 0; f < ringSet.getAtomContainerCount(); f++) {
equals = false;
equalCount = 0;
ring = (IRing) ringSet.getAtomContainer(f);
// bonds = ring.getBonds();
// newBonds = newRing.getBonds();
if (ring.getBondCount() == newRing.getBondCount()) {
for (IBond newBond : newRing.bonds()) {
for (IBond bond : ring.bonds()) {
if (newBond == bond) {
equals = true;
equalCount++;
break;
}
}
if (!equals) break;
}
}
if (equalCount == ring.getBondCount()) {
return true;
}
}
return false;
}
/**
* Iterates over the rings in the ring set, and marks the ring
* aromatic if all atoms and all bonds are aromatic.
*
* This method assumes that aromaticity perception has been done before hand.
*
* @param ringset The collection of rings
*/
@TestMethod("markAromatic")
public static void markAromaticRings(IRingSet ringset) {
for (IAtomContainer atomContainer : ringset.atomContainers()) {
RingManipulator.markAromaticRings((IRing) atomContainer);
}
}
}