/* * This file is part of MoleculeViewer. * * MoleculeViewer 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 3 of the License, or * (at your option) any later version. * * MoleculeViewer 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 MoleculeViewer. If not, see <http://www.gnu.org/licenses/>. */ package astex; import astex.generic.*; import java.util.*; /* Copyright Astex Technology Ltd. 1999 */ /* Copyright David Hall, Boston University, 2011 */ /* * 02-11-99 mjh * created */ /** * Class for holding information about ring systems in molecular structures. */ class Ring extends Generic { /** The atoms in the ring. */ private List<Atom> atoms = new ArrayList<Atom>(6); /** The bonds in the ring. */ private List<Bond> bonds = new ArrayList<Bond>(6); /** * Add an atom to the ring. */ public void addAtom(Atom a){ atoms.add(a); } /** * Add a bond to the ring. */ public void addBond(Bond b){ bonds.add(b); } /** * Get a bond. */ private Bond getBond(int index){ return bonds.get(index); } /** Return the atom count. */ public int getAtomCount(){ return atoms.size(); } /** Return the bond count. */ private int getBondCount(){ return bonds.size(); } /** * Does this ring contain the specified atom? */ private boolean contains(Atom queryAtom){ for(Atom atom: atoms){ if(atom == queryAtom){ return true; } } return false; } /** * Does this ring contain the specified bond? */ public boolean contains(Bond queryBond){ for(Bond bond: bonds){ if(bond == queryBond){ return true; } } return false; } /** Is this ring aromatic? */ public boolean isAromatic(){ int atomCount = getAtomCount(); if(atomCount < 5 || atomCount > 6){ return false; } // should always be the same as atomCount... int bondCount = getBondCount(); boolean allAromatic = true; for(Bond bond: bonds){ if(bond.getBondOrder() != Bond.BondOrder.AromaticBond){ allAromatic = false; break; } } // if all the bonds were actually marked as aromatic // we can return true if(allAromatic){ return true; } // count the hetero atoms in the ring. int heteroAtomCount = 0; for(Atom atom: atoms){ if(atom.getElement() != PeriodicTable.CARBON){ heteroAtomCount++; } } // otherwise we can look for a set of alternating // double and single bonds if(bondCount == 6){ allAromatic = true; for(int i = 0; i < bondCount; i++){ Bond bond = getBond(i); Bond nextBond = getBond(i == bondCount - 1 ? 0 : i + 1); Bond.BondOrder bondOrder = bond.getBondOrder(); Bond.BondOrder nextBondOrder = nextBond.getBondOrder(); if((bondOrder == Bond.BondOrder.SingleBond && nextBondOrder == Bond.BondOrder.DoubleBond) || (nextBondOrder == Bond.BondOrder.SingleBond && bondOrder == Bond.BondOrder.DoubleBond)){ continue; }else{ allAromatic = false; break; } } if(allAromatic){ return true; } }else if(atomCount == 5){ int doubleBondCount = 0; for(Bond bond: bonds){ if(bond.getBondOrder() == Bond.BondOrder.DoubleBond){ doubleBondCount++; } } if(heteroAtomCount > 0 && doubleBondCount > 1){ return true; } } return false; } /** Get the ring center. */ public Point3d getRingCenter(){ Point3d center = new Point3d(); int atomCount = getAtomCount(); assert(atomCount > 0); for(Atom atom: atoms){ center.add(atom); } center.divide(atomCount); return center; } }