Example #1
0
        /// <summary>
        /// Determines if the atom can be of type <see cref="IAtomType"/>. That is, it sees if this
        /// <see cref="IAtomType"/> only differs in bond orders, or implicit hydrogen count.
        /// </summary>
        private static bool CouldMatchAtomType(IAtomContainer container, IAtom atom, IAtomType type)
        {
            var bondOrderSum = container.GetBondOrderSum(atom);
            var maxBondOrder = container.GetMaximumBondOrder(atom);

            return(CouldMatchAtomType(atom, bondOrderSum, maxBondOrder, type));
        }
Example #2
0
        public bool IsSaturated(IAtom atom, IAtomContainer container)
        {
            var type = atomTypeList.GetAtomType(atom.AtomTypeName);

            if (type == null)
            {
                throw new CDKException($"Atom type is not a recognized CDK atom type: {atom.AtomTypeName}");
            }

            if (type.FormalNeighbourCount == null)
            {
                throw new CDKException($"Atom type is too general; cannot decide the number of implicit hydrogen to add for: {atom.AtomTypeName}");
            }

            if (type.GetProperty <object>(CDKPropertyName.PiBondCount) == null)
            {
                throw new CDKException($"Atom type is too general; cannot determine the number of pi bonds for: {atom.AtomTypeName}");
            }

            var bondOrderSum = container.GetBondOrderSum(atom);
            var maxBondOrder = container.GetMaximumBondOrder(atom);
            int?hcount       = atom.ImplicitHydrogenCount == null ? 0 : atom.ImplicitHydrogenCount;

            int piBondCount         = type.GetProperty <int?>(CDKPropertyName.PiBondCount).Value;
            int formalNeighborCount = type.FormalNeighbourCount.Value;

            int typeMaxBondOrder = piBondCount + 1;
            int typeBondOrderSum = formalNeighborCount + piBondCount;

            if (bondOrderSum + hcount == typeBondOrderSum && maxBondOrder.Numeric() <= typeMaxBondOrder)
            {
                return(true);
            }
            return(false);
        }
Example #3
0
        /// <summary>
        /// Checks if the current atom has exceeded its bond order sum value.
        /// </summary>
        /// <param name="atom">The Atom to check</param>
        /// <param name="ac">The atom container context</param>
        /// <returns>oversaturated or not</returns>
        public bool IsOverSaturated(IAtom atom, IAtomContainer ac)
        {
            var atomTypes = structgenATF.GetAtomTypes(atom.Symbol);

            if (!atomTypes.Any())
            {
                return(false);
            }
            var bondOrderSum = ac.GetBondOrderSum(atom);
            var maxBondOrder = ac.GetMaximumBondOrder(atom);
            var hcount       = atom.ImplicitHydrogenCount ?? 0;
            var charge       = atom.FormalCharge ?? 0;

            try
            {
                Debug.WriteLine($"*** Checking saturation of atom {ac.Atoms.IndexOf(atom)} ***");
                Debug.WriteLine($"bondOrderSum: {bondOrderSum}");
                Debug.WriteLine($"maxBondOrder: {maxBondOrder}");
                Debug.WriteLine($"hcount: {hcount}");
            }
            catch (Exception)
            {
            }
            foreach (var atomType in atomTypes)
            {
                if (bondOrderSum - charge + hcount > atomType.BondOrderSum)
                {
                    Debug.WriteLine("*** Good ! ***");
                    return(true);
                }
            }
            Debug.WriteLine("*** Bad ! ***");
            return(false);
        }
Example #4
0
        /// <summary>
        /// Function to set up an array of integers corresponding to indicate how many free valencies need fulfilling for each atom through ring bonds.
        /// </summary>
        /// <returns>The List of free valencies available for extra ring bonding</returns>
        private static List <int> GetFreeValenciesForRingGroup(IAtomContainer molecule, List <int> atomsToCheck, Matrix M, IRingSet rs)
        {
            List <int> fvtc = new List <int>();

            for (int i = 0; i < atomsToCheck.Count; i++)
            {
                int j = atomsToCheck[i];

                //Put in an implicit hydrogen atom for Planar3 C- atoms in 5-membered rings (it doesn't get put in by the Smiles parser)
                if (string.Equals("C", molecule.Atoms[j].Symbol, StringComparison.Ordinal) &&
                    (molecule.Atoms[j].Hybridization == Hybridization.Planar3))
                {
                    //Check that ring containing the atom is five-membered
                    foreach (var ac in rs)
                    {
                        if (ac.Contains(molecule.Atoms[j]))
                        {
                            if ((int)molecule.GetBondOrderSum(molecule.Atoms[j]) == 2 && ac.Atoms.Count == 5)
                            {
                                molecule.Atoms[j].ImplicitHydrogenCount = 1;
                                break;
                            }
                        }
                    }
                }
                int implicitH = 0;
                if (!molecule.Atoms[j].ImplicitHydrogenCount.HasValue)
                {
                    var ha = CDK.HydrogenAdder;
                    try
                    {
                        ha.AddImplicitHydrogens(molecule, molecule.Atoms[j]);
                        implicitH = molecule.Atoms[j].ImplicitHydrogenCount.Value;
                    }
                    catch (CDKException)
                    {
                        //No need to do anything because implicitH already set to 0
                    }
                }
                else
                {
                    implicitH = molecule.Atoms[j].ImplicitHydrogenCount.Value;
                }
                fvtc.Add(molecule.Atoms[j].Valency.Value - (implicitH + (int)molecule.GetBondOrderSum(molecule.Atoms[j])) + M.SumOfRow(i));
            }
            return(fvtc);
        }
Example #5
0
        // the Molecule tests

        private static ValidationReport ValidateBondOrderSum(IAtom atom, IAtomContainer molecule)
        {
            var report       = new ValidationReport();
            var checkBondSum = new ValidationTest(atom, "The atom's total bond order is too high.");

            try
            {
                var structgenATF = CDK.CdkAtomTypeFactory;
                int bos          = (int)molecule.GetBondOrderSum(atom);
                var atomTypes    = structgenATF.GetAtomTypes(atom.Symbol).ToReadOnlyList();
                if (atomTypes.Count == 0)
                {
                    checkBondSum.Details = $"Cannot validate bond order sum for atom not in valency atom type list: {atom.Symbol}";
                    report.Warnings.Add(checkBondSum);
                }
                else
                {
                    IAtomType failedOn = null;
                    bool      foundMatchingAtomType = false;
                    foreach (var type in atomTypes)
                    {
                        if (atom.FormalCharge == type.FormalCharge)
                        {
                            foundMatchingAtomType = true;
                            if (bos == type.BondOrderSum)
                            {
                                // skip this atom type
                            }
                            else
                            {
                                failedOn = type;
                            }
                        }
                    }
                    if (foundMatchingAtomType)
                    {
                        report.OKs.Add(checkBondSum);
                    }
                    else
                    {
                        if (failedOn != null)
                        {
                            checkBondSum.Details = $"Bond order exceeds the one allowed for atom {atom.Symbol} for which the total bond order is {failedOn.BondOrderSum}";
                        }
                        else
                        {
                        }
                        report.Errors.Add(checkBondSum);
                    }
                }
            }
            catch (Exception exception)
            {
                Trace.TraceError($"Error while performing atom bos validation: {exception.Message}");
                Debug.WriteLine(exception);
            }
            return(report);
        }
Example #6
0
        /// <summary>
        /// Checks whether an atom is saturated by comparing it with known atom types.
        /// </summary>
        /// <returns><see langword="true"/> if the atom is an pseudo atom and when the element is not in the list.</returns>
        public bool IsSaturated(IAtom atom, IAtomContainer container)
        {
            if (atom is IPseudoAtom)
            {
                Debug.WriteLine("don't figure it out... it simply does not lack H's");
                return(true);
            }

            var atomTypes = structgenATF.GetAtomTypes(atom.Symbol);

            if (atomTypes.Any())
            {
                Trace.TraceWarning($"Missing entry in atom type list for {atom.Symbol}");
                return(true);
            }
            var bondOrderSum = container.GetBondOrderSum(atom);
            var maxBondOrder = container.GetMaximumBondOrder(atom);
            var hcount       = atom.ImplicitHydrogenCount.Value;
            var charge       = atom.FormalCharge.Value;

            Debug.WriteLine($"Checking saturation of atom {atom.Symbol}");
            Debug.WriteLine($"bondOrderSum: {bondOrderSum}");
            Debug.WriteLine($"maxBondOrder: {maxBondOrder}");
            Debug.WriteLine($"hcount: {hcount}");
            Debug.WriteLine($"charge: {charge}");

            bool elementPlusChargeMatches = false;

            foreach (var type in atomTypes)
            {
                if (CouldMatchAtomType(atom, bondOrderSum, maxBondOrder, type))
                {
                    if (bondOrderSum + hcount == type.BondOrderSum &&
                        !BondManipulator.IsHigherOrder(maxBondOrder, type.MaxBondOrder))
                    {
                        Debug.WriteLine($"We have a match: {type}");
                        Debug.WriteLine($"Atom is saturated: {atom.Symbol}");
                        return(true);
                    }
                    else
                    {
                        // ok, the element and charge matche, but unfulfilled
                        elementPlusChargeMatches = true;
                    }
                } // else: formal charges don't match
            }

            if (elementPlusChargeMatches)
            {
                Debug.WriteLine("No, atom is not saturated.");
                return(false);
            }

            // ok, the found atom was not in the list
            Trace.TraceError("Could not find atom type!");
            throw new CDKException($"The atom with element {atom.Symbol} and charge {charge} is not found.");
        }
Example #7
0
 /// <summary>
 /// Determines if the atom can be of atom type.
 /// </summary>
 private static bool CouldMatchAtomType(IAtomContainer atomContainer, IAtom atom, IAtomType atomType)
 {
     Debug.WriteLine($"   ... matching atom {atom.Symbol} vs {atomType}");
     if (atomContainer.GetBondOrderSum(atom) + atom.ImplicitHydrogenCount < atomType.BondOrderSum)
     {
         Debug.WriteLine("    Match!");
         return(true);
     }
     Debug.WriteLine("    No Match");
     return(false);
 }
Example #8
0
        /// <summary>
        /// Checks whether an atom is saturated by comparing it with known atom types.
        /// </summary>
        public bool IsSaturated(IAtom atom, IAtomContainer ac)
        {
            var atomTypes = structgenATF.GetAtomTypes(atom.Symbol);

            if (!atomTypes.Any())
            {
                return(true);
            }
            double bondOrderSum = 0;
            var    maxBondOrder = BondOrder.Unset;
            int    hcount       = 0;
            int    charge       = 0;
            bool   isInited     = false;

            foreach (var atomType in atomTypes)
            {
                if (!isInited)
                {
                    isInited     = true;
                    bondOrderSum = ac.GetBondOrderSum(atom);
                    maxBondOrder = ac.GetMaximumBondOrder(atom);
                    hcount       = atom.ImplicitHydrogenCount ?? 0;
                    charge       = atom.FormalCharge ?? 0;
                    try
                    {
                        Debug.WriteLine($"*** Checking saturation of atom {atom.Symbol} {ac.Atoms.IndexOf(atom)} ***");
                        Debug.WriteLine($"bondOrderSum: {bondOrderSum}");
                        Debug.WriteLine($"maxBondOrder: {maxBondOrder}");
                        Debug.WriteLine($"hcount: {hcount}");
                    }
                    catch (Exception exc)
                    {
                        Debug.WriteLine(exc);
                    }
                }
                if (bondOrderSum - charge + hcount == atomType.BondOrderSum &&
                    !BondManipulator.IsHigherOrder(maxBondOrder, atomType.MaxBondOrder))
                {
                    Debug.WriteLine("*** Good ! ***");
                    return(true);
                }
            }
            Debug.WriteLine("*** Bad ! ***");
            return(false);
        }
Example #9
0
        private static double GetAtomScore(double score, IReadOnlyDictionary <IAtom, IAtom> atomMapMCS, IAtomContainer reactant, IAtomContainer product)
        {
            foreach (var mappings in atomMapMCS)
            {
                IAtom rAtom = mappings.Key;
                IAtom pAtom = mappings.Value;

                int    rHCount = 0;
                int    pHCount = 0;
                double rBO     = reactant.GetBondOrderSum(rAtom);
                double pBO     = product.GetBondOrderSum(pAtom);

                if (rAtom.ImplicitHydrogenCount != null)
                {
                    rHCount = rAtom.ImplicitHydrogenCount.Value;
                }
                if (pAtom.ImplicitHydrogenCount != null)
                {
                    pHCount = pAtom.ImplicitHydrogenCount.Value;
                }

                int    hScore  = Math.Abs(rHCount - pHCount);
                double boScore = Math.Abs(rBO - pBO);

                if (rHCount != pHCount)
                {
                    score -= hScore;
                }
                else
                {
                    score += hScore;
                }

                if (rBO != pBO)
                {
                    score -= boScore;
                }
                else
                {
                    score += boScore;
                }
            }
            return(score);
        }
Example #10
0
        public bool HasPerfectConfiguration(IAtom atom, IAtomContainer ac)
        {
            var bondOrderSum = ac.GetBondOrderSum(atom);
            var maxBondOrder = ac.GetMaximumBondOrder(atom);
            var atomTypes    = structgenATF.GetAtomTypes(atom.Symbol);

            if (!atomTypes.Any())
            {
                return(true);
            }
            Debug.WriteLine("*** Checking for perfect configuration ***");
            try
            {
                Debug.WriteLine($"Checking configuration of atom {ac.Atoms.IndexOf(atom)}");
                Debug.WriteLine($"Atom has bondOrderSum = {bondOrderSum}");
                Debug.WriteLine($"Atom has max = {bondOrderSum}");
            }
            catch (Exception)
            {
            }
            foreach (var atomType in atomTypes)
            {
                if (bondOrderSum == atomType.BondOrderSum && maxBondOrder == atomType.MaxBondOrder)
                {
                    try
                    {
                        Debug.WriteLine($"Atom {ac.Atoms.IndexOf(atom)} has perfect configuration");
                    }
                    catch (Exception)
                    {
                    }
                    return(true);
                }
            }
            try
            {
                Debug.WriteLine($"*** Atom {ac.Atoms.IndexOf(atom)} has imperfect configuration ***");
            }
            catch (Exception)
            {
            }
            return(false);
        }
Example #11
0
        private void FixCarbonHCount(IAtomContainer mol)
        {
            // the following line are just a quick fix for this particluar
            // carbon-only molecule until we have a proper hydrogen count
            // configurator
            double bondCount = 0;
            IAtom  atom;

            for (int f = 0; f < mol.Atoms.Count; f++)
            {
                atom      = mol.Atoms[f];
                bondCount = mol.GetBondOrderSum(atom);
                if (bondCount > 4)
                {
                    Console.Out.WriteLine("bondCount: " + bondCount);
                }
                atom.ImplicitHydrogenCount = 4 - (int)bondCount - (int)(atom.Charge ?? 0);
            }
        }
Example #12
0
        /// <summary>
        /// Finds the AtomType matching the Atom's element symbol, formal charge and
        /// hybridization state.
        /// </summary>
        /// <param name="atomContainer">AtomContainer</param>
        /// <param name="atom">the target atom</param>
        /// <exception cref="CDKException">Exception thrown if something goes wrong</exception>
        /// <returns>the matching AtomType</returns>
        public IEnumerable <IAtomType> PossibleAtomTypes(IAtomContainer atomContainer, IAtom atom)
        {
            var bondOrderSum = atomContainer.GetBondOrderSum(atom);
            var maxBondOrder = atomContainer.GetMaximumBondOrder(atom);
            var charge       = atom.FormalCharge.Value;
            var hcount       = atom.ImplicitHydrogenCount.Value;

            var types = factory.GetAtomTypes(atom.Symbol);

            foreach (var type in types)
            {
                Debug.WriteLine("   ... matching atom ", atom, " vs ", type);
                if (bondOrderSum - charge + hcount <= type.BondOrderSum &&
                    !BondManipulator.IsHigherOrder(maxBondOrder, type.MaxBondOrder))
                {
                    yield return(type);
                }
            }
            Debug.WriteLine("    No Match");

            yield break;
        }
Example #13
0
        /// <summary>
        /// Returns the currently maximum bond order for this atom.
        /// </summary>
        /// <param name="atom">The atom to be checked</param>
        /// <param name="ac">The AtomContainer that provides the context</param>
        /// <returns>the currently maximum bond order for this atom</returns>
        public double GetCurrentMaxBondOrder(IAtom atom, IAtomContainer ac)
        {
            var atomTypes = structgenATF.GetAtomTypes(atom.Symbol);

            if (!atomTypes.Any())
            {
                return(0);
            }
            var    bondOrderSum = ac.GetBondOrderSum(atom);
            var    hcount       = atom.ImplicitHydrogenCount ?? 0;
            double max          = 0;
            double current      = 0;

            foreach (var atomType in atomTypes)
            {
                current = hcount + bondOrderSum;
                if (atomType.BondOrderSum - current > max)
                {
                    max = atomType.BondOrderSum.Value - current;
                }
            }
            return(max);
        }
Example #14
0
        /// <summary>
        /// The method is known to fail for certain compounds. For more information, see
        /// cdk.test.limitations package.
        /// This method is known to fail, especially on pyrrole-like compounds.
        /// Consider using <see cref="Smiles.DeduceBondSystemTool"/>, which should work better
        /// </summary>
        public void Saturate(IAtomContainer atomContainer)
        {
            for (int i = 1; i < 4; i++)
            {
                // handle atoms with degree 1 first and then proceed to higher order
                for (int f = 0; f < atomContainer.Atoms.Count; f++)
                {
                    var atom = atomContainer.Atoms[f];
                    Debug.WriteLine($"symbol: {atom.Symbol}");
                    var atomTypes1 = structgenATF.GetAtomTypes(atom.Symbol);
                    var atomType1  = atomTypes1.FirstOrDefault();
                    if (atomType1 != null)
                    {
                        Debug.WriteLine($"first atom type: {atomType1}");
                        if (atomContainer.GetConnectedBonds(atom).Count() == i)
                        {
                            var hcount = atom.ImplicitHydrogenCount ?? 0;
                            if (atom.IsAromatic &&
                                atomContainer.GetBondOrderSum(atom) < atomType1.BondOrderSum - hcount)
                            {
                                var partners = atomContainer.GetConnectedAtoms(atom);
                                foreach (var partner in partners)
                                {
                                    Debug.WriteLine($"Atom has {partners.Count()} partners");
                                    var atomType2 = structgenATF.GetAtomTypes(partner.Symbol).FirstOrDefault();
                                    if (atomType2 == null)
                                    {
                                        return;
                                    }

                                    hcount = partner.ImplicitHydrogenCount ?? 0;
                                    if (atomContainer.GetBond(partner, atom).IsAromatic &&
                                        atomContainer.GetBondOrderSum(partner) < atomType2.BondOrderSum - hcount)
                                    {
                                        Debug.WriteLine($"Partner has {atomContainer.GetBondOrderSum(partner)}, may have: {atomType2.BondOrderSum}");
                                        var bond = atomContainer.GetBond(atom, partner);
                                        Debug.WriteLine($"Bond order was {bond.Order}");
                                        BondManipulator.IncreaseBondOrder(bond);
                                        Debug.WriteLine($"Bond order now {bond.Order}");
                                        break;
                                    }
                                }
                            }

                            var bondOrderSum              = atomType1.BondOrderSum ?? 0;
                            var hydrogenCount             = atom.ImplicitHydrogenCount ?? 0;
                            var atomContainerBondOrderSum = atomContainer.GetBondOrderSum(atom);

                            if (atomContainerBondOrderSum < bondOrderSum - hydrogenCount)
                            {
                                Debug.WriteLine("Atom has " + atomContainerBondOrderSum + ", may have: " + bondOrderSum);
                                var partners = atomContainer.GetConnectedAtoms(atom);
                                foreach (var partner in partners)
                                {
                                    Debug.WriteLine("Atom has " + partners.Count() + " partners");
                                    var atomType2 = structgenATF.GetAtomTypes(partner.Symbol).FirstOrDefault();
                                    if (atomType2 == null)
                                    {
                                        return;
                                    }

                                    var bos2   = atomType2.BondOrderSum ?? 0;
                                    var hc2    = partner.ImplicitHydrogenCount ?? 0;
                                    var acbos2 = atomContainer.GetBondOrderSum(partner);

                                    if (acbos2 < bos2 - hc2)
                                    {
                                        Debug.WriteLine($"Partner has {acbos2}, may have: {bos2}");
                                        var bond = atomContainer.GetBond(atom, partner);
                                        Debug.WriteLine($"Bond order was {bond.Order}");
                                        BondManipulator.IncreaseBondOrder(bond);
                                        Debug.WriteLine($"Bond order now {bond.Order}");
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Example #15
0
 public int CalculateNumberOfImplicitHydrogens(IAtom atom, IAtomContainer container)
 {
     return(this.CalculateNumberOfImplicitHydrogens(atom, container.GetBondOrderSum(atom), container.GetMaximumBondOrder(atom), container.GetConnectedBonds(atom).Count()));
 }
Example #16
0
        private static int GetBadCount(IAtomContainer atomContainer, IRingSet ringSet)
        {
            // finds count of nitrogens in the rings that have 4 bonds
            // to non hydrogen atoms and one to hydrogen
            // or nitrogens with 2 double bonds to atoms in the ringset
            // or have S atom with more than 2 bonds
            // these arent necessarily bad- just unlikely

            int count = 0;

            for (int j = 0; j <= atomContainer.Atoms.Count - 1; j++)
            {
                var atom = atomContainer.Atoms[j];

                if (InRingSet(atom, ringSet))
                {
                    if (atom.AtomicNumber.Equals(AtomicNumbers.N))
                    {
                        if (atom.FormalCharge == 0)
                        {
                            if (atomContainer.GetBondOrderSum(atom) == 4)
                            {
                                count++; //
                            }
                            else if (atomContainer.GetBondOrderSum(atom) == 5)
                            {
                                // check if have 2 double bonds to atom in ring
                                int doublebondcount = 0;
                                var ca = atomContainer.GetConnectedAtoms(atom);

                                foreach (var a in ca)
                                {
                                    if (atomContainer.GetBond(atom, a).Order == BondOrder.Double)
                                    {
                                        if (InRingSet(a, ringSet))
                                        {
                                            doublebondcount++;
                                        }
                                    }
                                }
                                if (doublebondcount == 2)
                                {
                                    count++;
                                }
                            }
                        }
                        else if (atom.FormalCharge == 1)
                        {
                            if (atomContainer.GetBondOrderSum(atom) == 5)
                            {
                                count++;
                            }
                        }
                    }
                    else if (atom.AtomicNumber.Equals(AtomicNumbers.S))
                    {
                        if (atomContainer.GetBondOrderSum(atom) > 2)
                        {
                            count++;
                        }
                    }
                }
            }

            return(count);
        }
Example #17
0
        /// <summary>
        /// Proposes a structure which can be accepted or rejected by an external
        /// entity. If rejected, the structure is not used as a starting point
        /// for the next random move in structure space.
        /// </summary>
        /// <returns>A proposed molecule</returns>
        public IAtomContainer ProposeStructure()
        {
            Debug.WriteLine("RandomGenerator->ProposeStructure() Start");
            do
            {
                trial = (IAtomContainer)Molecule.Clone();
                Mutate(trial);
                Debug.WriteLine("BondCounts:    " + string.Join(" ", trial.Atoms.Select(n => trial.GetConnectedBonds(n).Count())));
                Debug.WriteLine("BondOrderSums: " + string.Join(" ", trial.Atoms.Select(n => trial.GetBondOrderSum(n))));
            } while (trial == null || !ConnectivityChecker.IsConnected(trial));
            proposedStructure = trial;

            return(proposedStructure);
        }
Example #18
0
 public int CalculateNumberOfImplicitHydrogens(IAtom atom, IAtomContainer container, bool throwExceptionForUnknowAtom)
 {
     return(this.CalculateNumberOfImplicitHydrogens(atom, container.GetBondOrderSum(atom),
                                                    container.GetConnectedSingleElectrons(atom).Count(), container.GetConnectedBonds(atom),
                                                    throwExceptionForUnknowAtom));
 }