/// <summary>
        /// A small help method that count how many bonds an atom has, regarding
        /// bonds due to its charge and to implicit hydrogens.
        /// </summary>
        /// <param name="atom">The atom to check</param>
        /// <param name="atomContainer">The atomContainer containing the atom</param>
        /// <returns>The number of bonds that the atom has</returns>
        private static double BondsUsed(IAtom atom, IAtomContainer atomContainer)
        {
            int bondsToAtom = 0;

            foreach (var bond in atomContainer.Bonds)
            {
                if (bond.Contains(atom))
                {
                    bondsToAtom += (int)BondManipulator.DestroyBondOrder(bond.Order);
                }
            }
            int implicitHydrogens;

            if (atom.ImplicitHydrogenCount == null || atom.ImplicitHydrogenCount == null)
            {
                // Will probably only work with group 13-18, and not for helium...
                if (atom.Valency == null || atom.Valency == null)
                {
                    throw new CDKException($"Atom {atom.AtomTypeName} has not got the valency set.");
                }
                if (atom.FormalNeighbourCount == null || atom.FormalNeighbourCount == null)
                {
                    throw new CDKException($"Atom {atom.AtomTypeName} has not got the formal neighbour count set.");
                }
                implicitHydrogens = (8 - atom.Valency.Value) - atom.FormalNeighbourCount.Value;
                Trace.TraceWarning($"Number of implicit hydrogens not set for atom {atom.AtomTypeName}. Estimated it to: {implicitHydrogens}");
            }
            else
            {
                implicitHydrogens = atom.ImplicitHydrogenCount.Value;
            }

            double charge;

            if (atom.Charge == null)
            {
                if (atom.FormalCharge == null)
                {
                    charge = 0;
                    Trace.TraceWarning($"Neither charge nor formal charge is set for atom {atom.AtomTypeName}. Estimate it to: 0");
                }
                else
                {
                    charge = atom.FormalCharge.Value;
                }
            }
            else
            {
                charge = atom.Charge.Value;
            }
            return(bondsToAtom - charge + implicitHydrogens);
        }
        /// <summary>
        /// This method is used if, by some reason, the bond order sum is not set
        /// for an atom.
        /// </summary>
        /// <param name="atom">The atom in question</param>
        /// <param name="mol">The molecule that the atom belongs to</param>
        /// <returns>The bond order sum</returns>
        private static double GetAtomBondOrderSum(IAtom atom, IAtomContainer mol)
        {
            double sum = 0;

            foreach (var bond in mol.Bonds)
            {
                if (bond.Contains(atom))
                {
                    sum += BondManipulator.DestroyBondOrder(bond.Order);
                }
            }

            return(sum);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns the connection matrix representation of this <see cref="IAtomContainer"/>.
        /// </summary>
        /// <param name="container">The <see cref="IAtomContainer"/> for which the matrix is calculated</param>
        /// <returns>A connection matrix representing this <see cref="IAtomContainer"/></returns>
        public static double[][] GetMatrix(IAtomContainer container)
        {
            IBond bond = null;
            int   indexAtom1;
            int   indexAtom2;

            double[][] conMat = Arrays.CreateJagged <double>(container.Atoms.Count, container.Atoms.Count);
            for (int f = 0; f < container.Bonds.Count; f++)
            {
                bond       = container.Bonds[f];
                indexAtom1 = container.Atoms.IndexOf(bond.Begin);
                indexAtom2 = container.Atoms.IndexOf(bond.End);
                conMat[indexAtom1][indexAtom2] = BondManipulator.DestroyBondOrder(bond.Order);
                conMat[indexAtom2][indexAtom1] = BondManipulator.DestroyBondOrder(bond.Order);
            }
            return(conMat);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Randomly chooses four atoms and alters the bonding
        /// pattern between them according to rules described
        /// in "Faulon, JCICS 1996, 36, 731".
        /// </summary>
        public virtual void Mutate(IAtomContainer ac)
        {
            Debug.WriteLine("RandomGenerator->Mutate() Start");
            int    nrOfAtoms = ac.Atoms.Count;
            int    x1 = 0, x2 = 0, y1 = 0, y2 = 0;
            double a11 = 0, a12 = 0, a22 = 0, a21 = 0;
            double b11 = 0, lowerborder = 0, upperborder = 0;

            IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null;
            IBond b1 = null, b2 = null, b3 = null, b4 = null;

            int[] choices       = new int[3];
            int   choiceCounter = 0;
            /* We need at least two non-zero bonds in order to be successful */
            int nonZeroBondsCounter = 0;

            do
            {
                do
                {
                    nonZeroBondsCounter = 0;
                    /* Randomly choose four distinct atoms */
                    do
                    {
                        // this yields numbers between 0 and (nrOfAtoms - 1)
                        x1 = (int)(random.NextDouble() * nrOfAtoms);
                        x2 = (int)(random.NextDouble() * nrOfAtoms);
                        y1 = (int)(random.NextDouble() * nrOfAtoms);
                        y2 = (int)(random.NextDouble() * nrOfAtoms);
                        Debug.WriteLine($"RandomGenerator->Mutate(): x1, x2, y1, y2: {x1}, {x2}, {y1}, {y2}");
                    } while (!(x1 != x2 && x1 != y1 && x1 != y2 && x2 != y1 && x2 != y2 && y1 != y2));
                    ax1 = ac.Atoms[x1];
                    ay1 = ac.Atoms[y1];
                    ax2 = ac.Atoms[x2];
                    ay2 = ac.Atoms[y2];
                    /* Get four bonds for these four atoms */

                    b1 = ac.GetBond(ax1, ay1);
                    if (b1 != null)
                    {
                        a11 = BondManipulator.DestroyBondOrder(b1.Order);
                        nonZeroBondsCounter++;
                    }
                    else
                    {
                        a11 = 0;
                    }

                    b2 = ac.GetBond(ax1, ay2);
                    if (b2 != null)
                    {
                        a12 = BondManipulator.DestroyBondOrder(b2.Order);
                        nonZeroBondsCounter++;
                    }
                    else
                    {
                        a12 = 0;
                    }

                    b3 = ac.GetBond(ax2, ay1);
                    if (b3 != null)
                    {
                        a21 = BondManipulator.DestroyBondOrder(b3.Order);
                        nonZeroBondsCounter++;
                    }
                    else
                    {
                        a21 = 0;
                    }

                    b4 = ac.GetBond(ax2, ay2);
                    if (b4 != null)
                    {
                        a22 = BondManipulator.DestroyBondOrder(b4.Order);
                        nonZeroBondsCounter++;
                    }
                    else
                    {
                        a22 = 0;
                    }
                    Debug.WriteLine($"RandomGenerator->Mutate()->The old bond orders: a11, a12, a21, a22: {a11}, {a12}, {a21}, {a22}");
                } while (nonZeroBondsCounter < 2);

                /* Compute the range for b11 (see Faulons formulae for details) */
                double[] cmax = { 0, a11 - a22, a11 + a12 - 3, a11 + a21 - 3 };
                double[] cmin = { 3, a11 + a12, a11 + a21, a11 - a22 + 3 };
                lowerborder = MathTools.Max(cmax);
                upperborder = MathTools.Min(cmin);
                /* Randomly choose b11 != a11 in the range max > r > min */
                Debug.WriteLine("*** New Try ***");
                Debug.WriteLine($"a11 = {a11}");
                Debug.WriteLine($"upperborder = {upperborder}");
                Debug.WriteLine($"lowerborder = {lowerborder}");
                choiceCounter = 0;
                for (double f = lowerborder; f <= upperborder; f++)
                {
                    if (f != a11)
                    {
                        choices[choiceCounter] = (int)f;
                        choiceCounter++;
                    }
                }
                if (choiceCounter > 0)
                {
                    b11 = choices[(int)(random.NextDouble() * choiceCounter)];
                }

                Debug.WriteLine($"b11 = {b11}");
            } while (!(b11 != a11 && (b11 >= lowerborder && b11 <= upperborder)));

            var b12 = a11 + a12 - b11;
            var b21 = a11 + a21 - b11;
            var b22 = a22 - a11 + b11;

            if (b11 > 0)
            {
                if (b1 == null)
                {
                    b1 = ac.Builder.NewBond(ax1, ay1, BondManipulator.CreateBondOrder(b11));
                    ac.Bonds.Add(b1);
                }
                else
                {
                    b1.Order = BondManipulator.CreateBondOrder(b11);
                }
            }
            else if (b1 != null)
            {
                ac.Bonds.Remove(b1);
            }

            if (b12 > 0)
            {
                if (b2 == null)
                {
                    b2 = ac.Builder.NewBond(ax1, ay2, BondManipulator.CreateBondOrder(b12));
                    ac.Bonds.Add(b2);
                }
                else
                {
                    b2.Order = BondManipulator.CreateBondOrder(b12);
                }
            }
            else if (b2 != null)
            {
                ac.Bonds.Remove(b2);
            }

            if (b21 > 0)
            {
                if (b3 == null)
                {
                    b3 = ac.Builder.NewBond(ax2, ay1, BondManipulator.CreateBondOrder(b21));
                    ac.Bonds.Add(b3);
                }
                else
                {
                    b3.Order = BondManipulator.CreateBondOrder(b21);
                }
            }
            else if (b3 != null)
            {
                ac.Bonds.Remove(b3);
            }

            if (b22 > 0)
            {
                if (b4 == null)
                {
                    b4 = ac.Builder.NewBond(ax2, ay2, BondManipulator.CreateBondOrder(b22));
                    ac.Bonds.Add(b4);
                }
                else
                {
                    b4.Order = BondManipulator.CreateBondOrder(b22);
                }
            }
            else if (b4 != null)
            {
                ac.Bonds.Remove(b4);
            }

            Debug.WriteLine($"a11 a12 a21 a22: {a11} {a12} {a21} {a22}");
            Debug.WriteLine($"b11 b12 b21 b22: {b11} {b12} {b21} {b22}");
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Choose any possible quadruple of the set of atoms
        /// in ac and establish all of the possible bonding schemes according to
        /// Faulon's equations.
        /// </summary>
        public static IEnumerable <IAtomContainer> Sample(IAtomContainer ac)
        {
            Debug.WriteLine("RandomGenerator->Mutate() Start");

            int    nrOfAtoms = ac.Atoms.Count;
            double a11 = 0, a12 = 0, a22 = 0, a21 = 0;
            double b11 = 0, lowerborder = 0, upperborder = 0;
            double b12 = 0;
            double b21 = 0;
            double b22 = 0;

            double[]       cmax  = new double[4];
            double[]       cmin  = new double[4];
            IAtomContainer newAc = null;

            IAtom ax1 = null, ax2 = null, ay1 = null, ay2 = null;
            IBond b1 = null, b2 = null, b3 = null, b4 = null;
            //int[] choices = new int[3];
            /* We need at least two non-zero bonds in order to be successful */
            int nonZeroBondsCounter = 0;

            for (int x1 = 0; x1 < nrOfAtoms; x1++)
            {
                for (int x2 = x1 + 1; x2 < nrOfAtoms; x2++)
                {
                    for (int y1 = x2 + 1; y1 < nrOfAtoms; y1++)
                    {
                        for (int y2 = y1 + 1; y2 < nrOfAtoms; y2++)
                        {
                            nonZeroBondsCounter = 0;
                            ax1 = ac.Atoms[x1];
                            ay1 = ac.Atoms[y1];
                            ax2 = ac.Atoms[x2];
                            ay2 = ac.Atoms[y2];

                            /* Get four bonds for these four atoms */

                            b1 = ac.GetBond(ax1, ay1);
                            if (b1 != null)
                            {
                                a11 = BondManipulator.DestroyBondOrder(b1.Order);
                                nonZeroBondsCounter++;
                            }
                            else
                            {
                                a11 = 0;
                            }

                            b2 = ac.GetBond(ax1, ay2);
                            if (b2 != null)
                            {
                                a12 = BondManipulator.DestroyBondOrder(b2.Order);
                                nonZeroBondsCounter++;
                            }
                            else
                            {
                                a12 = 0;
                            }

                            b3 = ac.GetBond(ax2, ay1);
                            if (b3 != null)
                            {
                                a21 = BondManipulator.DestroyBondOrder(b3.Order);
                                nonZeroBondsCounter++;
                            }
                            else
                            {
                                a21 = 0;
                            }

                            b4 = ac.GetBond(ax2, ay2);
                            if (b4 != null)
                            {
                                a22 = BondManipulator.DestroyBondOrder(b4.Order);
                                nonZeroBondsCounter++;
                            }
                            else
                            {
                                a22 = 0;
                            }
                            if (nonZeroBondsCounter > 1)
                            {
                                // Compute the range for b11 (see Faulons formulae for details)

                                cmax[0]     = 0;
                                cmax[1]     = a11 - a22;
                                cmax[2]     = a11 + a12 - 3;
                                cmax[3]     = a11 + a21 - 3;
                                cmin[0]     = 3;
                                cmin[1]     = a11 + a12;
                                cmin[2]     = a11 + a21;
                                cmin[3]     = a11 - a22 + 3;
                                lowerborder = MathTools.Max(cmax);
                                upperborder = MathTools.Min(cmin);
                                for (b11 = lowerborder; b11 <= upperborder; b11++)
                                {
                                    if (b11 != a11)
                                    {
                                        b12 = a11 + a12 - b11;
                                        b21 = a11 + a21 - b11;
                                        b22 = a22 - a11 + b11;
                                        Debug.WriteLine("Trying atom combination : " + x1 + ":" + x2 + ":" + y1 + ":" + y2);
                                        newAc = (IAtomContainer)ac.Clone();
                                        Change(newAc, x1, y1, x2, y2, b11, b12, b21, b22);
                                        if (ConnectivityChecker.IsConnected(newAc))
                                        {
                                            yield return(newAc);
                                        }
                                        else
                                        {
                                            Debug.WriteLine("not connected");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            yield break;
        }