Calculates the number of H bond acceptors.

@param  atomContainer             AtomContainer
@return                   number of H bond acceptors
972305
@Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        int hBondAcceptors = 0;

        IAtomContainer ac;
        try {
            ac = (IAtomContainer) atomContainer.clone();
        } catch (CloneNotSupportedException e) {
            return getDummyDescriptorValue(e);
        }

        // aromaticity is detected prior to descriptor calculation if the respective parameter is set to true

        if (checkAromaticity) {
            try {
                AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(ac);
                Aromaticity.cdkLegacy().apply(ac);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }
        }

        //org.openscience.cdk.interfaces.IAtom[] atoms = ac.getAtoms();
        // labelled for loop to allow for labelled continue statements within the loop
        atomloop: for (IAtom atom : ac.atoms()) {
            // looking for suitable nitrogen atoms
            if (atom.getSymbol().equals("N") && atom.getFormalCharge() <= 0) {

                // excluding nitrogens that are adjacent to an oxygen
                List<IBond> bonds = ac.getConnectedBondsList(atom);
                int nPiBonds = 0;
                for (IBond bond : bonds) {
                    if (bond.getOther(atom).getSymbol().equals("O")) continue atomloop;
                    if (IBond.Order.DOUBLE.equals(bond.getOrder())) nPiBonds++;
                }

                // if the nitrogen is aromatic and there are no pi bonds then it's
                // lone pair cannot accept any hydrogen bonds
                if (atom.getFlag(CDKConstants.ISAROMATIC) && nPiBonds == 0) continue;

                hBondAcceptors++;
            }
            // looking for suitable oxygen atoms
            else if (atom.getSymbol().equals("O") && atom.getFormalCharge() <= 0) {
                //excluding oxygens that are adjacent to a nitrogen or to an aromatic carbon
                List<IBond> neighbours = ac.getConnectedBondsList(atom);
                for (IBond bond : neighbours) {
                    IAtom neighbor = bond.getOther(atom);
                    if (neighbor.getSymbol().equals("N") ||
                        (neighbor.getSymbol().equals("C") &&
                         neighbor.isAromatic() &&
                         bond.getOrder() != IBond.Order.DOUBLE))
                        continue atomloop;;
                }
                hBondAcceptors++;
            }
        }

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                hBondAcceptors), getDescriptorNames());
    }
360034
public double[] prepareNode(IAtomContainer atomContainer) {
        double nodeSequence[] = new double[atomContainer.getAtomCount()];
        int i = 0;
        for (IAtom atom : atomContainer.atoms()) {
            String symbol = atom.getSymbol();

            List<IBond> bonds = atomContainer.getConnectedBondsList(atom);
            if (bonds.size() == 1) {
                IBond bond0 = bonds.get(0);
                IBond.Order order = bond0.getOrder();
                if (symbol.equals("C")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 1;// CH3-
                    else if (order == IBond.Order.DOUBLE)
                        nodeSequence[i] = 3;// CH2=
                    else if (order == IBond.Order.TRIPLE) nodeSequence[i] = 6;// CH#
                } else if (symbol.equals("O")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 14;// HO-
                    else if (order == IBond.Order.DOUBLE) nodeSequence[i] = 16;// O=
                    // missing the case of an aromatic double bond
                } else if (symbol.equals("N")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 18;// NH2-
                    else if (order == IBond.Order.DOUBLE) {
                        if (atom.getCharge() == -1.0)
                            nodeSequence[i] = 27;// N= contains -1 charge
                        else
                            nodeSequence[i] = 20;// NH=
                    } else if (order == IBond.Order.TRIPLE) nodeSequence[i] = 23;// N#
                } else if (symbol.equals("S")) {
                    if (order == IBond.Order.SINGLE)
                        nodeSequence[i] = 31;// HS-
                    else if (order == IBond.Order.DOUBLE) nodeSequence[i] = 33;// S=
                } else if (symbol.equals("P"))
                    nodeSequence[i] = 38;// PH2-
                else if (symbol.equals("F"))
                    nodeSequence[i] = 42;// F-
                else if (symbol.equals("Cl"))
                    nodeSequence[i] = 43;// Cl-
                else if (symbol.equals("Br"))
                    nodeSequence[i] = 44;// Br-
                else if (symbol.equals("I"))
                    nodeSequence[i] = 45;// I-
                else {
                    logger.debug("in case of a new node, please " + "report this bug to cdk-devel@lists.sf.net.");
                }
            } else if (bonds.size() == 2) {
                IBond bond0 = (IBond) bonds.get(0);
                IBond bond1 = (IBond) bonds.get(1);
                IBond.Order order0 = bond0.getOrder();
                IBond.Order order1 = bond1.getOrder();
                if (symbol.equals("C")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 2;// -CH2-
                    else if (order0 == IBond.Order.DOUBLE && order1 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 10;// =C=
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.SINGLE)
                            && (order0 == IBond.Order.DOUBLE || bond1.getOrder() == IBond.Order.DOUBLE))
                        nodeSequence[i] = 5;// -CH=
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.TRIPLE)
                            && (order0 == IBond.Order.TRIPLE || bond1.getOrder() == IBond.Order.TRIPLE))
                        nodeSequence[i] = 9;// -C#
                    // case 3 would not allow to reach this statement as there
                    // is no aromatic bond order
                    if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 11;// ArCH
                } else if (symbol.equals("N")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 19;// -NH-
                    else if (order0 == IBond.Order.DOUBLE && order1 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 28;// =N= with charge=-1
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.SINGLE)
                            && (order0 == IBond.Order.DOUBLE || bond1.getOrder() == IBond.Order.DOUBLE))
                        nodeSequence[i] = 22;// -N=
                    else if ((order0 == IBond.Order.DOUBLE || bond1.getOrder() == IBond.Order.DOUBLE)
                            && (order0 == IBond.Order.TRIPLE || bond1.getOrder() == IBond.Order.TRIPLE))
                        nodeSequence[i] = 26;// =N#
                    else if ((order0 == IBond.Order.SINGLE || bond1.getOrder() == IBond.Order.SINGLE)
                            && (order0 == IBond.Order.TRIPLE || bond1.getOrder() == IBond.Order.TRIPLE))
                        nodeSequence[i] = 29;// -N# with charge=+1
                    // case 3 would not allow to reach this statement as there
                    // is no aromatic bond order
                    if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 30;// ArN
                    // there is no way to distinguish between ArNH and ArN as
                    // bonds to protons are not considered
                } else if (symbol.equals("O")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 15;// -O-
                    else if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 17;// ArO
                } else if (symbol.equals("S")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE)
                        nodeSequence[i] = 32;// -S-
                    else if (order0 == IBond.Order.DOUBLE && order1 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 35;// =S=
                    else if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC))
                        nodeSequence[i] = 37;// ArS
                } else if (symbol.equals("P")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE) nodeSequence[i] = 39;// -PH-
                } else {
                    logger.debug("in case of a new node, " + "please report this bug to cdk-devel@lists.sf.net.");
                }
            } else if (bonds.size() == 3) {
                IBond bond0 = (IBond) bonds.get(0);
                IBond bond1 = (IBond) bonds.get(1);
                IBond bond2 = (IBond) bonds.get(2);
                IBond.Order order0 = bond0.getOrder();
                IBond.Order order1 = bond1.getOrder();
                IBond.Order order2 = bond2.getOrder();

                if (symbol.equals("C")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE && order2 == IBond.Order.SINGLE)
                        nodeSequence[i] = 4;// >C-
                    else if (order0 == IBond.Order.DOUBLE || order1 == IBond.Order.DOUBLE
                            || order2 == IBond.Order.DOUBLE) nodeSequence[i] = 8;// >C=
                    // case 2 would not allow to reach this statement because
                    // there is always a double bond (pi system) around an
                    // aromatic atom
                    if ((bond0.getFlag(CDKConstants.ISAROMATIC) || bond1.getFlag(CDKConstants.ISAROMATIC) || bond2
                            .getFlag(CDKConstants.ISAROMATIC))
                            && (order0 == IBond.Order.SINGLE || order1 == IBond.Order.SINGLE || bond2.getOrder() == IBond.Order.SINGLE))
                        nodeSequence[i] = 12;// ArC-
                    // case 3 would not allow to reach this statement
                    if (bond0.getFlag(CDKConstants.ISAROMATIC) && bond1.getFlag(CDKConstants.ISAROMATIC)
                            && bond2.getFlag(CDKConstants.ISAROMATIC)) nodeSequence[i] = 13;// ArC
                } else if (symbol.equals("N")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE && order2 == IBond.Order.SINGLE)
                        nodeSequence[i] = 21;// >N-
                    else if (order0 == IBond.Order.SINGLE || order1 == IBond.Order.SINGLE
                            || order2 == IBond.Order.SINGLE) nodeSequence[i] = 25;// -N(=)=
                } else if (symbol.equals("S")) {
                    if (order0 == IBond.Order.DOUBLE || order1 == IBond.Order.DOUBLE || order2 == IBond.Order.DOUBLE)
                        nodeSequence[i] = 34;// >S=
                } else if (symbol.equals("P")) {
                    if (order0 == IBond.Order.SINGLE && order1 == IBond.Order.SINGLE && order2 == IBond.Order.SINGLE)
                        nodeSequence[i] = 40;// >P-
                } else {
                    logger.debug("in case of a new node, " + "please report this bug to cdk-devel@lists.sf.net.");
                }
            } else if (bonds.size() == 4) {
                if (atom.getSymbol().equals("C"))
                    nodeSequence[i] = 7;// >C<
                else if (atom.getSymbol().equals("N"))
                    nodeSequence[i] = 24;// >N(=)-
                else if (atom.getSymbol().equals("S"))
                    nodeSequence[i] = 36;// >S(=)=
                else if (atom.getSymbol().equals("P"))
                    nodeSequence[i] = 41;// =P<-
                else {
                    logger.debug("in case of a new node, " + "please report this bug to cdk-devel@lists.sf.net.");
                }
            }
            i++;
        }
        return nodeSequence;
    }
404842
private static int checkAtom(IAtomContainer ac, IAtom currentAtom) {
        int check = -1;
        List<IAtom> atoms = ac.getConnectedAtomsList(currentAtom);
        List<IBond> 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;
    }
278663
public boolean saturateByIncreasingBondOrder(IBond bond, IAtomContainer atomContainer) throws CDKException {
        IAtom[] atoms = BondManipulator.getAtomArray(bond);
        IAtom atom = atoms[0];
        IAtom partner = atoms[1];
        logger.debug("  saturating bond: ", atom.getSymbol(), "-", partner.getSymbol());
        IAtomType[] atomTypes1 = getAtomTypeFactory(bond.getBuilder()).getAtomTypes(atom.getSymbol());
        IAtomType[] atomTypes2 = getAtomTypeFactory(bond.getBuilder()).getAtomTypes(partner.getSymbol());
        for (int atCounter1 = 0; atCounter1 < atomTypes1.length; atCounter1++) {
            IAtomType aType1 = atomTypes1[atCounter1];
            logger.debug("  condidering atom type: ", aType1);
            if (couldMatchAtomType(atomContainer, atom, aType1)) {
                logger.debug("  trying atom type: ", aType1);
                for (int atCounter2 = 0; atCounter2 < atomTypes2.length; atCounter2++) {
                    IAtomType aType2 = atomTypes2[atCounter2];
                    logger.debug("  condidering partner type: ", aType1);
                    if (couldMatchAtomType(atomContainer, partner, atomTypes2[atCounter2])) {
                        logger.debug("    with atom type: ", aType2);
                        if (BondManipulator.isLowerOrder(bond.getOrder(), aType2.getMaxBondOrder())
                                && BondManipulator.isLowerOrder(bond.getOrder(), aType1.getMaxBondOrder())) {
                            bond.setOrder(BondManipulator.increaseBondOrder(bond.getOrder()));
                            logger.debug("Bond order now ", bond.getOrder());
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }
994493
@Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        int hBondDonors = 0;

        IAtomContainer ac;
        try {
            ac = (IAtomContainer) atomContainer.clone();
        } catch (CloneNotSupportedException e) {
            return getDummyDescriptorValue(e);
        }

        //org.openscience.cdk.interfaces.IAtom[] atoms = ac.getAtoms();
        // iterate over all atoms of this AtomContainer; use label atomloop to allow for labelled continue
        atomloop: for (int atomIndex = 0; atomIndex < ac.getAtomCount(); atomIndex++) {
            IAtom atom = (IAtom) ac.getAtom(atomIndex);
            // checking for O and N atoms where the formal charge is >= 0
            if ((atom.getSymbol().equals("O") || atom.getSymbol().equals("N")) && atom.getFormalCharge() >= 0) {
                // implicit hydrogens
                Integer implicitH = atom.getImplicitHydrogenCount();
                if (implicitH == CDKConstants.UNSET) implicitH = 0;
                if (implicitH > 0) {
                    hBondDonors++;
                    continue atomloop; // we skip the explicit hydrogens part cause we found implicit hydrogens
                }
                // explicit hydrogens
                java.util.List neighbours = ac.getConnectedAtomsList(atom);
                for (Object neighbour : neighbours) {
                    if (((IAtom) neighbour).getSymbol().equals("H")) {
                        hBondDonors++;
                        continue atomloop;
                    }
                }
            }
        }

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                hBondDonors), getDescriptorNames());
    }
1051020
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        if (!GeometryUtil.has3DCoordinates(container))
            return getDummyDescriptorValue(new CDKException("Molecule must have 3D coordinates"));

        IsotopeFactory factory = null;
        double mass1;
        double mass2;
        try {
            factory = Isotopes.getInstance();
        } catch (Exception e) {
            logger.debug(e);
        }

        double sum = 0;
        for (int i = 0; i < container.getBondCount(); i++) {
            IBond bond = container.getBond(i);

            if (bond.getAtomCount() != 2) {
                return getDummyDescriptorValue(new CDKException("GravitationalIndex: Only handles 2 center bonds"));
            }

            mass1 = factory.getMajorIsotope(bond.getBegin().getSymbol()).getMassNumber();
            mass2 = factory.getMajorIsotope(bond.getEnd().getSymbol()).getMassNumber();

            Point3d p1 = bond.getBegin().getPoint3d();
            Point3d p2 = bond.getEnd().getPoint3d();

            double x1 = p1.x;
            double y1 = p1.y;
            double z1 = p1.z;
            double x2 = p2.x;
            double y2 = p2.y;
            double z2 = p2.z;

            double dist = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2);
            sum += (mass1 * mass2) / dist;
        }

        // heavy atoms only
        double heavysum = 0;
        for (int i = 0; i < container.getBondCount(); i++) {
            IBond b = container.getBond(i);

            if (b.getAtomCount() != 2) {
                return getDummyDescriptorValue(new CDKException("GravitationalIndex: Only handles 2 center bonds"));
            }

            if (b.getBegin().getSymbol().equals("H") || b.getEnd().getSymbol().equals("H")) continue;

            mass1 = factory.getMajorIsotope(b.getBegin().getSymbol()).getMassNumber();
            mass2 = factory.getMajorIsotope(b.getEnd().getSymbol()).getMassNumber();

            Point3d point0 = b.getBegin().getPoint3d();
            Point3d point1 = b.getEnd().getPoint3d();

            double x1 = point0.x;
            double y1 = point0.y;
            double z1 = point0.z;
            double x2 = point1.x;
            double y2 = point1.y;
            double z2 = point1.z;

            double dist = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2);
            heavysum += (mass1 * mass2) / dist;
        }

        // all pairs
        ArrayList<Integer> x = new ArrayList<Integer>();
        for (int i = 0; i < container.getAtomCount(); i++) {
            if (!container.getAtom(i).getSymbol().equals("H")) x.add(i);
        }
        int npair = x.size() * (x.size() - 1) / 2;
        pair[] p = new pair[npair];
        for (int i = 0; i < npair; i++)
            p[i] = new pair();
        int pcount = 0;
        for (int i = 0; i < x.size() - 1; i++) {
            for (int j = i + 1; j < x.size(); j++) {
                int present = 0;
                int a = x.get(i);
                int b = x.get(j);
                for (int k = 0; k < pcount; k++) {
                    if ((p[k].x == a && p[k].y == b) || (p[k].y == a && p[k].x == b)) present = 1;
                }
                if (present == 1) continue;
                p[pcount].x = a;
                p[pcount].y = b;
                pcount += 1;
            }
        }
        double allheavysum = 0;
        for (pair aP : p) {
            int atomNumber1 = aP.x;
            int atomNumber2 = aP.y;

            mass1 = factory.getMajorIsotope(container.getAtom(atomNumber1).getSymbol()).getMassNumber();
            mass2 = factory.getMajorIsotope(container.getAtom(atomNumber2).getSymbol()).getMassNumber();

            double x1 = container.getAtom(atomNumber1).getPoint3d().x;
            double y1 = container.getAtom(atomNumber1).getPoint3d().y;
            double z1 = container.getAtom(atomNumber1).getPoint3d().z;
            double x2 = container.getAtom(atomNumber2).getPoint3d().x;
            double y2 = container.getAtom(atomNumber2).getPoint3d().y;
            double z2 = container.getAtom(atomNumber2).getPoint3d().z;

            double dist = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2);
            allheavysum += (mass1 * mass2) / dist;
        }

        DoubleArrayResult retval = new DoubleArrayResult(9);
        retval.add(heavysum);
        retval.add(Math.sqrt(heavysum));
        retval.add(Math.pow(heavysum, 1.0 / 3.0));

        retval.add(sum);
        retval.add(Math.sqrt(sum));
        retval.add(Math.pow(sum, 1.0 / 3.0));

        retval.add(allheavysum);
        retval.add(Math.sqrt(allheavysum));
        retval.add(Math.pow(allheavysum, 1.0 / 3.0));

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), retval,
                getDescriptorNames());
    }
935046
private int getDoubleBondedNitrogenCount(IAtomContainer ac, IAtom atom) {
        List<IAtom> neighbours = ac.getConnectedAtomsList(atom);
        IBond bond;
        int ndbcounter = 0;
        for (IAtom neighbour : neighbours) {
            if (neighbour.getSymbol().equals("N")) {
                bond = ac.getBond(neighbour, atom);
                if (!neighbour.getFlag(CDKConstants.ISAROMATIC)) {
                    if (bond.getOrder() == IBond.Order.DOUBLE) {
                        ndbcounter += 1;
                    }
                }
            }
        }
        return ndbcounter;
    }
675992
public static int[][] getMatrix(IAtomContainer container) {
        IBond bond;
        int indexAtom1;
        int indexAtom2;
        int[][] conMat = new int[container.getAtomCount()][container.getAtomCount()];
        for (int f = 0; f < container.getBondCount(); f++) {
            bond = container.getBond(f);
            indexAtom1 = container.indexOf(bond.getBegin());
            indexAtom2 = container.indexOf(bond.getEnd());
            conMat[indexAtom1][indexAtom2] = 1;
            conMat[indexAtom2][indexAtom1] = 1;
        }
        return conMat;
    }
1240068
private double getTopologicalFactors(IAtomContainer atomContainer, IAtomContainer ac) {
        /* factor for separation of charge */
        int totalNCharge1 = AtomContainerManipulator.getTotalNegativeFormalCharge(atomContainer);
        int totalPCharge1 = AtomContainerManipulator.getTotalPositiveFormalCharge(atomContainer);

        double fQ = 1.0;
        if (totalNCharge1 != 0.0) {
            fQ = 0.5;
            for (int i = 0; i < atomContainer.getBondCount(); i++) {
                IBond bond = atomContainer.getBond(i);
                if (bond.getBegin().getFormalCharge() != 0.0 && bond.getEnd().getFormalCharge() != 0.0) {
                    fQ = 0.25;
                    break;
                }
            }
        }
        /* factor, if the number of covalents bonds is decreased */
        double fB = 1.0;

        int numBond1 = 0;
        int numBond2 = 0;
        for (int i = 0; i < atomContainer.getBondCount(); i++) {
            if (atomContainer.getBond(i).getOrder() == IBond.Order.DOUBLE) numBond1 += 1;
            if (ac.getBond(i).getOrder() == IBond.Order.DOUBLE) numBond2 += 1;
        }

        if (numBond1 < /* > */numBond2) fB = 0.8;

        double fPlus = 1.0;
        if (totalNCharge1 == 0.0 && totalPCharge1 == 0.0) fPlus = 0.1;

        /* aromatic */
        double fA = 1.0;
        try {
            if (Aromaticity.cdkLegacy().apply(ac)) if (!Aromaticity.cdkLegacy().apply(atomContainer)) fA = 0.3;
        } catch (CDKException e) {
            e.printStackTrace();
        }
        logger.debug("return " + fQ * fB * fPlus * fA + "= sp:" + fQ + ", dc:" + fB + ", fPlus:" + fPlus + ", fA:" + fA);

        return fQ * fB * fPlus * fA;
    }
1121500
public static int getBondCount(IRingSet set) {
        int count = 0;
        for (IAtomContainer atomContainer : set.atomContainers()) {
            count += atomContainer.getBondCount();
        }
        return count;
    }
190830
private static int getDoubleBondNumber(IAtomContainer container) {
        int doubleNumber = 0;
        for (IBond bond : container.bonds()) {
            if (bond.getOrder().equals(IBond.Order.DOUBLE) || bond.getOrder().equals(IBond.Order.TRIPLE))
                doubleNumber++;
        }
        return doubleNumber;
    }
681353
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        int atomCount = 0;

        if (container == null) {
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                    (int) Double.NaN), getDescriptorNames(), new CDKException("The supplied AtomContainer was NULL"));
        }

        if (container.getAtomCount() == 0) {
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                    (int) Double.NaN), getDescriptorNames(), new CDKException(
                    "The supplied AtomContainer did not have any atoms"));
        }

        if (elementName.equals("*")) {
            for (int i = 0; i < container.getAtomCount(); i++) {
                // we assume that UNSET is equivalent to 0 implicit H's
                Integer hcount = container.getAtom(i).getImplicitHydrogenCount();
                if (hcount != CDKConstants.UNSET) atomCount += hcount;
            }
            atomCount += container.getAtomCount();
        } else if (elementName.equals("H")) {
            for (int i = 0; i < container.getAtomCount(); i++) {
                if (container.getAtom(i).getSymbol().equals(elementName)) {
                    atomCount += 1;
                } else {
                    // we assume that UNSET is equivalent to 0 implicit H's
                    Integer hcount = container.getAtom(i).getImplicitHydrogenCount();
                    if (hcount != CDKConstants.UNSET) atomCount += hcount;
                }
            }
        } else {
            for (int i = 0; i < container.getAtomCount(); i++) {
                if (container.getAtom(i).getSymbol().equals(elementName)) {
                    atomCount += 1;
                }
            }
        }

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                atomCount), getDescriptorNames());
    }
1111957
public double calculateKJMeanMolecularPolarizability(IAtomContainer atomContainer) {
        double polarizabilitiy = 0;
        IAtomContainer acH = atomContainer.getBuilder().newInstance(IAtomContainer.class, atomContainer);
        addExplicitHydrogens(acH);
        for (int i = 0; i < acH.getAtomCount(); i++) {
            polarizabilitiy += getKJPolarizabilityFactor(acH, acH.getAtom(i));
        }
        return polarizabilitiy;
    }
1338833
public static double getBondLengthMedian(final IAtomContainer container) {
        if (container.getBondCount() == 0) throw new IllegalArgumentException("Container has no bonds.");
        int nBonds = 0;
        double[] lengths = new double[container.getBondCount()];
        for (int i = 0; i < container.getBondCount(); i++) {
            final IBond bond = container.getBond(i);
            final IAtom atom1 = bond.getBegin();
            final IAtom atom2 = bond.getEnd();
            Point2d p1 = atom1.getPoint2d();
            Point2d p2 = atom2.getPoint2d();
            if (p1 == null || p2 == null)
                throw new IllegalArgumentException("An atom has no 2D coordinates.");
            if (p1.x != p2.x || p1.y != p2.y)
                lengths[nBonds++] = p1.distance(p2);
        }
        Arrays.sort(lengths, 0, nBonds);
        return lengths[nBonds / 2];
    }
1145732
public IAtomContainer getCyclicFragmentsContainer() {
        IAtomContainer fragContainer = this.molecule.getBuilder().newInstance(IAtomContainer.class);
        IAtomContainer spt = getSpanningTree();

        for (int i = 0; i < totalEdgeCount; i++)
            if (!bondsInTree[i]) {
                IRing ring = getRing(spt, molecule.getBond(i));
                for (int b = 0; b < ring.getBondCount(); b++) {
                    IBond ringBond = ring.getBond(b);
                    if (!fragContainer.contains(ringBond)) {
                        for (int atomCount = 0; atomCount < ringBond.getAtomCount(); atomCount++) {
                            IAtom atom = ringBond.getAtom(atomCount);
                            if (!fragContainer.contains(atom)) {
                                atom.setFlag(CDKConstants.ISINRING, true);
                                fragContainer.addAtom(atom);
                            }
                        }
                        fragContainer.addBond(ringBond);
                    }
                }
            }
        return fragContainer;
    }
38094
public static int markRingAtomsAndBonds(IAtomContainer mol) {
        EdgeToBondMap bonds = EdgeToBondMap.withSpaceFor(mol);
        return markRingAtomsAndBonds(mol, GraphUtil.toAdjList(mol, bonds), bonds);
    }
246501
public static void convertImplicitToExplicitHydrogens(IAtomContainer atomContainer) {
        List<IAtom> hydrogens = new ArrayList<IAtom>();
        List<IBond> newBonds = new ArrayList<IBond>();

        // store a single explicit hydrogen of each original neighbor
        Map<IAtom, IAtom> hNeighbor = Maps.newHashMapWithExpectedSize(atomContainer.getAtomCount());

        for (IAtom atom : atomContainer.atoms()) {
            if (!atom.getSymbol().equals("H")) {
                Integer hCount = atom.getImplicitHydrogenCount();
                if (hCount != null) {
                    for (int i = 0; i < hCount; i++) {

                        IAtom hydrogen = atom.getBuilder().newInstance(IAtom.class, "H");
                        hydrogen.setAtomTypeName("H");
                        hydrogen.setImplicitHydrogenCount(0);
                        hydrogens.add(hydrogen);
                        newBonds.add(atom.getBuilder().newInstance(IBond.class, atom, hydrogen,
                                Order.SINGLE));

                        if (hNeighbor.get(atom) == null) hNeighbor.put(atom, hydrogen);

                    }
                    atom.setImplicitHydrogenCount(0);
                }
            }
        }
        for (IAtom atom : hydrogens)
            atomContainer.addAtom(atom);
        for (IBond bond : newBonds)
            atomContainer.addBond(bond);

        // update stereo elements with an implicit part
        List<IStereoElement> stereos = new ArrayList<>();
        for (IStereoElement stereo : atomContainer.stereoElements()) {
            if (stereo instanceof ITetrahedralChirality) {
                ITetrahedralChirality tc = (ITetrahedralChirality) stereo;

                IAtom   focus    = tc.getFocus();
                IAtom[] carriers = tc.getCarriers().toArray(new IAtom[4]);
                IAtom   hydrogen = hNeighbor.get(focus);

                // in sulfoxide - the implicit part of the tetrahedral centre
                // is a lone pair

                if (hydrogen != null) {
                    replaceAtom(carriers, focus, hydrogen);
                    stereos.add(new TetrahedralChirality(focus, carriers, tc.getStereo()));
                } else {
                    stereos.add(stereo);
                }
            } else if (stereo instanceof ExtendedTetrahedral) {
                ExtendedTetrahedral tc = (ExtendedTetrahedral) stereo;

                IAtom   focus    = tc.getFocus();
                IAtom[] carriers = tc.getCarriers().toArray(new IAtom[4]);
                IAtom[] ends     = ExtendedTetrahedral.findTerminalAtoms(atomContainer, focus);
                IAtom   h1       = hNeighbor.get(ends[0]);
                IAtom   h2       = hNeighbor.get(ends[1]);
                if (h1 != null || h2 != null) {
                    if (h1 != null)
                        replaceAtom(carriers, ends[0], h1);
                    if (h2 != null)
                        replaceAtom(carriers, ends[1], h2);
                    stereos.add(new ExtendedTetrahedral(focus, carriers, tc.getConfigOrder()));
                } else {
                    stereos.add(stereo);
                }
            } else {
                stereos.add(stereo);
            }
        }
        atomContainer.setStereoElements(stereos);

    }