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

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