Calculates the descriptor value using the {@link VABCVolume} class.

@param atomContainer The {@link IAtomContainer} whose volume is to be calculated
@return A double containing the volume
558109
@Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        double volume;
        try {
            // clone: don't mod original
            volume = VABCVolume.calculate(clone(atomContainer));
        } catch (CDKException exception) {
            return getDummyDescriptorValue(exception);
        }

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(volume),
                getDescriptorNames());
    }
436796
@Override
    public void removeAtomContainer(IAtomContainer atomContainer) {
        for (int i = atomContainerCount - 1; i >= 0; i--) {
            if (atomContainers[i] == atomContainer) removeAtomContainer(i);
        }
    }
937840
public static double getTotalCharge(IAtomContainer atomContainer) {
        double charge = 0.0;
        for (IAtom atom : atomContainer.atoms()) {
            // we assume CDKConstant.UNSET is equal to 0
            Double thisCharge = atom.getCharge();
            if (thisCharge != CDKConstants.UNSET) charge += thisCharge;
        }
        return charge;
    }
768057
public static double getBondLengthMedian(final IAtomContainer container) {
        if (container.getBondCount() == 0) throw new IllegalArgumentException("Container has no bonds.");
        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();
            if (atom1.getPoint2d() == null || atom2.getPoint2d() == null)
                throw new IllegalArgumentException("An atom has no 2D coordinates.");
            lengths[i] = getLength2D(bond);
        }
        Arrays.sort(lengths);
        return lengths[lengths.length / 2];
    }
340793
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        IRingSet rs;
        try {
            AllRingsFinder arf = new AllRingsFinder();
            rs = arf.findAllRings(container);
        } catch (Exception e) {
            return getDummyDescriptorValue(new CDKException("Could not find all rings: " + e.getMessage()));
        }

        String[] fragment = new String[container.getAtomCount()];
        EStateAtomTypeMatcher eStateMatcher = new EStateAtomTypeMatcher();
        eStateMatcher.setRingSet(rs);

        for (IAtomContainer ring : rs.atomContainers()) {
            boolean arom = true;
            for (IBond bond : ring.bonds()) {
                if (!bond.isAromatic()) {
                    arom = false;
                    break;
                }
            }
            ring.setFlag(CDKConstants.ISAROMATIC, arom);
        }

        for (int i = 0; i < container.getAtomCount(); i++) {
            IAtomType atomType = eStateMatcher.findMatchingAtomType(container, container.getAtom(i));
            if (atomType == null) {
                fragment[i] = null;
            } else {
                fragment[i] = atomType.getAtomTypeName();
            }
        }

        double[] ret = new double[0];
        try {
            ret = calculate(container, fragment, rs);
        } catch (CDKException e) {
            e.printStackTrace();
            return getDummyDescriptorValue(new CDKException(e.getMessage()));
        }

        DoubleArrayResult results = new DoubleArrayResult();
        results.add(ret[0]);
        results.add(ret[1]);
        results.add(ret[2]);

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), results,
                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;
    }
288866
@Override
    public DescriptorValue calculate(IAtom atom, IAtomContainer container) {
        int period;
        String symbol = atom.getSymbol();
        period = periodicTable.get(symbol);
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(period),
                                   NAMES);
    }
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());
    }
858365
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        IAtomContainer molecule;
        try {
            molecule = (IAtomContainer) container.clone();
        } catch (CloneNotSupportedException e) {
            return getDummyDescriptorValue(new CDKException("Error occurred during clone " + e));
        }

        // add H's in case they're not present
        try {
            CDKAtomTypeMatcher matcher = CDKAtomTypeMatcher.getInstance(molecule.getBuilder());
            Iterator<IAtom> atoms = molecule.atoms().iterator();
            while (atoms.hasNext()) {
                IAtom atom = atoms.next();
                IAtomType type = matcher.findMatchingAtomType(molecule, atom);
                AtomTypeManipulator.configure(atom, type);
            }
            CDKHydrogenAdder hAdder = CDKHydrogenAdder.getInstance(molecule.getBuilder());
            hAdder.addImplicitHydrogens(molecule);
            AtomContainerManipulator.convertImplicitToExplicitHydrogens(molecule);
        } catch (Exception e) {
            return getDummyDescriptorValue(new CDKException("Could not add hydrogens: " + e.getMessage(), e));
        }

        // do aromaticity detecttion for calculating polarizability later on
        try {
            AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(molecule);
        } catch (CDKException e) {
            return getDummyDescriptorValue(new CDKException("Could not percieve atom types: " + e.getMessage(), e));
        }
        try {
            Aromaticity.cdkLegacy().apply(molecule);
        } catch (CDKException e) {
            return getDummyDescriptorValue(new CDKException("Could not percieve aromaticity: " + e.getMessage(), e));
        }

        // get the distance matrix for pol calcs as well as for later on
        int[][] distancematrix = PathTools.computeFloydAPSP(AdjacencyMatrix.getMatrix(molecule));

        try {
            double[] w = listpolarizability(molecule, distancematrix);
            int natom = molecule.getAtomCount();
            double[] polarizabilitySum = new double[5];

            for (int k = 0; k < 5; k++) {
                for (int i = 0; i < natom; i++) {
                    if (molecule.getAtom(i).getSymbol().equals("H")) continue;
                    for (int j = 0; j < natom; j++) {
                        if (molecule.getAtom(j).getSymbol().equals("H")) continue;
                        if (distancematrix[i][j] == k) {
                            polarizabilitySum[k] += w[i] * w[j];
                        } else
                            polarizabilitySum[k] += 0.0;
                    }
                }
                if (k > 0) polarizabilitySum[k] = polarizabilitySum[k] / 2;

            }
            DoubleArrayResult result = new DoubleArrayResult(5);
            for (double aPolarizabilitySum : polarizabilitySum) {
                result.add(aPolarizabilitySum);

            }

            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                    getDescriptorNames());

        } catch (Exception ex) {
            return getDummyDescriptorValue(new CDKException("Error while calculating the ATSpolarizabilty descriptor: "
                    + ex.getMessage(), ex));
        }
    }
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;
    }
428430
@Override
    public DescriptorValue calculate(IAtom atom, IAtomContainer container) {
        double value;

        try {
            int i = container.indexOf(atom);
            if (i < 0) throw new CDKException("atom was not a memeber of the provided container");

            // don't modify the original
            container = container.clone();
            atom = container.getAtom(i);

            AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(container);
            LonePairElectronChecker lpcheck = new LonePairElectronChecker();
            lpcheck.saturate(container);
        } catch (CDKException | CloneNotSupportedException e) {
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(
                    Double.NaN), NAMES, null);
        }

        value = db.extractAffinity(container, atom);
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(value),
                                   NAMES);

    }
1156742
public static double[] get2DDimension(IAtomContainer atomCon) {
        double[] minmax = getMinMax(atomCon);
        double maxX = minmax[2];
        double maxY = minmax[3];
        double minX = minmax[0];
        double minY = minmax[1];
        return new double[]{maxX - minX, maxY - minY};
    }
380415
public static IAtomContainer getRelevantAtomContainer(IChemModel chemModel, IAtom atom) {
        IAtomContainer result = null;
        if (chemModel.getMoleculeSet() != null) {
            IAtomContainerSet moleculeSet = chemModel.getMoleculeSet();
            result = MoleculeSetManipulator.getRelevantAtomContainer(moleculeSet, atom);
            if (result != null) {
                return result;
            }
        }
        if (chemModel.getReactionSet() != null) {
            IReactionSet reactionSet = chemModel.getReactionSet();
            return ReactionSetManipulator.getRelevantAtomContainer(reactionSet, atom);
        }
        if (chemModel.getCrystal() != null && chemModel.getCrystal().contains(atom)) {
            return chemModel.getCrystal();
        }
        if (chemModel.getRingSet() != null) {
            return AtomContainerSetManipulator.getRelevantAtomContainer(chemModel.getRingSet(), atom);
        }
        throw new IllegalArgumentException("The provided atom is not part of this IChemModel.");
    }
95591
@Override
    public DescriptorValue calculate(IAtomContainer ac) {
        ac = clone(ac); // don't mod original
        int rotatableBondsCount = 0;
        int degree0;
        int degree1;
        IRingSet ringSet;
        try {
            ringSet = new SpanningTree(ac).getBasicRings();
        } catch (NoSuchAtomException e) {
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                    (int) Double.NaN), getDescriptorNames(), e);
        }
        for (IBond bond : ac.bonds()) {
            if (ringSet.getRings(bond).getAtomContainerCount() > 0) {
                bond.setFlag(CDKConstants.ISINRING, true);
            }
        }
        for (IBond bond : ac.bonds()) {
            IAtom atom0 = bond.getBegin();
            IAtom atom1 = bond.getEnd();
            if (atom0.getSymbol().equals("H") || atom1.getSymbol().equals("H")) continue;
            if (bond.getOrder() == Order.SINGLE) {
                if ((BondManipulator.isLowerOrder(ac.getMaximumBondOrder(atom0), IBond.Order.TRIPLE))
                        && (BondManipulator.isLowerOrder(ac.getMaximumBondOrder(atom1), IBond.Order.TRIPLE))) {
                    if (!bond.getFlag(CDKConstants.ISINRING)) {

                        if (excludeAmides && (isAmide(atom0, atom1, ac) || isAmide(atom1, atom0, ac))) {
                            continue;
                        }

                        // if there are explicit H's we should ignore those bonds
                        degree0 = ac.getConnectedBondsCount(atom0) - getConnectedHCount(ac, atom0);
                        degree1 = ac.getConnectedBondsCount(atom1) - getConnectedHCount(ac, atom1);
                        if ((degree0 == 1) || (degree1 == 1)) {
                            if (includeTerminals) {
                                rotatableBondsCount += 1;
                            }
                        } else {
                            rotatableBondsCount += 1;
                        }
                    }
                }
            }
        }
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                rotatableBondsCount), getDescriptorNames());

    }
1142090
@Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        IAtomContainer container;
        try {
            container = (IAtomContainer) atomContainer.clone();
            container = AtomContainerManipulator.removeHydrogens(container);
        } catch (CloneNotSupportedException e) {
            DoubleArrayResult result = new DoubleArrayResult(5);
            for (int i = 0; i < 5; i++)
                result.add(Double.NaN);
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                    getDescriptorNames(), new CDKException("Error during cloner: " + e.getMessage(), e));
        }

        try {
            double[] w = listConvertion(container);
            int natom = container.getAtomCount();
            int[][] distancematrix = TopologicalMatrix.getMatrix(container);
            double[] masSum = new double[5];

            for (int k = 0; k < 5; k++) {
                for (int i = 0; i < natom; i++) {
                    for (int j = 0; j < natom; j++) {

                        if (distancematrix[i][j] == k) {
                            masSum[k] += w[i] * w[j];
                        } else
                            masSum[k] += 0.0;
                    }
                }
                if (k > 0) masSum[k] = masSum[k] / 2;

            }
            DoubleArrayResult result = new DoubleArrayResult(5);
            for (double aMasSum : masSum) {
                result.add(aMasSum);
            }

            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                    getDescriptorNames());

        } catch (IOException | ClassNotFoundException ex) {
            DoubleArrayResult result = new DoubleArrayResult(5);
            for (int i = 0; i < 5; i++)
                result.add(Double.NaN);
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                    getDescriptorNames(), new CDKException("Error while calculating the ATS_mass descriptor: "
                            + ex.getMessage(), ex));
        }
    }
80942
public double getPolarizabilitiyFactorForAtom(IAtomContainer atomContainer, IAtom atom) {
        IAtomContainer acH = atomContainer.getBuilder().newInstance(IAtomContainer.class, atomContainer);
        addExplicitHydrogens(acH);
        return getKJPolarizabilityFactor(acH, atom);
    }
218680
@Override
    public void add(IAtomContainer atomContainer) {
        if (atomContainer instanceof QueryAtomContainer) {
            for (int f = 0; f < atomContainer.getAtomCount(); f++) {
                if (!contains(atomContainer.getAtom(f))) {
                    addAtom(atomContainer.getAtom(f));
                }
            }
            for (int f = 0; f < atomContainer.getBondCount(); f++) {
                if (!contains(atomContainer.getBond(f))) {
                    addBond(atomContainer.getBond(f));
                }
            }
            for (int f = 0; f < atomContainer.getLonePairCount(); f++) {
                if (!contains(atomContainer.getLonePair(f))) {
                    addLonePair(atomContainer.getLonePair(f));
                }
            }
            for (int f = 0; f < atomContainer.getSingleElectronCount(); f++) {
                if (!contains(atomContainer.getSingleElectron(f))) {
                    addSingleElectron(atomContainer.getSingleElectron(f));
                }
            }
            notifyChanged();
        } else {
            throw new IllegalArgumentException("AtomContainer is not of type QueryAtomContainer");
        }
    }