/// <summary>
        /// Tries to saturate a bond by increasing its bond orders by 1.0.
        /// </summary>
        /// <returns>true if the bond could be increased</returns>
        public bool SaturateByIncreasingBondOrder(IBond bond, IAtomContainer atomContainer)
        {
            var atoms   = BondManipulator.GetAtomArray(bond);
            var atom    = atoms[0];
            var partner = atoms[1];

            Debug.WriteLine("  saturating bond: ", atom.Symbol, "-", partner.Symbol);
            var atomTypes1 = structgenATF.GetAtomTypes(atom.Symbol);
            var atomTypes2 = structgenATF.GetAtomTypes(partner.Symbol);

            foreach (var aType1 in atomTypes1)
            {
                Debug.WriteLine($"  considering atom type: {aType1}");
                if (CouldMatchAtomType(atomContainer, atom, aType1))
                {
                    Debug.WriteLine($"  trying atom type: {aType1}");
                    foreach (var aType2 in atomTypes2)
                    {
                        Debug.WriteLine($"  considering partner type: {aType1}");
                        if (CouldMatchAtomType(atomContainer, partner, aType2))
                        {
                            Debug.WriteLine($"    with atom type: {aType2}");
                            if (BondManipulator.IsLowerOrder(bond.Order, aType2.MaxBondOrder) &&
                                BondManipulator.IsLowerOrder(bond.Order, aType1.MaxBondOrder))
                            {
                                bond.Order = BondManipulator.IncreaseBondOrder(bond.Order);
                                Debug.WriteLine($"Bond order now {bond.Order}");
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
Exemple #2
0
        /// <summary>
        /// Saturate atom by adjusting its bond orders.
        /// This method is known to fail, especially on pyrrole-like compounds.
        /// Consider using <see cref="Smiles.DeduceBondSystemTool"/>, which should work better
        /// </summary>
        public bool NewSaturate(IBond bond, IAtomContainer atomContainer)
        {
            var atoms   = BondManipulator.GetAtomArray(bond);
            var atom    = atoms[0];
            var partner = atoms[1];

            Debug.WriteLine($"  saturating bond: {atom.Symbol}-{partner.Symbol}");
            var  atomTypes1         = structgenATF.GetAtomTypes(atom.Symbol);
            var  atomTypes2         = structgenATF.GetAtomTypes(partner.Symbol);
            bool bondOrderIncreased = true;

            while (bondOrderIncreased && !IsSaturated(bond, atomContainer))
            {
                Debug.WriteLine("Can increase bond order");
                bondOrderIncreased = false;
                foreach (var aType1 in atomTypes1)
                {
                    if (bondOrderIncreased)
                    {
                        break;
                    }
                    Debug.WriteLine($"  considering atom type: {aType1}");
                    if (CouldMatchAtomType(atomContainer, atom, aType1))
                    {
                        Debug.WriteLine($"  trying atom type: {aType1}");
                        foreach (var aType2 in atomTypes2)
                        {
                            if (bondOrderIncreased)
                            {
                                break;
                            }
                            Debug.WriteLine($"  considering partner type: {aType1}");
                            if (CouldMatchAtomType(atomContainer, partner, aType2))
                            {
                                Debug.WriteLine($"    with atom type: {aType2}");
                                if (!BondManipulator.IsLowerOrder(bond.Order, aType2.MaxBondOrder) ||
                                    !BondManipulator.IsLowerOrder(bond.Order, aType1.MaxBondOrder))
                                {
                                    Debug.WriteLine("Bond order not increased: atoms has reached (or exceeded) maximum bond order for this atom type");
                                }
                                else if (BondManipulator.IsLowerOrder(bond.Order, aType2.MaxBondOrder) &&
                                         BondManipulator.IsLowerOrder(bond.Order, aType1.MaxBondOrder))
                                {
                                    BondManipulator.IncreaseBondOrder(bond);
                                    Debug.WriteLine($"Bond order now {bond.Order}");
                                    bondOrderIncreased = true;
                                }
                            }
                        }
                    }
                }
            }
            return(IsSaturated(bond, atomContainer));
        }
Exemple #3
0
        /// <summary>
        /// The method calculates the number of rotatable bonds of an atom container.
        /// If the boolean parameter is set to <see langword="true"/>, terminal bonds are included.
        /// </summary>
        /// <returns>number of rotatable bonds</returns>
        /// <param name="includeTerminals"><see langword="true"/> if terminal bonds are included</param>
        /// <param name="excludeAmides"><see langword="true"/> if amide C-N bonds should be excluded</param>
        public Result Calculate(IAtomContainer container, bool includeTerminals = false, bool excludeAmides = false)
        {
            container = (IAtomContainer)container.Clone();

            IRingSet ringSet;

            try
            {
                ringSet = new SpanningTree(container).GetBasicRings();
            }
            catch (NoSuchAtomException)
            {
                return(new Result(0));
            }

            foreach (var bond in container.Bonds)
            {
                if (ringSet.GetRings(bond).Count() > 0)
                {
                    bond.IsInRing = true;
                }
            }

            int rotatableBondsCount = 0;

            foreach (var bond in container.Bonds)
            {
                var atom0 = bond.Atoms[0];
                var atom1 = bond.Atoms[1];
                if (atom0.AtomicNumber.Equals(AtomicNumbers.H) || atom1.AtomicNumber.Equals(AtomicNumbers.H))
                {
                    continue;
                }
                if (bond.Order == BondOrder.Single)
                {
                    if (BondManipulator.IsLowerOrder(container.GetMaximumBondOrder(atom0), BondOrder.Triple) &&
                        BondManipulator.IsLowerOrder(container.GetMaximumBondOrder(atom1), BondOrder.Triple))
                    {
                        if (!bond.IsInRing)
                        {
                            if (excludeAmides && (IsAmide(atom0, atom1, container) || IsAmide(atom1, atom0, container)))
                            {
                                continue;
                            }

                            // if there are explicit H's we should ignore those bonds
                            var degree0 = container.GetConnectedBonds(atom0).Count() - GetConnectedHCount(container, atom0);
                            var degree1 = container.GetConnectedBonds(atom1).Count() - GetConnectedHCount(container, atom1);
                            if ((degree0 == 1) || (degree1 == 1))
                            {
                                if (includeTerminals)
                                {
                                    rotatableBondsCount += 1;
                                }
                            }
                            else
                            {
                                rotatableBondsCount += 1;
                            }
                        }
                    }
                }
            }

            return(new Result(rotatableBondsCount));
        }