org.openscience.cdk.graph.invariant.ConjugatedPiSystemsDetector Maven / Gradle / Ivy
/* Copyright (C) 2004-2007 Kai Hartmann
*
* 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.invariant;
import org.openscience.cdk.CDKConstants;
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 java.util.List;
import java.util.Stack;
/**
* @author kaihartmann
* @cdk.githash
* @cdk.created 2004-09-17
* @cdk.module reaction
*
* @cdk.todo add negatively charged atoms (e.g. O-) to the pi system
*/
public class ConjugatedPiSystemsDetector {
/**
* Detect all conjugated pi systems in an AtomContainer. This method returns a AtomContainerSet
* with Atom and Bond objects from the original AtomContainer. The aromaticity has to be known
* before calling this method.
*
* An example for detection of Radical Allyl:
*
* Atom a0 = new Atom("C"); mol.addAtom(a0);
* Atom a1 = new Atom("C"); mol.addAtom(a1);
* Atom a2 = new Atom("C"); mol.addAtom(a2);
* Atom h1 = new Atom("H"); mol.addAtom(h1);
* Atom h2 = new Atom("H"); mol.addAtom(h2);
* Atom h3 = new Atom("H"); mol.addAtom(h3);
* Atom h4 = new Atom("H"); mol.addAtom(h4);
* Atom h5 = new Atom("H"); mol.addAtom(h5);
* mol.addBond(0, 1, IBond.Order.DOUBLE);
* mol.addBond(1, 2, IBond.Order.SINGLE);
* mol.addBond(0, 3, IBond.Order.SINGLE);
* mol.addBond(0, 4, IBond.Order.SINGLE);
* mol.addBond(1, 5, IBond.Order.SINGLE);
* mol.addBond(2, 6, IBond.Order.SINGLE);
* mol.addBond(2, 7, IBond.Order.SINGLE);
* SingleElectron se = new SingleElectron(a2);
* mol.addElectronContainer(se);
*
*
*@param ac The AtomContainer for which to detect conjugated pi systems
*@return The set of AtomContainers with conjugated pi systems
*/
public static IAtomContainerSet detect(IAtomContainer ac) {
IAtomContainerSet piSystemSet = ac.getBuilder().newInstance(IAtomContainerSet.class);
for (int i = 0; i < ac.getAtomCount(); i++) {
IAtom atom = ac.getAtom(i);
atom.setFlag(CDKConstants.VISITED, false);
}
for (int i = 0; i < ac.getAtomCount(); i++) {
IAtom firstAtom = ac.getAtom(i);
// if this atom was already visited in a previous DFS, continue
if (firstAtom.getFlag(CDKConstants.VISITED) || checkAtom(ac, firstAtom) == -1) {
continue;
}
IAtomContainer piSystem = ac.getBuilder().newInstance(IAtomContainer.class);
Stack stack = new Stack();
piSystem.addAtom(firstAtom);
stack.push(firstAtom);
firstAtom.setFlag(CDKConstants.VISITED, true);
// Start DFS from firstAtom
while (!stack.empty()) {
//boolean addAtom = false;
IAtom currentAtom = stack.pop();
List atoms = ac.getConnectedAtomsList(currentAtom);
List bonds = ac.getConnectedBondsList(currentAtom);
for (int j = 0; j < atoms.size(); j++) {
IAtom atom = atoms.get(j);
IBond bond = bonds.get(j);
if (!atom.getFlag(CDKConstants.VISITED)) {
int check = checkAtom(ac, atom);
if (check == 1) {
piSystem.addAtom(atom);
piSystem.addBond(bond);
continue;
// do not mark atom as visited if cumulative double bond
} else if (check == 0) {
piSystem.addAtom(atom);
piSystem.addBond(bond);
stack.push(atom);
}
atom.setFlag(CDKConstants.VISITED, true);
}
// close rings with one bond
else if (!piSystem.contains(bond) && piSystem.contains(atom)) {
piSystem.addBond(bond);
}
}
}
if (piSystem.getAtomCount() > 2) {
piSystemSet.addAtomContainer(piSystem);
}
}
return piSystemSet;
}
/**
* Check an Atom whether it may be conjugated or not.
*
*@param ac The AtomContainer containing currentAtom
*@param currentAtom The Atom to check
*@return -1 if isolated, 0 if conjugated, 1 if cumulative db
*/
private static int checkAtom(IAtomContainer ac, IAtom currentAtom) {
int check = -1;
List atoms = ac.getConnectedAtomsList(currentAtom);
List bonds = ac.getConnectedBondsList(currentAtom);
if (currentAtom.getFlag(CDKConstants.ISAROMATIC)) {
check = 0;
} else if (currentAtom.getFormalCharge() == 1 /*
* &&
* currentAtom.getSymbol
* ().equals("C")
*/) {
check = 0;
} else if (currentAtom.getFormalCharge() == -1) {
//// NEGATIVE CHARGES WITH A NEIGHBOOR PI BOND //////////////
int counterOfPi = 0;
for (IAtom atom : atoms) {
if (ac.getMaximumBondOrder(atom) != IBond.Order.SINGLE) {
counterOfPi++;
}
}
if (counterOfPi > 0) check = 0;
} else {
int se = ac.getConnectedSingleElectronsCount(currentAtom);
if (se == 1) {
check = 0; //// DETECTION of radicals
} else if (ac.getConnectedLonePairsCount(currentAtom) > 0
/* && (currentAtom.getSymbol().equals("N") */) {
check = 0; //// DETECTION of lone pair
} else {
int highOrderBondCount = 0;
for (int j = 0; j < atoms.size(); j++) {
IBond bond = bonds.get(j);
if (bond == null || bond.getOrder() != IBond.Order.SINGLE) {
highOrderBondCount++;
} else {
}
}
if (highOrderBondCount == 1) {
check = 0;
} else if (highOrderBondCount > 1) {
check = 1;
}
}
}
return check;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy