The AlogP descriptor.

TODO Ideally we should explicit H addition should be cached

@param atomContainer the molecule to calculate on
@return the result of the calculation
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());
    }
163485
@Override
    public IAtomContainer get(int i) {
        Point3d[] tmp = coordinates.get(i);
        for (int j = 0; j < atomContainer.getAtomCount(); j++) {
            IAtom atom = atomContainer.getAtom(j);
            atom.setPoint3d(tmp[j]);
        }
        return atomContainer;
    }
502659
public static IAtomContainer anonymise(IAtomContainer src) {

        IChemObjectBuilder builder = src.getBuilder();

        IAtom[] atoms = new IAtom[src.getAtomCount()];
        IBond[] bonds = new IBond[src.getBondCount()];

        for (int i = 0; i < atoms.length; i++) {
            atoms[i] = builder.newAtom();
            atoms[i].setAtomicNumber(6);
            atoms[i].setSymbol("C");
            atoms[i].setImplicitHydrogenCount(0);
            IAtom srcAtom = src.getAtom(i);
            if (srcAtom.getPoint2d() != null)
                atoms[i].setPoint2d(new Point2d(srcAtom.getPoint2d()));
            if (srcAtom.getPoint3d() != null)
                atoms[i].setPoint3d(new Point3d(srcAtom.getPoint3d()));
        }
        for (int i = 0; i < bonds.length; i++) {
            IBond bond = src.getBond(i);
            int u = src.indexOf(bond.getBegin());
            int v = src.indexOf(bond.getEnd());
            bonds[i] = builder.newInstance(IBond.class, atoms[u], atoms[v]);
        }

        IAtomContainer dest = builder.newInstance(IAtomContainer.class, 0, 0, 0, 0);
        dest.setAtoms(atoms);
        dest.setBonds(bonds);
        return dest;
    }
985556
static public SimpleGraph getMoleculeGraph(IAtomContainer molecule) {
        SimpleGraph graph = new SimpleGraph();
        for (int i = 0; i < molecule.getAtomCount(); i++) {
            IAtom atom = molecule.getAtom(i);
            graph.addVertex(atom);
        }

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

            /*
             * int order = (int) bond.getOrder(); for (int j=0; j<order; j++) {
             * graph.addEdge(bond.getAtoms()[0], bond.getAtoms()[1]); }
             */
            graph.addEdge(bond.getBegin(), bond.getEnd());
        }
        return graph;
    }
1269548
public static IAtomContainer makeDeepCopy(IAtomContainer container) {

        IAtomContainer newAtomContainer = container.getBuilder().newInstance(IAtomContainer.class);
        //      Deep copy of the Atoms
        IAtom[] atoms = copyAtoms(container, newAtomContainer);

        //      Deep copy of the bonds
        copyBonds(atoms, container, newAtomContainer);

        //      Deep copy of the LonePairs
        for (int index = 0; index < container.getLonePairCount(); index++) {
            if (container.getAtom(index).getSymbol().equalsIgnoreCase("R")
                    || container.getAtom(index).getSymbol().equalsIgnoreCase("A")) {
                newAtomContainer.addLonePair(container.getBuilder().newInstance(ILonePair.class,
                        container.getAtom(index)));
            } else {
                newAtomContainer.addLonePair(index);
            }
        }

        for (int index = 0; index < container.getSingleElectronCount(); index++) {
            newAtomContainer.addSingleElectron(index);
        }
        newAtomContainer.addProperties(container.getProperties());
        newAtomContainer.setFlags(container.getFlags());
        newAtomContainer.setID(container.getID());
        newAtomContainer.notifyChanged();

        return newAtomContainer;
    }
290202
@Override
    public DescriptorValue calculate(IAtom atom, IAtomContainer container) {
        int atomValence = AtomValenceTool.getValence(atom);
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new IntegerResult(
                atomValence), getDescriptorNames());
    }
654835
public static int getVertexCountAtDistance(IAtomContainer atomContainer, int distance) {
        int natom = atomContainer.getAtomCount();

        int[][] admat = AdjacencyMatrix.getMatrix(atomContainer);
        int[][] distanceMatrix = computeFloydAPSP(admat);

        int matches = 0;

        for (int i = 0; i < natom; i++) {
            for (int j = 0; j < natom; j++) {
                if (distanceMatrix[i][j] == distance) matches++;
            }
        }
        return matches / 2;
    }
909233
public static IAtomContainer convertToAtomContainer(IRingSet ringSet) {
        IRing ring = (IRing) ringSet.getAtomContainer(0);
        if (ring == null) return null;
        IAtomContainer ac = ring.getBuilder().newInstance(IAtomContainer.class);
        for (int i = 0; i < ringSet.getAtomContainerCount(); i++) {
            ring = (IRing) ringSet.getAtomContainer(i);
            for (int r = 0; r < ring.getBondCount(); r++) {
                IBond bond = ring.getBond(r);
                if (!ac.contains(bond)) {
                    for (int j = 0; j < bond.getAtomCount(); j++) {
                        ac.addAtom(bond.getAtom(j));
                    }
                    ac.addBond(bond);
                }
            }
        }
        return ac;
    }
40566
public static int getTotalFormalCharge(IAtomContainer atomContainer) {
        int chargeP = getTotalNegativeFormalCharge(atomContainer);
        int chargeN = getTotalPositiveFormalCharge(atomContainer);

        return chargeP + chargeN;
    }
555801
@Override
    public DescriptorValue calculate(IAtom first, IAtom second, IAtomContainer atomContainer) {
        IAtomContainer ac;
        try {
            ac = (IAtomContainer) atomContainer.clone();
        } catch (CloneNotSupportedException e) {
            return getDummyDescriptorValue(e);
        }
        IAtom clonedFirst = ac.getAtom(atomContainer.indexOf(first));
        IAtom clonedSecond = ac.getAtom(atomContainer.indexOf(first));

        IAtomContainer mol = ac.getBuilder().newInstance(IAtomContainer.class, ac);
        if (checkAromaticity) {
            try {
                AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol);
                Aromaticity.cdkLegacy().apply(mol);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }
        }
        boolean piContact = false;
        int counter = 0;

        if (acold != ac) {
            acold = ac;
            acSet = ConjugatedPiSystemsDetector.detect(mol);
        }
        java.util.Iterator<IAtomContainer> detected = acSet.atomContainers().iterator();

        List<IAtom> neighboorsFirst = mol.getConnectedAtomsList(clonedFirst);
        List<IAtom> neighboorsSecond = mol.getConnectedAtomsList(clonedSecond);

        while (detected.hasNext()) {
            IAtomContainer detectedAC = detected.next();
            if (detectedAC.contains(clonedFirst) && detectedAC.contains(clonedSecond)) {
                counter += 1;
                break;
            }
            if (isANeighboorsInAnAtomContainer(neighboorsFirst, detectedAC)
                    && isANeighboorsInAnAtomContainer(neighboorsSecond, detectedAC)) {
                counter += 1;
                break;
            }
        }

        if (counter > 0) {
            piContact = true;
        }
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new BooleanResult(
                piContact), getDescriptorNames());
    }
80942
public double getPolarizabilitiyFactorForAtom(IAtomContainer atomContainer, IAtom atom) {
        IAtomContainer acH = atomContainer.getBuilder().newInstance(IAtomContainer.class, atomContainer);
        addExplicitHydrogens(acH);
        return getKJPolarizabilityFactor(acH, atom);
    }
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;
    }
65956
public static IAtomContainer getAtomContainer(String formulaString, IChemObjectBuilder builder) {
        return MolecularFormulaManipulator.getAtomContainer(MolecularFormulaManipulator.getMolecularFormula(
                formulaString, builder));
    }
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());
    }
84416
@Override
    public DescriptorValue calculate(IAtomContainer mol) {
        try {
            mol = mol.clone();
        } catch (CloneNotSupportedException ex) {
        }
        double polar = 0, weight = 0;
        try {
            // type & assign implicit hydrogens
            IChemObjectBuilder builder = mol.getBuilder();
            CDKAtomTypeMatcher matcher = CDKAtomTypeMatcher.getInstance(builder);
            for (IAtom atom : mol.atoms()) {
                IAtomType type = matcher.findMatchingAtomType(mol, atom);
                AtomTypeManipulator.configure(atom, type);
            }
            CDKHydrogenAdder adder = CDKHydrogenAdder.getInstance(builder);
            adder.addImplicitHydrogens(mol);

            // polar surface area: chain it off the TPSADescriptor
            TPSADescriptor tpsa = new TPSADescriptor();
            DescriptorValue value = tpsa.calculate(mol);
            polar = ((DoubleResult) value.getValue()).doubleValue();

            //  molecular weight
            for (IAtom atom : mol.atoms()) {
                weight += Isotopes.getInstance().getMajorIsotope(atom.getSymbol()).getExactMass();
                Integer hcount = atom.getImplicitHydrogenCount();
                if (hcount != CDKConstants.UNSET) weight += hcount * 1.00782504;
            }
        } catch (CDKException | IOException exception) {
            return getDummyDescriptorValue(exception);
        }

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(
                weight == 0 ? 0 : polar / weight), getDescriptorNames());
    }
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);

    }
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;
    }