/// <summary>
        /// Calculates the eccentric connectivity
        /// </summary>
        /// <returns>A <see cref="Result"/> value representing the eccentric connectivity index</returns>
        public Result Calculate(IAtomContainer container)
        {
            container = AtomContainerManipulator.RemoveHydrogens(container);

            var natom   = container.Atoms.Count;
            var admat   = AdjacencyMatrix.GetMatrix(container);
            var distmat = PathTools.ComputeFloydAPSP(admat);

            int eccenindex = 0;

            for (int i = 0; i < natom; i++)
            {
                int max = -1;
                for (int j = 0; j < natom; j++)
                {
                    if (distmat[i][j] > max)
                    {
                        max = distmat[i][j];
                    }
                }
                var degree = container.GetConnectedBonds(container.Atoms[i]).Count();
                eccenindex += max * degree;
            }
            return(new Result(eccenindex));
        }
示例#2
0
        /// <summary>
        /// Calculate the Wiener numbers.
        /// </summary>
        /// <returns>wiener numbers as array of 2 doubles</returns>
        public Result Calculate(IAtomContainer container)
        {
            // RemoveHydrogens does not break container
            var matr = ConnectionMatrix.GetMatrix(AtomContainerManipulator.RemoveHydrogens(container));

            int wienerPathNumber     = 0; //wienerPath
            int wienerPolarityNumber = 0; //wienerPol

            var distances = PathTools.ComputeFloydAPSP(matr);

            int partial;

            for (int i = 0; i < distances.Length; i++)
            {
                for (int j = 0; j < distances.Length; j++)
                {
                    partial           = distances[i][j];
                    wienerPathNumber += partial;
                    if (partial == 3)
                    {
                        wienerPolarityNumber += 1;
                    }
                }
            }

            return(new Result((double)wienerPathNumber / 2, (double)wienerPolarityNumber / 2));
        }
        /// <summary>
        /// Constructor for the TopologicalEquivalentClass object.
        /// </summary>
        public EquivalentClassPartitioner(IAtomContainer atomContainer)
        {
            adjaMatrix  = ConnectionMatrix.GetMatrix(atomContainer);
            apspMatrix  = PathTools.ComputeFloydAPSP(adjaMatrix);
            layerNumber = 1;
            nodeNumber  = atomContainer.Atoms.Count;

            for (int i = 1; i < atomContainer.Atoms.Count; i++)
            {
                for (int j = 0; j < i; j++)
                {
                    // define the number of layer equal to the longest path obtained
                    // by calculating the all-pair-shortest path
                    if (apspMatrix[i][j] > layerNumber)
                    {
                        layerNumber = apspMatrix[i][j];
                    }
                    // correct adjacency matrix to consider aromatic bonds as such
                    if (adjaMatrix[i][j] > 0)
                    {
                        IBond bond   = atomContainer.GetBond(atomContainer.Atoms[i], atomContainer.Atoms[j]);
                        bool  isArom = bond.IsAromatic;
                        adjaMatrix[i][j] = (isArom) ? 1.5 : adjaMatrix[i][j];
                        adjaMatrix[j][i] = adjaMatrix[i][j];
                    }
                }
            }
            nodeMatrix = Arrays.CreateJagged <double>(nodeNumber, layerNumber + 1);
            bondMatrix = Arrays.CreateJagged <double>(nodeNumber, layerNumber);
            weight     = new double[nodeNumber + 1];
        }
示例#4
0
        /// <summary>
        /// Returns the topological matrix for the given AtomContainer.
        /// </summary>
        /// <param name="container">The AtomContainer for which the matrix is calculated</param>
        /// <returns>A topological matrix representating this AtomContainer</returns>
        public static int[][] GetMatrix(IAtomContainer container)
        {
            int[][] conMat        = AdjacencyMatrix.GetMatrix(container);
            int[][] topolDistance = PathTools.ComputeFloydAPSP(conMat);

            return(topolDistance);
        }
示例#5
0
        /// <summary>
        /// This method calculate the ATS Autocorrelation descriptor.
        /// </summary>
        public Result Calculate(IAtomContainer container)
        {
            container = (IAtomContainer)container.Clone();

            AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(container);
            var hAdder = CDK.HydrogenAdder;

            hAdder.AddImplicitHydrogens(container);
            AtomContainerManipulator.ConvertImplicitToExplicitHydrogens(container);
            Aromaticity.CDKLegacy.Apply(container);

            // get the distance matrix for pol calcs as well as for later on
            var distancematrix = PathTools.ComputeFloydAPSP(AdjacencyMatrix.GetMatrix(container));

            var w                 = Listpolarizability(container, distancematrix);
            var natom             = container.Atoms.Count;
            var polarizabilitySum = new double[5];

            for (int k = 0; k < 5; k++)
            {
                for (int i = 0; i < natom; i++)
                {
                    if (container.Atoms[i].AtomicNumber.Equals(AtomicNumbers.H))
                    {
                        continue;
                    }
                    for (int j = 0; j < natom; j++)
                    {
                        if (container.Atoms[j].AtomicNumber.Equals(AtomicNumbers.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;
                }
            }
            return(new Result(polarizabilitySum));
        }
示例#6
0
        /// <summary>
        /// Search an aliphatic molecule for the longest chain. This is the method to
        /// be used if there are no rings in the molecule and you want to layout the
        /// longest chain in the molecule as a starting point of the structure diagram
        /// generation.
        /// </summary>
        /// <param name="molecule">The molecule to be search for the longest unplaced chain</param>
        /// <returns>An AtomContainer holding the longest chain.</returns>
        /// <exception cref="NoSuchAtomException">Description of the Exception</exception>
        public static IAtomContainer GetInitialLongestChain(IAtomContainer molecule)
        {
            Debug.WriteLine("Start of GetInitialLongestChain()");
            var conMat = ConnectionMatrix.GetMatrix(molecule);

            Debug.WriteLine("Computing all-pairs-shortest-paths");
            var   apsp          = PathTools.ComputeFloydAPSP(conMat);
            int   maxPathLength = 0;
            int   bestStartAtom = -1;
            int   bestEndAtom   = -1;
            IAtom atom          = null;
            IAtom startAtom     = null;

            for (int f = 0; f < apsp.Length; f++)
            {
                atom = molecule.Atoms[f];
                if (molecule.GetConnectedBonds(atom).Count() == 1)
                {
                    for (int g = 0; g < apsp.Length; g++)
                    {
                        if (apsp[f][g] > maxPathLength)
                        {
                            maxPathLength = apsp[f][g];
                            bestStartAtom = f;
                            bestEndAtom   = g;
                        }
                    }
                }
            }
            Debug.WriteLine($"Longest chain in molecule is of length {maxPathLength} between atoms {bestStartAtom + 1} and {bestEndAtom + 1}");

            startAtom = molecule.Atoms[bestStartAtom];
            var path = molecule.Builder.NewAtomContainer();

            path.Atoms.Add(startAtom);
            path = GetLongestUnplacedChain(molecule, startAtom);
            Debug.WriteLine("End of GetInitialLongestChain()");
            return(path);
        }
示例#7
0
        public static double[] GetAtomWeights(IAtomContainer atomContainer)
        {
            IAtom atom, headAtom, endAtom;
            int   headAtomPosition, endAtomPosition;

            //int k = 0;
            double[]   weightArray = new double[atomContainer.Atoms.Count];
            double[][] adjaMatrix  = ConnectionMatrix.GetMatrix(atomContainer);

            int[][] apspMatrix = PathTools.ComputeFloydAPSP(adjaMatrix);
            int[]   atomLayers = GetAtomLayers(apspMatrix);

            int[] valenceSum;
            int[] interLayerBondSum;

            Debug.WriteLine("adjacency matrix: ");
            DisplayMatrix(adjaMatrix);
            Debug.WriteLine("all-pairs-shortest-path matrix: ");
            DisplayMatrix(apspMatrix);
            Debug.WriteLine("atom layers: ");
            DisplayArray(atomLayers);

            for (int i = 0; i < atomContainer.Atoms.Count; i++)
            {
                atom = atomContainer.Atoms[i];

                valenceSum = new int[atomLayers[i]];
                for (int v = 0; v < valenceSum.Length; v++)
                {
                    valenceSum[v] = 0;
                }

                interLayerBondSum = new int[atomLayers[i] - 1];
                for (int v = 0; v < interLayerBondSum.Length; v++)
                {
                    interLayerBondSum[v] = 0;
                }

                //weightArray[k] = atom.GetValenceElectronsCount() - atom.GetHydrogenCount(); // method unfinished
                if (AtomicNumbers.O.Equals(atom.AtomicNumber))
                {
                    weightArray[i] = 6 - atom.ImplicitHydrogenCount.Value;
                }
                else
                {
                    weightArray[i] = 4 - atom.ImplicitHydrogenCount.Value;
                }

                for (int j = 0; j < apspMatrix.Length; j++)
                {
                    if (string.Equals("O", atomContainer.Atoms[j].Symbol, StringComparison.Ordinal))
                    {
                        valenceSum[apspMatrix[j][i]] += 6 - atomContainer.Atoms[j].ImplicitHydrogenCount.Value;
                    }
                    else
                    {
                        valenceSum[apspMatrix[j][i]] += 4 - atomContainer.Atoms[j].ImplicitHydrogenCount.Value;
                    }
                }

                var bonds = atomContainer.Bonds;
                foreach (var bond in bonds)
                {
                    headAtom = bond.Begin;
                    endAtom  = bond.End;

                    headAtomPosition = atomContainer.Atoms.IndexOf(headAtom);
                    endAtomPosition  = atomContainer.Atoms.IndexOf(endAtom);

                    if (Math.Abs(apspMatrix[i][headAtomPosition] - apspMatrix[i][endAtomPosition]) == 1)
                    {
                        int       min   = Math.Min(apspMatrix[i][headAtomPosition], apspMatrix[i][endAtomPosition]);
                        BondOrder order = bond.Order;
                        interLayerBondSum[min] += order.IsUnset() ? 0 : order.Numeric();
                    }
                }

                for (int j = 0; j < interLayerBondSum.Length; j++)
                {
                    weightArray[i] += interLayerBondSum[j] * valenceSum[j + 1] * Math.Pow(10, -(j + 1));
                }

                Debug.WriteLine("valence sum: ");
                DisplayArray(valenceSum);
                Debug.WriteLine("inter-layer bond sum: ");
                DisplayArray(interLayerBondSum);
            }

            Debug.WriteLine("weight array: ");
            DisplayArray(weightArray);

            return(weightArray);
        }
示例#8
0
        private static Result CalculateMain(IAtomContainer container, int nhigh, int nlow)
        {
            var iso    = CDK.IsotopeFactory;
            int nheavy = 0;

            // find number of heavy atoms
            nheavy += container.Atoms.Count(atom => !atom.AtomicNumber.Equals(AtomicNumbers.H));
            if (nheavy == 0)
            {
                throw new CDKException("No heavy atoms in the container");
            }

            var diagvalue = new double[nheavy];

            // get atomic mass weighted BCUT
            try
            {
                var counter = 0;
                foreach (var atom in container.Atoms.Where(atom => !atom.AtomicNumber.Equals(AtomicNumbers.H)))
                {
                    diagvalue[counter] = iso.GetMajorIsotope(atom.AtomicNumber).ExactMass.Value;
                    counter++;
                }
            }
            catch (Exception e)
            {
                throw new CDKException($"Could not calculate weight: {e.Message}", e);
            }

            double[] eval1, eval2, eval3;
            {
                var burdenMatrix = BurdenMatrix.EvalMatrix(container, diagvalue);
                if (HasUndefined(burdenMatrix))
                {
                    throw new CDKException("Burden matrix has undefined values");
                }
                var matrix = Matrix <double> .Build.DenseOfColumnArrays(burdenMatrix);

                var eigenDecomposition = matrix.Evd().EigenValues;
                eval1 = eigenDecomposition.Select(n => n.Real).ToArray();
            }
            try
            {
                // get charge weighted BCUT
                CDK.LonePairElectronChecker.Saturate(container);
                var charges = new double[container.Atoms.Count];
                var peoe    = new GasteigerMarsiliPartialCharges();
                peoe.AssignGasteigerMarsiliSigmaPartialCharges(container, true);
                for (int i = 0; i < container.Atoms.Count; i++)
                {
                    charges[i] += container.Atoms[i].Charge.Value;
                }
                for (int i = 0; i < container.Atoms.Count; i++)
                {
                    container.Atoms[i].Charge = charges[i];
                }
            }
            catch (Exception e)
            {
                throw new CDKException("Could not calculate partial charges: " + e.Message, e);
            }
            {
                var counter = 0;
                foreach (var atom in container.Atoms.Where(atom => !atom.AtomicNumber.Equals(AtomicNumbers.H)))
                {
                    diagvalue[counter++] = atom.Charge.Value;
                }
            }
            {
                var burdenMatrix = BurdenMatrix.EvalMatrix(container, diagvalue);
                if (HasUndefined(burdenMatrix))
                {
                    throw new CDKException("Burden matrix has undefined values");
                }
                var matrix = Matrix <double> .Build.DenseOfColumnArrays(burdenMatrix);

                var eigenDecomposition = matrix.Evd().EigenValues;
                eval2 = eigenDecomposition.Select(n => n.Real).ToArray();
            }

            var topoDistance = PathTools.ComputeFloydAPSP(AdjacencyMatrix.GetMatrix(container));

            // get polarizability weighted BCUT
            {
                var counter = 0;
                foreach (var atom in container.Atoms.Where(atom => !atom.AtomicNumber.Equals(AtomicNumbers.H)))
                {
                    diagvalue[counter++] = Polarizability.CalculateGHEffectiveAtomPolarizability(container, atom, false, topoDistance);
                }
            }
            {
                var burdenMatrix = BurdenMatrix.EvalMatrix(container, diagvalue);
                if (HasUndefined(burdenMatrix))
                {
                    throw new CDKException("Burden matrix has undefined values");
                }
                var matrix = Matrix <double> .Build.DenseOfColumnArrays(burdenMatrix);

                var eigenDecomposition = matrix.Evd().EigenValues;
                eval3 = eigenDecomposition.Select(n => n.Real).ToArray();
            }

            // return only the n highest & lowest eigenvalues
            int lnlow, lnhigh, enlow, enhigh;

            if (nlow > nheavy)
            {
                lnlow = nheavy;
                enlow = nlow - nheavy;
            }
            else
            {
                lnlow = nlow;
                enlow = 0;
            }

            if (nhigh > nheavy)
            {
                lnhigh = nheavy;
                enhigh = nhigh - nheavy;
            }
            else
            {
                lnhigh = nhigh;
                enhigh = 0;
            }

            var retval = new List <double>((lnlow + enlow + lnhigh + enhigh) * 3);

            for (int i = 0; i < lnlow; i++)
            {
                retval.Add(eval1[i]);
            }
            for (int i = 0; i < enlow; i++)
            {
                retval.Add(double.NaN);
            }
            for (int i = 0; i < lnhigh; i++)
            {
                retval.Add(eval1[eval1.Length - i - 1]);
            }
            for (int i = 0; i < enhigh; i++)
            {
                retval.Add(double.NaN);
            }

            for (int i = 0; i < lnlow; i++)
            {
                retval.Add(eval2[i]);
            }
            for (int i = 0; i < enlow; i++)
            {
                retval.Add(double.NaN);
            }
            for (int i = 0; i < lnhigh; i++)
            {
                retval.Add(eval2[eval2.Length - i - 1]);
            }
            for (int i = 0; i < enhigh; i++)
            {
                retval.Add(double.NaN);
            }

            for (int i = 0; i < lnlow; i++)
            {
                retval.Add(eval3[i]);
            }
            for (int i = 0; i < enlow; i++)
            {
                retval.Add(double.NaN);
            }
            for (int i = 0; i < lnhigh; i++)
            {
                retval.Add(eval3[eval3.Length - i - 1]);
            }
            for (int i = 0; i < enhigh; i++)
            {
                retval.Add(double.NaN);
            }

            return(new Result(retval, nhigh, nlow));
        }
示例#9
0
 public Calculator(IAtomContainer container)
 {
     this.container = AtomContainerManipulator.RemoveHydrogens(container); // it returns clone
     adjMatrix      = AdjacencyMatrix.GetMatrix(container);
     tdist          = PathTools.ComputeFloydAPSP(adjMatrix);
 }