Returns true if atom is in hetero ring system

@param  ac  AtomContainer
@return     true/false
491747
private boolean isHeteroRingSystem(IAtomContainer ac) {
        if (ac != null) {
            for (int i = 0; i < ac.getAtomCount(); i++) {
                if (!(ac.getAtom(i).getSymbol()).equals("H") && !(ac.getAtom(i).getSymbol()).equals("C")) {
                    return true;
                }
            }
        }
        return false;
    }
573931
private int getHalogenCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        int acounter = 0;
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("F") || neighbour.getSymbol().equals("I")
                    || neighbour.getSymbol().equals("Cl") || neighbour.getSymbol().equals("Br")) {
                acounter += 1;
            }
        }
        return acounter;
    }
1312611
private boolean getPresenceOfSulfat(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        //org.openscience.cdk.interfaces.IAtom[] second = null;
        //IBond bond = null;
        //int counter = 0;
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("S") && getOxygenCount(ac, neighbour) >= 2
                    && ac.getConnectedBondsCount(neighbour) == 4) {
                return true;
            }
        }
        return false;
    }
1366819
public IAtomContainer assignMMFF94PartialCharges(IAtomContainer ac) throws CDKException {
        if (!mmff.assignAtomTypes(ac))
            throw new CDKException("Molecule had an atom of unknown MMFF type");
        mmff.partialCharges(ac);
        mmff.clearProps(ac);
        for (IAtom atom : ac.atoms())
            atom.setProperty(MMFF_94_CHARGE, atom.getCharge());
        return ac;
    }
1036712
public static boolean hasCrystalCoordinates(IAtomContainer container) {
        Iterator<IAtom> atoms = container.atoms().iterator();
        while (atoms.hasNext()) {
            if (atoms.next().getFractionalPoint3d() == null) {
                return false;
            }
        }
        return true;
    }
441943
List<AtomPair> findCongestedPairs() {

        List<AtomPair> pairs = new ArrayList<>();

        // only add a single pair between each ring system, otherwise we
        // may have many pairs that are actually all part of the same
        // congestion
        Set<IntTuple> ringpairs = new HashSet<>();

        // score at which to check for crossing bonds
        final double maybeCrossed = 1.0 / (2 * 2);

        final int numAtoms = mol.getAtomCount();
        for (int u = 0; u < numAtoms; u++) {
            for (int v = u + 1; v < numAtoms; v++) {
                double contribution = congestion.contribution(u, v);
                // <0 = bonded
                if (contribution <= 0)
                    continue;

                // we don't modify ring bonds with the class to when the atoms
                // same ring systems we can't reduce the congestion
                if (ringsystems[u] > 0 && ringsystems[u] == ringsystems[v])
                    continue;

                // an un-bonded atom pair is congested if they're and with a certain distance
                // or any of their bonds are crossing
                if (contribution >= MIN_SCORE || contribution >= maybeCrossed && haveCrossingBonds(u, v)) {

                    int uWeight = mol.getAtom(u).getProperty(AtomPlacer.PRIORITY);
                    int vWeight = mol.getAtom(v).getProperty(AtomPlacer.PRIORITY);

                    int[] path = uWeight > vWeight ? apsp.from(u).pathTo(v)
                                                   : apsp.from(v).pathTo(u);

                    // something not right here if the len is < 3
                    int len = path.length;
                    if (len < 3) continue;

                    // build the seqAt and bndAt lists from shortest path
                    int[] seqAt = new int[len - 2];
                    IBond[] bndAt = new IBond[len - 1];
                    makeAtmBndQueues(path, seqAt, bndAt);

                    // we already know about this collision between these ring systems
                    // so dont add the pair
                    if (ringsystems[u] > 0 && ringsystems[v] > 0 &&
                            !ringpairs.add(new IntTuple(ringsystems[u], ringsystems[v])))
                        continue;

                    // add to pairs to overlap
                    pairs.add(new AtomPair(u, v, seqAt, bndAt));
                }
            }
        }

        // sort the pairs to attempt consistent overlap resolution (order independent)
        Collections.sort(pairs, new Comparator<AtomPair>() {
            @Override
            public int compare(AtomPair a, AtomPair b) {
                int a1 = atoms[a.fst].getProperty(AtomPlacer.PRIORITY);
                int a2 = atoms[a.snd].getProperty(AtomPlacer.PRIORITY);
                int b1 = atoms[b.fst].getProperty(AtomPlacer.PRIORITY);
                int b2 = atoms[b.snd].getProperty(AtomPlacer.PRIORITY);
                int amin, amax;
                int bmin, bmax;
                if (a1 < a2) {
                    amin = a1;
                    amax = a2;
                }
                else {
                    amin = a2;
                    amax = a1;
                }
                if (b1 < b2) {
                    bmin = a1;
                    bmax = a2;
                }
                else {
                    bmin = a2;
                    bmax = a1;
                }
                int cmp = Integer.compare(amin, bmin);
                if (cmp != 0) return cmp;
                return Integer.compare(amax, bmax);
            }
        });

        return pairs;
    }
37133
private int getAtomTypeXCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        int nocounter = 0;
        IBond bond;
        for (IAtom neighbour : neighbours) {
            if ((neighbour.getSymbol().equals("N") || neighbour.getSymbol().equals("O"))
                    && !(Boolean) neighbour.getProperty("IS_IN_AROMATIC_RING")) {
                //if (ac.getMaximumBondOrder(neighbours[i]) == 1.0) {
                bond = ac.getBond(neighbour, atom);
                if (bond.getOrder() != IBond.Order.DOUBLE) {
                    nocounter += 1;
                }
            }
        }
        return nocounter;
    }
1120796
protected static IAtomContainer makeAtomContainer(IAtom atom, List<IBond> parts, IAtom excludedAtom) {
        IAtomContainer partContainer = atom.getBuilder().newInstance(IAtomContainer.class);
        partContainer.addAtom(atom);
        for (IBond aBond : parts) {
            for (IAtom bondedAtom : aBond.atoms()) {
                if (!bondedAtom.equals(excludedAtom) && !partContainer.contains(bondedAtom))
                    partContainer.addAtom(bondedAtom);
            }
            if (!aBond.contains(excludedAtom)) partContainer.addBond(aBond);
        }
        return partContainer;
    }
1101357
public IAtomContainer assignGasteigerPiPartialCharges(IAtomContainer ac, boolean setCharge) throws Exception {

        // we save the aromaticity flags for the input molecule so that
        // we can add them back before we return
        boolean[] oldBondAromaticity = new boolean[ac.getBondCount()];
        boolean[] oldAtomAromaticity = new boolean[ac.getAtomCount()];
        for (int i = 0; i < ac.getAtomCount(); i++)
            oldAtomAromaticity[i] = ac.getAtom(i).getFlag(CDKConstants.ISAROMATIC);
        for (int i = 0; i < ac.getBondCount(); i++)
            oldBondAromaticity[i] = ac.getBond(i).getFlag(CDKConstants.ISAROMATIC);

        IAtomContainerSet setHI = null;

        /* 0: remove charge, and possible flag ac */
        for (int j = 0; j < ac.getAtomCount(); j++) {
            ac.getAtom(j).setCharge(0.0);
            ac.getAtom(j).setFlag(ISCHANGEDFC, false);
        }
        for (int j = 0; j < ac.getBondCount(); j++) {
            ac.getBond(j).setFlag(ISCHANGEDFC, false);
        }

        /* 1: detect resonance structure */
        StructureResonanceGenerator gR1 = new StructureResonanceGenerator();/*
                                                                             * according
                                                                             * G
                                                                             * .
                                                                             * should
                                                                             * be
                                                                             * integrated
                                                                             * the
                                                                             * breaking
                                                                             * bonding
                                                                             */
        List<IReactionProcess> reactionList1 = gR1.getReactions();
        List<IParameterReact> paramList1 = new ArrayList<IParameterReact>();
        IParameterReact param = new SetReactionCenter();
        param.setParameter(Boolean.TRUE);
        paramList1.add(param);
        HeterolyticCleavagePBReaction reactionHCPB = new HeterolyticCleavagePBReaction();
        reactionHCPB.setParameterList(paramList1);
        reactionList1.add(new SharingAnionReaction());
        Iterator<IReactionProcess> itReaction = reactionList1.iterator();
        while (itReaction.hasNext()) {
            IReactionProcess reaction = itReaction.next();
            reaction.setParameterList(paramList1);
        }
        gR1.setReactions(reactionList1);

        StructureResonanceGenerator gR2 = new StructureResonanceGenerator();/*
                                                                             * according
                                                                             * G
                                                                             * .
                                                                             * should
                                                                             * be
                                                                             * integrated
                                                                             * the
                                                                             * breaking
                                                                             * bonding
                                                                             */
        gR2.setMaximalStructures(MX_RESON);
        List<IReactionProcess> reactionList2 = gR2.getReactions();
        List<IParameterReact> paramList = new ArrayList<IParameterReact>();
        IParameterReact paramA = new SetReactionCenter();
        paramA.setParameter(Boolean.TRUE);
        paramList.add(paramA);
        reactionList2.add(new HeterolyticCleavagePBReaction());
        reactionList2.add(new SharingAnionReaction());
        itReaction = reactionList2.iterator();
        while (itReaction.hasNext()) {
            IReactionProcess reaction = itReaction.next();
            reaction.setParameterList(paramList);
        }
        gR2.setReactions(reactionList2);

        /* find resonance containers, which eliminates the repetitions */
        StructureResonanceGenerator gRN = new StructureResonanceGenerator();/*
                                                                             * according
                                                                             * G
                                                                             * .
                                                                             * should
                                                                             * be
                                                                             * integrated
                                                                             * the
                                                                             * breaking
                                                                             * bonding
                                                                             */
        IAtomContainerSet acSet = gRN.getContainers(removingFlagsAromaticity(ac));
        //		IAtomContainerSet acSet = ConjugatedPiSystemsDetector.detect(removingFlagsAromaticity(ac));

        IAtomContainerSet iSet = ac.getBuilder().newInstance(IAtomContainerSet.class);
        iSet.addAtomContainer(ac);

        if (acSet != null) for (Iterator<IAtomContainer> it = acSet.atomContainers().iterator(); it.hasNext();) {
            IAtomContainer container = it.next();
            ac = setFlags(container, ac, true);

            // Aromatic don't break its double bond homolytically
            if (Aromaticity.cdkLegacy().apply(ac))
                reactionList1.remove(reactionHCPB);
            else
                reactionList1.add(reactionHCPB);

            IAtomContainerSet a = gR1.getStructures(removingFlagsAromaticity(ac));
            if (a.getAtomContainerCount() > 1) {
                for (int j = 1; j < a.getAtomContainerCount(); j++) { // the first is already added
                    iSet.addAtomContainer(a.getAtomContainer(j));
                }
            }
            ac = setFlags(container, ac, false);

            /* processing for bonds which are not in resonance */
            for (int number = 0; number < ac.getBondCount(); number++) {
                IAtomContainer aa = setAntiFlags(container, ac, number, true);
                if (aa != null) {
                    IAtomContainerSet ab = gR2.getStructures(aa);
                    if (ab.getAtomContainerCount() > 1) for (int j = 1; j < ab.getAtomContainerCount(); j++) { // the first is already added
                            iSet.addAtomContainer(ab.getAtomContainer(j));
                        }
                    ac = setAntiFlags(container, aa, number, false);
                }
            }
        }

        /* detect hyperconjugation interactions */
        setHI = getHyperconjugationInteractions(ac, iSet);

        if (setHI != null) {
            if (setHI.getAtomContainerCount() != 0) iSet.add(setHI);
            logger.debug("setHI: " + iSet.getAtomContainerCount());
        }
        if (iSet.getAtomContainerCount() < 2) {
            for (int i = 0; i < ac.getAtomCount(); i++)
                ac.getAtom(i).setFlag(CDKConstants.ISAROMATIC, oldAtomAromaticity[i]);
            for (int i = 0; i < ac.getBondCount(); i++)
                ac.getBond(i).setFlag(CDKConstants.ISAROMATIC, oldBondAromaticity[i]);
            return ac;
        }

        /*
         * 2: search whose atoms which don't keep their formal charge and set flags
         */
        double[][] sumCharges = new double[iSet.getAtomContainerCount()][ac.getAtomCount()];
        for (int i = 1; i < iSet.getAtomContainerCount(); i++) {
            IAtomContainer iac = iSet.getAtomContainer(i);
            for (int j = 0; j < iac.getAtomCount(); j++)
                sumCharges[i][j] = iac.getAtom(j).getFormalCharge();

        }

        for (int i = 1; i < iSet.getAtomContainerCount(); i++) {
            IAtomContainer iac = iSet.getAtomContainer(i);
            int count = 0;
            for (int j = 0; j < ac.getAtomCount(); j++)
                if (count < 2) if (sumCharges[i][j] != ac.getAtom(j).getFormalCharge()) {
                    ac.getAtom(j).setFlag(ISCHANGEDFC, true);
                    iac.getAtom(j).setFlag(ISCHANGEDFC, true);
                    count++; /* TODO- error */
                }
        }

        /* 3: set sigma charge (PEOE). Initial start point */
        GasteigerMarsiliPartialCharges peoe = new GasteigerMarsiliPartialCharges();;
        peoe.setMaxGasteigerIters(6);
        IAtomContainer acCloned;

        double[][] gasteigerFactors = assignPiFactors(iSet);//a,b,c,deoc,chi,q

        /* 4: calculate topological weight factors Wt=fQ*fB*fA */
        double[] Wt = new double[iSet.getAtomContainerCount() - 1];
        for (int i = 1; i < iSet.getAtomContainerCount(); i++) {
            Wt[i - 1] = getTopologicalFactors(iSet.getAtomContainer(i), ac);
            logger.debug(", W:" + Wt[i - 1]);
            try {
                acCloned = (IAtomContainer) iSet.getAtomContainer(i).clone();

                acCloned = peoe.assignGasteigerMarsiliSigmaPartialCharges(acCloned, true);
                for (int j = 0; j < acCloned.getAtomCount(); j++)
                    if (iSet.getAtomContainer(i).getAtom(j).getFlag(ISCHANGEDFC)) {
                        gasteigerFactors[i][STEP_SIZE * j + j + 5] = acCloned.getAtom(j).getCharge();
                    }
            } catch (CloneNotSupportedException e) {
                throw new CDKException("Could not clone ac", e);
            }
        }

        /*
         * calculate electronegativity for changed atoms and make the difference
         * between whose atoms which change their formal charge
         */
        for (int iter = 0; iter < MX_ITERATIONS; iter++) {
            //		for (int iter = 0; iter < 1; iter++) {
            for (int k = 1; k < iSet.getAtomContainerCount(); k++) {
                IAtomContainer iac = iSet.getAtomContainer(k);
                double[] electronegativity = new double[2];
                int count = 0;
                int atom1 = 0;
                int atom2 = 0;
                for (int j = 0; j < iac.getAtomCount(); j++) {
                    if (count == 2) /*
                                     * The change of sign is product of only two
                                     * atoms, is not true
                                     */
                    break;
                    if (iac.getAtom(j).getFlag(ISCHANGEDFC)) {
                        logger.debug("Atom: " + j + ", S:" + iac.getAtom(j).getSymbol() + ", C:"
                                + iac.getAtom(j).getFormalCharge());
                        if (count == 0)
                            atom1 = j;
                        else
                            atom2 = j;

                        double q1 = gasteigerFactors[k][STEP_SIZE * j + j + 5];
                        electronegativity[count] = gasteigerFactors[k][STEP_SIZE * j + j + 2] * q1 * q1
                                + gasteigerFactors[k][STEP_SIZE * j + j + 1] * q1
                                + gasteigerFactors[k][STEP_SIZE * j + j];
                        logger.debug("e:" + electronegativity[count] + ",q1: " + q1 + ", c:"
                                + gasteigerFactors[k][STEP_SIZE * j + j + 2] + ", b:"
                                + gasteigerFactors[k][STEP_SIZE * j + j + 1] + ", a:"
                                + gasteigerFactors[k][STEP_SIZE * j + j]);
                        count++;
                    }
                }
                logger.debug("Atom1:" + atom1 + ",Atom2:" + atom2);
                /* difference of electronegativity 1 lower */
                double max1 = Math.max(electronegativity[0], electronegativity[1]);
                double min1 = Math.min(electronegativity[0], electronegativity[1]);
                double DX = 1.0;
                if (electronegativity[0] < electronegativity[1])
                    DX = gasteigerFactors[k][STEP_SIZE * atom1 + atom1 + 3];
                else
                    DX = gasteigerFactors[k][STEP_SIZE * atom2 + atom2 + 3];

                double Dq = (max1 - min1) / DX;
                logger.debug("Dq : " + Dq + " = (" + max1 + "-" + min1 + ")/" + DX);
                double epN1 = getElectrostaticPotentialN(iac, atom1, gasteigerFactors[k]);
                double epN2 = getElectrostaticPotentialN(iac, atom2, gasteigerFactors[k]);
                double SumQN = Math.abs(epN1 - epN2);
                logger.debug("sum(" + SumQN + ") = (" + epN1 + ") - (" + epN2 + ")");

                /* electronic weight */
                double WE = Dq + fE * SumQN;
                logger.debug("WE : " + WE + " = Dq(" + Dq + ")+fE(" + fE + ")*SumQN(" + SumQN);
                int iTE = iter + 1;

                /* total topological */
                double W = WE * Wt[k - 1] * fS / (iTE);
                logger.debug("W : " + W + " = WE(" + WE + ")*Wt(" + Wt[k - 1] + ")*fS(" + fS + ")/iter(" + iTE
                        + "), atoms: " + atom1 + ", " + atom2);

                /* iac == new structure, ac == old structure */
                /* atom1 */
                if (iac.getAtom(atom1).getFormalCharge() == 0) {
                    if (ac.getAtom(atom1).getFormalCharge() < 0) {
                        gasteigerFactors[k][STEP_SIZE * atom1 + atom1 + 5] = -1 * W;
                    } else {
                        gasteigerFactors[k][STEP_SIZE * atom1 + atom1 + 5] = W;
                    }
                } else if (iac.getAtom(atom1).getFormalCharge() > 0) {
                    gasteigerFactors[k][STEP_SIZE * atom1 + atom1 + 5] = W;
                } else {
                    gasteigerFactors[k][STEP_SIZE * atom1 + atom1 + 5] = -1 * W;
                }
                /* atom2 */
                if (iac.getAtom(atom2).getFormalCharge() == 0) {
                    if (ac.getAtom(atom2).getFormalCharge() < 0) {
                        gasteigerFactors[k][STEP_SIZE * atom2 + atom2 + 5] = -1 * W;
                    } else {
                        gasteigerFactors[k][STEP_SIZE * atom2 + atom2 + 5] = W;
                    }
                } else if (iac.getAtom(atom2).getFormalCharge() > 0) {
                    gasteigerFactors[k][STEP_SIZE * atom2 + atom2 + 5] = W;
                } else {
                    gasteigerFactors[k][STEP_SIZE * atom2 + atom2 + 5] = -1 * W;
                }

            }
            for (int k = 1; k < iSet.getAtomContainerCount(); k++) {

                for (int i = 0; i < ac.getAtomCount(); i++)
                    if (iSet.getAtomContainer(k).getAtom(i).getFlag(ISCHANGEDFC)) {
                        double charge = ac.getAtom(i).getCharge();
                        double chargeT = 0.0;
                        chargeT = charge + gasteigerFactors[k][STEP_SIZE * i + i + 5];
                        logger.debug("i<|" + ac.getAtom(i).getSymbol() + ", " + chargeT + "=c:" + charge + "+g: "
                                + gasteigerFactors[k][STEP_SIZE * i + i + 5]);
                        ac.getAtom(i).setCharge(chargeT);
                    }
            }

        }// iterations
        logger.debug("final");

        // before getting back we should set back the aromatic flags
        for (int i = 0; i < ac.getAtomCount(); i++)
            ac.getAtom(i).setFlag(CDKConstants.ISAROMATIC, oldAtomAromaticity[i]);
        for (int i = 0; i < ac.getBondCount(); i++)
            ac.getBond(i).setFlag(CDKConstants.ISAROMATIC, oldBondAromaticity[i]);

        return ac;

    }
610845
def is_het_residue(self, obres):
        """"""
        if not obres.GetResidueProperty(0):
            # If the residue is NOT amino (0)
            # It can be amino_nucleo, coenzme, ion, nucleo, protein, purine, pyrimidine, solvent
            # In these cases, it is a ligand candidate
            return True
        else:
            # Here, the residue is classified as amino
            # Amino acids can still be ligands, so we check for HETATM entries
            # Only residues with at least one HETATM entry are processed as ligands
            het_atoms = []
            for atm in pybel.ob.OBResidueAtomIter(obres):
                het_atoms.append(obres.IsHetAtom(atm))
            if True in het_atoms:
                return True
        return False
1006377
public int numberOfUnplacedHeavyAtoms(IAtomContainer ac) {
        int nUnplacedHeavyAtoms = 0;
        for (int i = 0; i < ac.getAtomCount(); i++) {
            if (isUnplacedHeavyAtom(ac.getAtom(i))) {
                nUnplacedHeavyAtoms++;
            }
        }
        return nUnplacedHeavyAtoms;
    }
1141986
public boolean isCachedAtomContainer(IAtomContainer container) {
        if (cachedDescriptorValues == null) return false;
        return (cachedDescriptorValues.get(PREVIOUS_ATOMCONTAINER) == container);
    }
1147667
private int getDoubleBondedSulfurCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        IBond bond;
        int sdbcounter = 0;
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("S")) {
                if (atom.getFormalCharge() == 1 && neighbour.getFormalCharge() == -1) {
                    sdbcounter += 1;
                }
                bond = ac.getBond(neighbour, atom);
                if (!neighbour.getFlag(CDKConstants.ISAROMATIC)) {
                    if (bond.getOrder() == IBond.Order.DOUBLE) {
                        sdbcounter += 1;
                    }
                }
            }
        }
        return sdbcounter;
    }
1272563
public boolean isSaturated(IBond bond, IAtomContainer atomContainer) throws CDKException {
        logger.debug("isBondSaturated?: ", bond);
        IAtom[] atoms = BondManipulator.getAtomArray(bond);
        boolean isSaturated = true;
        for (int i = 0; i < atoms.length; i++) {
            logger.debug("isSaturated(Bond, AC): atom I=", i);
            isSaturated = isSaturated && isSaturated(atoms[i], atomContainer);
        }
        logger.debug("isSaturated(Bond, AC): result=", isSaturated);
        return isSaturated;
    }
710816
@Override
    public boolean matches(IBond bond) {
        if (bond.isAromatic() ^ isAromatic()) return false;

        // we check for both bonds being aromatic - but the query will
        // never come in as aromatic (since there is a separate aromatic
        // query bond). But no harm in checking
        return bond.isAromatic() || bond.getOrder() == getOrder();
    }
742097
private int getDoubleBondedCarbonsCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        IBond bond;
        int cdbcounter = 0;
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("C")) {
                bond = ac.getBond(neighbour, atom);
                if (bond.getOrder() == IBond.Order.DOUBLE) {
                    cdbcounter += 1;
                }
            }
        }
        return cdbcounter;
    }
1324841
static boolean[] terminalHydrogens(final IAtomContainer ac, final int[][] g) {

        final boolean[] hydrogens = new boolean[ac.getAtomCount()];

        // we specifically don't check for null atomic number, this must be set.
        // if not, something major is wrong
        for (int i = 0; i < ac.getAtomCount(); i++) {
            IAtom atom = ac.getAtom(i);
            hydrogens[i] = atom.getAtomicNumber() == 1 &&
                           atom.getMassNumber() == null &&
                           g[i].length == 1;
        }

        return hydrogens;
    }