Esempio n. 1
0
        /// <summary>
        /// Determines if the atom can be of atom type. That is, it sees if this
        /// atom type only differs in bond orders, or implicit hydrogen count.
        /// </summary>
        private static bool CouldMatchAtomType(IAtom atom, double bondOrderSum, BondOrder maxBondOrder, IAtomType type)
        {
            Debug.WriteLine($"{nameof(CouldMatchAtomType)}:   ... matching atom {atom} vs {type}");
            var hcount = atom.ImplicitHydrogenCount.Value;
            var charge = atom.FormalCharge.Value;

            if (charge == type.FormalCharge)
            {
                Debug.WriteLine($"{nameof(CouldMatchAtomType)}e:     formal charge matches...");
                if (bondOrderSum + hcount <= type.BondOrderSum)
                {
                    Debug.WriteLine($"{nameof(CouldMatchAtomType)}:     bond order sum is OK...");
                    if (!BondManipulator.IsHigherOrder(maxBondOrder, type.MaxBondOrder))
                    {
                        Debug.WriteLine($"{nameof(CouldMatchAtomType)}:     max bond order is OK... We have a match!");
                        return(true);
                    }
                }
                else
                {
                    Debug.WriteLine($"{nameof(CouldMatchAtomType)}:      no match {(bondOrderSum + hcount)} > {type.BondOrderSum}");
                }
            }
            else
            {
                Debug.WriteLine($"{nameof(CouldMatchAtomType)}:     formal charge does NOT match...");
            }
            Debug.WriteLine($"{nameof(CouldMatchAtomType)}e:    No Match");
            return(false);
        }
Esempio n. 2
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.");
        }
Esempio n. 3
0
        private static ValidationReport ValidateMaxBondOrder(IBond bond)
        {
            var report = new ValidationReport();
            var maxBO  = new ValidationTest(bond, "Bond order exceeds the maximum for one of its atoms.");

            try
            {
                var structgenATF = CDK.CdkAtomTypeFactory;
                for (int i = 0; i < bond.Atoms.Count; i++)
                {
                    var atom = bond.Atoms[i];
                    if (atom is IPseudoAtom)
                    {
                        // ok, all is fine; we don't know the properties of pseudo atoms
                        break;
                    }
                    var       atomTypes             = structgenATF.GetAtomTypes(atom.Symbol);
                    IAtomType failedOn              = null;
                    bool      foundMatchingAtomType = false;
                    foreach (var atomType in atomTypes)
                    {
                        if (!BondManipulator.IsHigherOrder(bond.Order, atomType.MaxBondOrder))
                        {
                            foundMatchingAtomType = true;
                        }
                        else
                        {
                            failedOn = atomType;
                        }
                    }
                    if (foundMatchingAtomType)
                    {
                        report.OKs.Add(maxBO);
                    }
                    else
                    {
                        if (failedOn != null)
                        {
                            maxBO.Details = $"Bond order exceeds the one allowed for atom {atom.Symbol} for which the maximum bond order is {failedOn.MaxBondOrder}";
                        }
                        report.Errors.Add(maxBO);
                    }
                }
            }
            catch (Exception exception)
            {
                Trace.TraceError("Error while performing atom bos validation");
                Debug.WriteLine(exception);
                maxBO.Details = $"Error while performing atom bos validation: {exception.ToString()}";
                report.CDKErrors.Add(maxBO);
            }
            return(report);
        }
Esempio n. 4
0
        private static BondOrder GetHighestBondOrder(IAtomContainer container, IAtom atom)
        {
            var bonds    = container.GetConnectedBonds(atom);
            var maxOrder = BondOrder.Single;

            foreach (var bond in bonds)
            {
                if (BondManipulator.IsHigherOrder(bond.Order, maxOrder))
                {
                    maxOrder = bond.Order;
                }
            }
            return(maxOrder);
        }
Esempio n. 5
0
        /// <summary>
        /// Method that tests if the matched <see cref="IAtomType"/> and the <see cref="IAtom"/> are
        /// consistent. For example, it tests if hybridization states and formal charges are equal.
        ///
        // @cdk.bug 1897589
        /// </summary>
        private void AssertConsistentProperties(IAtomContainer mol, IAtom atom, IAtomType matched)
        {
            // X has no properties; nothing to match
            if (string.Equals("X", matched.AtomTypeName, StringComparison.Ordinal))
            {
                return;
            }

            if (!atom.Hybridization.IsUnset() && !matched.Hybridization.IsUnset())
            {
                Assert.AreEqual(atom.Hybridization, matched.Hybridization, "Hybridization does not match");
            }
            if (atom.FormalCharge != null && matched.FormalCharge != null)
            {
                Assert.AreEqual(atom.FormalCharge, matched.FormalCharge, "Formal charge does not match");
            }
            var connections     = mol.GetConnectedBonds(atom);
            int connectionCount = connections.Count();

            if (matched.FormalNeighbourCount != null)
            {
                Assert.IsFalse(connectionCount > matched.FormalNeighbourCount, "Number of neighbors is too high");
            }
            if (!matched.MaxBondOrder.IsUnset())
            {
                BondOrder expectedMax = matched.MaxBondOrder;
                foreach (var bond in connections)
                {
                    BondOrder order = bond.Order;
                    if (!order.IsUnset())
                    {
                        if (BondManipulator.IsHigherOrder(order, expectedMax))
                        {
                            Assert.Fail("At least one bond order exceeds the maximum for the atom type");
                        }
                    }
                    else if (bond.IsSingleOrDouble)
                    {
                        if (expectedMax != BondOrder.Single && expectedMax != BondOrder.Double)
                        {
                            Assert.Fail("A single or double flagged bond does not match the bond order of the atom type");
                        }
                    }
                }
            }
        }
Esempio n. 6
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);
        }
Esempio n. 7
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;
        }