Пример #1
0
        /// <summary>
        /// A compound with one sulfur atom joined to three oxygen
        /// atoms total in which two of the three are double-bound
        /// while the third is single bound and, in addition, said
        /// third oxygen atom is, itself, bound to a hydrogen atom.
        /// </summary>
        public static bool IsSulphonic(this IAtomContainer mol)
        {
            if (mol == null)
            {
                return(false);
            }

            foreach (var bond in mol.Bonds)
            {
                if (bond.Begin.Symbol != "S" && bond.End.Symbol != "S")
                {
                    continue;
                }

                var sulfur = bond.Begin.Symbol == "S" ? bond.Begin : bond.End;

                var sulfurBonds = mol.GetConnectedBonds(sulfur)?.ToList();
                if (sulfurBonds == null || !sulfurBonds.Any())
                {
                    continue;
                }

                if (sulfurBonds.Count < 4)
                {
                    continue;
                }

                if (sulfurBonds.Count(b => b.Order == BondOrder.Double && (b.Begin.IsOxygenAtom() || b.End.IsOxygenAtom())) != 2)
                {
                    continue;
                }

                var sulfur2OxygenSingle = sulfurBonds.FirstOrDefault(b =>
                                                                     b.Order == BondOrder.Single && (b.Begin.IsOxygenAtom() || b.End.IsOxygenAtom()));

                if (sulfur2OxygenSingle == null)
                {
                    continue;
                }

                var singleBoundOxygen = sulfur2OxygenSingle.Begin.IsOxygenAtom()
                    ? sulfur2OxygenSingle.Begin
                    : sulfur2OxygenSingle.End;

                var singleBoundOxygenBonds = mol.GetConnectedBonds(singleBoundOxygen)?.ToList();
                if (singleBoundOxygenBonds == null || !singleBoundOxygenBonds.Any())
                {
                    continue;
                }

                if (singleBoundOxygenBonds.Count(b =>
                                                 b.Order == BondOrder.Single && (b.Begin.IsHydrogenAtom() || b.End.IsHydrogenAtom())) != 1)
                {
                    continue;
                }
                return(true);
            }

            return(false);
        }
Пример #2
0
 /// <summary>
 /// set the active center for this molecule.
 /// The active center will be those which correspond with X=Y-Z-H.
 /// <pre>
 /// X: Atom
 /// =: bond
 /// Y: Atom
 /// -: bond
 /// Z: Atom
 /// -: bond
 /// H: Atom
 ///  </pre>
 /// </summary>
 /// <param name="reactant">The molecule to set the activity</param>
 private static void SetActiveCenters(IAtomContainer reactant)
 {
     foreach (var atomi in reactant.Atoms)
     {
         if ((atomi.FormalCharge ?? 0) == 0 &&
             !reactant.GetConnectedSingleElectrons(atomi).Any())
         {
             foreach (var bondi in reactant.GetConnectedBonds(atomi))
             {
                 if (bondi.Order == BondOrder.Double)
                 {
                     IAtom atomj = bondi.GetOther(atomi);
                     if ((atomj.FormalCharge ?? 0) == 0 &&
                         !reactant.GetConnectedSingleElectrons(atomj).Any())
                     {
                         foreach (var bondj in reactant.GetConnectedBonds(atomj))
                         {
                             if (bondj.Equals(bondi))
                             {
                                 continue;
                             }
                             if (bondj.Order == BondOrder.Single)
                             {
                                 IAtom atomk = bondj.GetOther(atomj);
                                 if ((atomk.FormalCharge ?? 0) == 0 &&
                                     !reactant.GetConnectedSingleElectrons(atomk).Any()
                                     )
                                 {
                                     foreach (var bondk in reactant.GetConnectedBonds(atomk))
                                     {
                                         if (bondk.Equals(bondj))
                                         {
                                             continue;
                                         }
                                         if (bondk.Order == BondOrder.Single)
                                         {
                                             IAtom atoml = bondk.GetOther(atomk); // Atom pos 4
                                             if (atoml.AtomicNumber.Equals(AtomicNumbers.H))
                                             {
                                                 atomi.IsReactiveCenter = true;
                                                 atomj.IsReactiveCenter = true;
                                                 atomk.IsReactiveCenter = true;
                                                 atoml.IsReactiveCenter = true;
                                                 bondi.IsReactiveCenter = true;
                                                 bondj.IsReactiveCenter = true;
                                                 bondk.IsReactiveCenter = true;
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
Пример #3
0
        private void CreateCenterCode(IAtom root, IAtomContainer ac, bool ringsize)
        {
            int partnerCount = 0;

            partnerCount = atomContainer.GetConnectedBonds(root).Count()
                           + (root.ImplicitHydrogenCount ?? 0);
            centerCode = root.Symbol + "-" + partnerCount + CreateChargeCode(root)
                         + (ringsize ? GetRingcode(root, ac) : "") + ";";
        }
        /// <summary>
        /// Adjust the configuration of the <paramref name="dbs"/> element (if required).
        /// </summary>
        /// <param name="dbs">double-bond stereochemistry element</param>
        private void Adjust(IDoubleBondStereochemistry dbs)
        {
            var db    = dbs.StereoBond;
            var bonds = dbs.Bonds;

            var left  = db.Begin;
            var right = db.End;

            var p = Parity(dbs.Configure);
            var q = Parity(GetAtoms(left, bonds[0].GetOther(left), right))
                    * Parity(GetAtoms(right, bonds[1].GetOther(right), left));

            // configuration is unspecified? then we add an unspecified bond.
            // note: IDoubleBondStereochemistry doesn't indicate this yet
            if (p == 0)
            {
                foreach (var bond in container.GetConnectedBonds(left))
                {
                    bond.Stereo = BondStereo.None;
                }
                foreach (var bond in container.GetConnectedBonds(right))
                {
                    bond.Stereo = BondStereo.None;
                }
                bonds[0].Stereo = BondStereo.UpOrDown;
                return;
            }

            // configuration is already correct
            if (p == q)
            {
                return;
            }

            Arrays.Fill(visited, false);
            visited[atomToIndex[left]] = true;

            if (ringSearch.Cyclic(atomToIndex[left], atomToIndex[right]))
            {
                db.Stereo = BondStereo.EOrZ;
                return;
            }

            foreach (var w in graph[atomToIndex[right]])
            {
                if (!visited[w])
                {
                    Reflect(w, db);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Performs a breadthFirstSearch in an AtomContainer starting with a
        /// particular sphere, which usually consists of one start atom, and searches
        /// for the longest aliphatic chain which is yet unplaced. If the search
        /// encounters an unplaced ring atom, it is also appended to the chain so that
        /// this last bond of the chain can also be laid out. This gives us the
        /// orientation for the attachment of the ring system.
        /// </summary>
        /// <param name="ac">The AtomContainer to be searched</param>
        /// <param name="sphere">A sphere of atoms to start the search with</param>
        /// <param name="pathes">A vector of N paths (N = no of heavy atoms).</param>
        /// <exception cref="CDKException"> Description of the Exception</exception>
        public static void BreadthFirstSearch(IAtomContainer ac, IList <IAtom> sphere, IAtomContainer[] pathes)
        {
            IAtom nextAtom = null;
            int   atomNr;
            int   nextAtomNr;
            //IAtomContainer path = null;
            var newSphere = new List <IAtom>();

            Debug.WriteLine("Start of breadthFirstSearch");

            foreach (var atom in sphere)
            {
                if (!atom.IsInRing)
                {
                    atomNr = ac.Atoms.IndexOf(atom);
                    Debug.WriteLine($"{nameof(BreadthFirstSearch)} around atom {atomNr + 1}");

                    var bonds = ac.GetConnectedBonds(atom);
                    foreach (var curBond in bonds)
                    {
                        nextAtom = curBond.GetOther(atom);
                        if (!nextAtom.IsVisited && !nextAtom.IsPlaced)
                        {
                            nextAtomNr = ac.Atoms.IndexOf(nextAtom);
                            Debug.WriteLine("BreadthFirstSearch is meeting new atom " + (nextAtomNr + 1));
                            pathes[nextAtomNr] = ac.Builder.NewAtomContainer(pathes[atomNr]);
                            Debug.WriteLine("Making copy of path " + (atomNr + 1) + " to form new path " + (nextAtomNr + 1));
                            pathes[nextAtomNr].Atoms.Add(nextAtom);
                            Debug.WriteLine("Adding atom " + (nextAtomNr + 1) + " to path " + (nextAtomNr + 1));
                            pathes[nextAtomNr].Bonds.Add(curBond);
                            if (ac.GetConnectedBonds(nextAtom).Count() > 1)
                            {
                                newSphere.Add(nextAtom);
                            }
                        }
                    }
                }
            }
            if (newSphere.Count > 0)
            {
                for (int f = 0; f < newSphere.Count; f++)
                {
                    newSphere[f].IsVisited = true;
                }
                BreadthFirstSearch(ac, newSphere, pathes);
            }
            Debug.WriteLine("End of breadthFirstSearch");
        }
Пример #6
0
        /// <inheritdoc/>
        public void AddImplicitHydrogens(IAtomContainer container, IAtom atom)
        {
            if (atom.AtomTypeName == null)
            {
                throw new CDKException("IAtom is not typed! " + atom.Symbol);
            }

            if (string.Equals("X", atom.AtomTypeName, StringComparison.Ordinal))
            {
                if (atom.ImplicitHydrogenCount == null)
                {
                    atom.ImplicitHydrogenCount = 0;
                }
                return;
            }

            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}");
            }

            // very simply counting: each missing explicit neighbor is a missing hydrogen
            atom.ImplicitHydrogenCount = type.FormalNeighbourCount - container.GetConnectedBonds(atom).Count();
        }
Пример #7
0
        private static int CountAttachedBonds(IAtomContainer container, IAtom atom, BondOrder order, string symbol)
        {
            var neighbors         = container.GetConnectedBonds(atom).ToReadOnlyList();
            int neighborcount     = neighbors.Count;
            int doubleBondedAtoms = 0;

            for (int i = neighborcount - 1; i >= 0; i--)
            {
                var bond = neighbors[i];
                if (bond.Order == order)
                {
                    if (bond.Atoms.Count == 2 && bond.Contains(atom))
                    {
                        if (symbol != null)
                        {
                            var neighbor = bond.GetOther(atom);
                            if (string.Equals(neighbor.Symbol, symbol, StringComparison.Ordinal))
                            {
                                doubleBondedAtoms++;
                            }
                        }
                        else
                        {
                            doubleBondedAtoms++;
                        }
                    }
                }
            }
            return(doubleBondedAtoms);
        }
Пример #8
0
        private static bool IsCarbonyl(IAtomContainer atomContainer, IAtom atom)
        {
            var neighbors = atomContainer.GetConnectedBonds(atom).ToReadOnlyList();

            if (neighbors.Count != 1)
            {
                return(false);
            }
            var neighbor     = neighbors[0];
            var neighborAtom = neighbor.GetOther(atom);

            if (neighborAtom.AtomicNumber.Equals(AtomicNumbers.C))
            {
                if (neighbor.Order == BondOrder.Single)
                {
                    if (CountAttachedBonds(atomContainer, neighborAtom, BondOrder.Double, "O") == 1)
                    {
                        return(true);
                    }
                }
                else if (neighbor.Order == BondOrder.Double)
                {
                    if (CountAttachedBonds(atomContainer, neighborAtom, BondOrder.Single, "O") == 1)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Пример #9
0
        internal static bool TestIsAlcoholEther(IAtomContainer mol, Func <IAtom, IAtom, bool> expr)
        {
            if (mol == null || expr == null)
            {
                return(false);
            }

            foreach (var atom in mol.Atoms)
            {
                if (!atom.IsOxygenAtom())
                {
                    continue;
                }

                var bonds = mol.GetConnectedBonds(atom)?.ToList();
                if (bonds == null || bonds.Count != 2)
                {
                    continue;
                }

                var end0 = bonds[0].Atoms.FirstOrDefault(a => !a.IsOxygenAtom());
                var end1 = bonds[1].Atoms.FirstOrDefault(a => !a.IsOxygenAtom());

                if (expr(end0, end1))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #10
0
        /// <summary>
        /// Compounds that contain one or more halogens
        /// </summary>
        public static bool IsHalide(this IAtomContainer mol)
        {
            if (mol == null)
            {
                return(false);
            }

            foreach (var atom in mol.Atoms)
            {
                if (!atom.IsCarbonAtom())
                {
                    continue;
                }

                var bonds = mol.GetConnectedBonds(atom)?.ToList();
                if (bonds == null || bonds.Count != 4)
                {
                    continue;
                }

                foreach (var cBond in bonds)
                {
                    var connected = cBond.Atoms.FirstOrDefault(a => !a.IsCarbonAtom());
                    if (connected.ToNfAtom() is IHalogens)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #11
0
 /// <summary>
 /// set the active center for this molecule.
 /// The active center will be those which correspond with [A+]=B.
 /// <pre>
 /// A: Atom with positive charge
 /// =: Double bond
 /// B: Atom
 ///  </pre>
 /// </summary>
 /// <param name="reactant">The molecule to set the activity</param>
 private static void SetActiveCenters(IAtomContainer reactant)
 {
     foreach (var atomi in reactant.Atoms)
     {
         if (atomi.FormalCharge == 1)
         {
             foreach (var bondi in reactant.GetConnectedBonds(atomi))
             {
                 if (bondi.Order != BondOrder.Single)
                 {
                     IAtom atomj = bondi.GetOther(atomi);
                     if (atomj.FormalCharge == 0)
                     {
                         if (!reactant.GetConnectedSingleElectrons(atomj).Any())
                         {
                             atomi.IsReactiveCenter = true;
                             bondi.IsReactiveCenter = true;
                             atomj.IsReactiveCenter = true;
                         }
                     }
                 }
             }
         }
     }
 }
Пример #12
0
        /// <summary>
        /// Produces a HOSE code for Atom <paramref name="root"/> in the <see cref="IAtomContainer"/> <paramref name="ac"/>. The HOSE
        /// code is produced for the number of spheres given by <paramref name="noOfSpheres"/>.
        /// </summary>
        /// <remarks>
        /// <note type="important">
        /// If you want aromaticity to be included in the code, you need
        /// to apply <see cref="Aromaticities.Aromaticity.Apply(IAtomContainer)"/> to <paramref name="ac"/> prior to
        /// using <see cref="GetHOSECode(IAtomContainer, IAtom, int, bool)"/>. This method only gives proper results if the molecule is
        /// fully saturated (if not, the order of the HOSE code might depend on atoms in higher spheres).
        /// This method is known to fail for protons sometimes.
        /// </note>
        /// <note type="important">
        /// Your molecule must contain implicit or explicit hydrogens
        /// for this method to work properly.
        /// </note>
        /// </remarks>
        /// <param name="ac">The IAtomContainer with the molecular skeleton in which the root atom resides</param>
        /// <param name="root">The root atom for which to produce the HOSE code</param>
        /// <param name="noOfSpheres">The number of spheres to look at</param>
        /// <param name="ringsize">The size of the Ring(s) it is in is included in center atom code</param>
        /// <returns>The HOSECode value</returns>
        /// <exception cref="CDKException">Thrown if something is wrong</exception>
        public string GetHOSECode(IAtomContainer ac, IAtom root, int noOfSpheres, bool ringsize)
        {
            var canLabler = new CanonicalLabeler();

            canLabler.CanonLabel(ac);
            centerCode         = "";
            this.atomContainer = ac;
            maxSphere          = noOfSpheres;
            spheres            = new List <TreeNode> [noOfSpheres + 1];
            for (int i = 0; i < ac.Atoms.Count; i++)
            {
                ac.Atoms[i].IsVisited = false;
            }
            root.IsVisited = true;
            rootNode       = new TreeNode(this, root.Symbol, null, root, (double)0, atomContainer.GetConnectedBonds(root).Count(), 0);

            // All we need to observe is how the ranking of substituents in the
            // subsequent spheres of the root nodes influences the ranking of the
            // first sphere, since the order of a node in a sphere depends on the
            // order the preceding node in its branch
            HOSECode = new StringBuilder();
            CreateCenterCode(root, ac, ringsize);
            BreadthFirstSearch(root, true);
            CreateCode();
            FillUpSphereDelimiters();
            Debug.WriteLine($"HOSECodeGenerator -> HOSECode: {HOSECode}");
            return(HOSECode.ToString());
        }
Пример #13
0
        public TargetProperties(IAtomContainer container)
        {
            int i = 0;

            atoms      = new Dictionary <IAtom, int>();
            atomsIndex = new Dictionary <int, IAtom>();
            connectedTargetAtomCountMap = new Dictionary <IAtom, int>();
            connectedTargetAtomListMap  = new Dictionary <IAtom, IReadOnlyList <IAtom> >();
            map = Arrays.CreateJagged <IBond>(container.Atoms.Count, container.Atoms.Count);
            foreach (var atom in container.Atoms)
            {
                int count = container.GetConnectedBonds(atom).Count();
                connectedTargetAtomCountMap[atom] = count;
                var list = container.GetConnectedAtoms(atom);
                if (list != null)
                {
                    connectedTargetAtomListMap[atom] = list.ToReadOnlyList();
                }
                else
                {
                    connectedTargetAtomListMap[atom] = new List <IAtom>();
                }
                atoms[atom]   = i;
                atomsIndex[i] = atom;
                i++;
            }

            foreach (var bond in container.Bonds)
            {
                map[atoms[bond.Begin]][atoms[bond.End]] = bond;
                map[atoms[bond.End]][atoms[bond.Begin]] = bond;
            }
        }
Пример #14
0
        /// <summary>
        /// Helper method to locate two terminal atoms in a container for a given
        /// focus.
        /// </summary>
        /// <param name="container">structure representation</param>
        /// <param name="focus">cumulated atom</param>
        /// <returns>the terminal atoms (unordered)</returns>
        public static IAtom[] FindTerminalAtoms(IAtomContainer container, IAtom focus)
        {
            var focusBonds = container.GetConnectedBonds(focus);

            if (focusBonds.Count() != 2)
            {
                throw new ArgumentException("focus must have exactly 2 neighbors");
            }

            var leftPrev  = focus;
            var rightPrev = focus;
            var left      = focusBonds.ElementAt(0).GetOther(focus);
            var right     = focusBonds.ElementAt(1).GetOther(focus);

            IAtom tmp;

            while (left != null && right != null)
            {
                tmp       = GetOtherNbr(container, left, leftPrev);
                leftPrev  = left;
                left      = tmp;
                tmp       = GetOtherNbr(container, right, rightPrev);
                rightPrev = right;
                right     = tmp;
            }
            return(new IAtom[] { leftPrev, rightPrev });
        }
Пример #15
0
        /// <summary>
        /// Says if an atom as a center of a square planar chirality.
        /// This method uses wedge bonds. 3D coordinates are not taken into account. If there
        /// are no wedge bonds around a potential stereo center, it will not be found.
        /// </summary>
        /// <param name="atom">The atom which is the center</param>
        /// <param name="container">The atomContainer the atom is in</param>
        /// <returns>true=is square planar, false=is not</returns>
        public static bool IsSquarePlanar(IAtomContainer container, IAtom atom)
        {
            var atoms = container.GetConnectedAtoms(atom);

            if (atoms.Count() != 4)
            {
                return(false);
            }
            var bonds = container.GetConnectedBonds(atom);
            int up    = 0;
            int down  = 0;

            foreach (var bond in bonds)
            {
                switch (bond.Stereo)
                {
                case BondStereo.None:
                    break;

                case BondStereo.Up:
                    up++;
                    break;

                case BondStereo.Down:
                    down++;
                    break;
                }
            }
            return(up == 2 && down == 2 && !StereosAreOpposite(container, atom));
        }
Пример #16
0
        /// <summary>
        /// Make a query atom that matches atomic number, h count, valence, and
        /// connectivity. This effectively provides an exact match for that atom
        /// type.
        /// </summary>
        /// <param name="mol">molecule</param>
        /// <param name="atom">atom of molecule</param>
        /// <returns>the query atom (null if attachment point)</returns>
        private static IQueryAtom MatchExact(IAtomContainer mol, IAtom atom)
        {
            var bldr = atom.Builder;

            var elem = atom.AtomicNumber;

            // attach atom skipped
            if (elem == 0)
            {
                return(null);
            }

            var hcnt = atom.ImplicitHydrogenCount.Value;
            var val  = hcnt;
            var con  = hcnt;

            foreach (var bond in mol.GetConnectedBonds(atom))
            {
                val += bond.Order.Numeric();
                con++;
                if (bond.GetOther(atom).AtomicNumber == 1)
                {
                    hcnt++;
                }
            }

            var expr = new Expr(ExprType.Element, elem)
                       .And(new Expr(ExprType.TotalDegree, con))
                       .And(new Expr(ExprType.TotalHCount, hcnt))
                       .And(new Expr(ExprType.Valence, val));

            return(new QueryAtom(expr));
        }
Пример #17
0
        private string EncodePath(IAtomContainer mol, Dictionary <IAtom, List <IBond> > cache, List <IAtom> path, StringBuilder buffer)
        {
            buffer.Clear();
            var prev = path[0];

            buffer.Append(GetAtomSymbol(prev));
            for (int i = 1; i < path.Count; i++)
            {
                var next  = path[i];
                var bonds = cache[prev];

                if (bonds == null)
                {
                    bonds       = mol.GetConnectedBonds(prev).ToList();
                    cache[prev] = bonds;
                }

                var bond = FindBond(bonds, next, prev);
                if (bond == null)
                {
                    throw new InvalidOperationException("FATAL - Atoms in patch were connected?");
                }
                buffer.Append(GetBondSymbol(bond));
                buffer.Append(GetAtomSymbol(next));
                prev = next;
            }
            return(buffer.ToString());
        }
Пример #18
0
        public void SaturateRingSystems(IAtomContainer atomContainer)
        {
            var   rs0      = Cycles.FindSSSR(atomContainer.Builder.NewAtomContainer(atomContainer)).ToRingSet();
            var   ringSets = RingPartitioner.PartitionRings(rs0);
            IAtom atom     = null;

            foreach (var rs in ringSets)
            {
                var containers = RingSetManipulator.GetAllAtomContainers(rs);
                foreach (var ac in containers)
                {
                    var temp = new int[ac.Atoms.Count];
                    for (int g = 0; g < ac.Atoms.Count; g++)
                    {
                        atom    = ac.Atoms[g];
                        temp[g] = atom.ImplicitHydrogenCount.Value;
                        atom.ImplicitHydrogenCount = (atomContainer.GetConnectedBonds(atom).Count() - ac.GetConnectedBonds(atom).Count() - temp[g]);
                    }
                    Saturate(ac);
                    for (int g = 0; g < ac.Atoms.Count; g++)
                    {
                        atom = ac.Atoms[g];
                        atom.ImplicitHydrogenCount = temp[g];
                    }
                }
            }
        }
        /// <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));
        }
        private static void SetActiveCenters(IAtomContainer reactant, CheckReactant checkReatant, CheckReactantAtom checkReatantAtom, CheckAtom checkAtom)
        {
            if (checkReatant != null && !checkReatant(reactant))
            {
                return;
            }

            foreach (var atomi in reactant.Atoms)
            {
                if (checkReatantAtom(reactant, atomi))
                {
                    foreach (var bondi in reactant.GetConnectedBonds(atomi))
                    {
                        if (bondi.Order == BondOrder.Single)
                        {
                            IAtom atomj = bondi.GetOther(atomi);
                            if ((atomj.FormalCharge ?? 0) == 0 &&
                                !reactant.GetConnectedSingleElectrons(atomj).Any())
                            {
                                foreach (var bondj in reactant.GetConnectedBonds(atomj))
                                {
                                    if (bondj.Equals(bondi))
                                    {
                                        continue;
                                    }

                                    if (bondj.Order == BondOrder.Double)
                                    {
                                        IAtom atomk = bondj.GetOther(atomj);
                                        if (checkAtom(atomk) &&
                                            !reactant.GetConnectedSingleElectrons(atomk).Any())
                                        {
                                            atomi.IsReactiveCenter = true;
                                            atomj.IsReactiveCenter = true;
                                            atomk.IsReactiveCenter = true;
                                            bondi.IsReactiveCenter = true;
                                            bondj.IsReactiveCenter = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #21
0
        /// <summary>
        /// Says if an atom as a center of a tetrahedral chirality.
        /// This method uses wedge bonds. 3D coordinates are not taken into account. If there
        /// are no wedge bonds around a potential stereo center, it will not be found.
        /// </summary>
        /// <param name="atom">The atom which is the center</param>
        /// <param name="container">The atomContainer the atom is in</param>
        /// <param name="strict"></param>
        /// <returns>0=is not tetrahedral; &gt;1 is a certain depiction of
        ///     tetrahedrality (evaluated in parse chain)</returns>
        public static int IsTetrahedral(IAtomContainer container, IAtom atom, bool strict)
        {
            var atoms = container.GetConnectedAtoms(atom);

            if (atoms.Count() != 4)
            {
                return(0);
            }
            var bonds = container.GetConnectedBonds(atom);
            int up    = 0;
            int down  = 0;

            foreach (var bond in bonds)
            {
                switch (bond.Stereo)
                {
                case BondStereo.None:
                    break;

                case BondStereo.Up:
                    up++;
                    break;

                case BondStereo.Down:
                    down++;
                    break;
                }
            }
            if (up == 1 && down == 1)
            {
                return(1);
            }
            if (up == 2 && down == 2)
            {
                if (StereosAreOpposite(container, atom))
                {
                    return(2);
                }
                return(0);
            }
            if (up == 1 && down == 0 && !strict)
            {
                return(3);
            }
            if (down == 1 && up == 0 && !strict)
            {
                return(4);
            }
            if (down == 2 && up == 1 && !strict)
            {
                return(5);
            }
            if (down == 1 && up == 2 && !strict)
            {
                return(6);
            }
            return(0);
        }
Пример #22
0
        internal IReactionSet Initiate(IChemObjectSet <IAtomContainer> reactants, IChemObjectSet <IAtomContainer> agents, bool isReverse, CheckReactantAtom checkReactantAtom, CheckAtom checkAtom, CheckBond checkBond)
        {
            CheckInitiateParams(reactants, agents);

            IReactionSet   setOfReactions = reactants.Builder.NewReactionSet();
            IAtomContainer reactant       = reactants[0];

            // if the parameter hasActiveCenter is not fixed yet, set the active centers
            IParameterReaction ipr = base.GetParameterClass(typeof(SetReactionCenter));

            if (ipr != null && !ipr.IsSetParameter)
            {
                SetActiveCenters(reactant, checkReactantAtom, checkAtom, checkBond);
            }

            foreach (var atomi in reactant.Atoms)
            {
                if (atomi.IsReactiveCenter && checkReactantAtom(reactant, atomi))
                {
                    foreach (var bondi in reactant.GetConnectedBonds(atomi))
                    {
                        if (bondi.IsReactiveCenter && checkBond(bondi))
                        {
                            IAtom atomj = bondi.GetOther(atomi);
                            if (atomj.IsReactiveCenter && checkAtom(atomj) && !reactant.GetConnectedSingleElectrons(atomj).Any())
                            {
                                IAtom[] atomList;
                                if (isReverse)
                                {
                                    atomList = new[] { atomj, atomi }
                                }
                                ;
                                else
                                {
                                    atomList = new[] { atomi, atomj }
                                };
                                var bondList = new[] { bondi };

                                IChemObjectSet <IAtomContainer> moleculeSet = reactant.Builder.NewChemObjectSet <IAtomContainer>();

                                moleculeSet.Add(reactant);
                                IReaction reaction = Mechanism.Initiate(moleculeSet, atomList, bondList);
                                if (reaction == null)
                                {
                                    continue;
                                }
                                else
                                {
                                    setOfReactions.Add(reaction);
                                }
                            }
                        }
                    }
                }
            }
            return(setOfReactions);
        }
Пример #23
0
 internal List <IBond> GetBonds(IAtom atom)
 {
     if (!cache.TryGetValue(atom, out List <IBond> bonds))
     {
         bonds       = mol.GetConnectedBonds(atom).ToList();
         cache[atom] = bonds;
     }
     return(bonds);
 }
Пример #24
0
        /// <summary>
        /// Calculates the volume for the given <see cref="IAtomContainer"/>. This methods assumes
        /// that atom types have been perceived.
        /// </summary>
        /// <param name="molecule"><see cref="IAtomContainer"/> to calculate the volume of.</param>
        /// <returns>the volume in cubic Ångström.</returns>
        public static double Calculate(IAtomContainer molecule)
        {
            double sum         = 0.0;
            int    totalHCount = 0;

            foreach (var atom in molecule.Atoms)
            {
                if (!bondiiVolumes.TryGetValue(atom.Symbol, out double bondiiVolume))
                {
                    throw new CDKException("Unsupported element.");
                }

                sum += bondiiVolume;

                // add volumes of implicit hydrogens?
                var type = atomTypeList.GetAtomType(atom.AtomTypeName);
                if (type == null)
                {
                    throw new CDKException($"Unknown atom type for atom: {atom.Symbol}");
                }
                if (type.FormalNeighbourCount == null)
                {
                    throw new CDKException($"Formal neighbor count not given for : {type.AtomTypeName}");
                }
                int hCount = type.FormalNeighbourCount.Value - molecule.GetConnectedBonds(atom).Count();
                sum         += hCount * bondiiVolumes["H"];
                totalHCount += hCount;
            }
            sum -= 5.92 * (molecule.Bonds.Count + totalHCount);

            Aromaticity.CDKLegacy.Apply(molecule);
            var ringSet = Cycles.FindSSSR(molecule).ToRingSet();

            if (ringSet.Count() > 0)
            {
                int aromRingCount    = 0;
                int nonAromRingCount = 0;
                foreach (var ring in ringSet)
                {
                    if (RingIsAromatic(ring))
                    {
                        aromRingCount++;
                    }
                    else
                    {
                        nonAromRingCount++;
                    }
                }

                sum -= 14.7 * aromRingCount;
                sum -= 3.8 * nonAromRingCount;
            }

            return(sum);
        }
Пример #25
0
        internal static List <IBond> Traverse(IAtomContainer atomContainer, IAtom atom, List <IBond> bondList)
        {
            var connectedBonds = atomContainer.GetConnectedBonds(atom);

            foreach (var aBond in connectedBonds)
            {
                if (bondList.Contains(aBond))
                {
                    continue;
                }
                bondList.Add(aBond);
                IAtom nextAtom = aBond.GetOther(atom);
                if (atomContainer.GetConnectedBonds(nextAtom).Count() == 1)
                {
                    continue;
                }
                Traverse(atomContainer, nextAtom, bondList);
            }
            return(bondList);
        }
Пример #26
0
        /// <summary>
        ///  Sums up the degrees of atoms in an atomcontainer
        /// </summary>
        /// <param name="ac">The atomcontainer to be processed</param>
        /// <param name="superAC">The superAtomContainer from which the former has been derived</param>
        /// <returns>sum of degrees</returns>
        static int GetDegreeSum(IAtomContainer ac, IAtomContainer superAC)
        {
            int degreeSum = 0;

            for (int f = 0; f < ac.Atoms.Count; f++)
            {
                degreeSum += superAC.GetConnectedBonds(ac.Atoms[f]).Count();

                degreeSum += ac.Atoms[f].ImplicitHydrogenCount ?? 0;
            }
            return(degreeSum);
        }
Пример #27
0
 /// <summary>
 /// Finds a neighbor attached to 'atom' that is singley bonded and isn't 'exclude'. If no such atom exists, the 'atom' is returned.
 /// </summary>
 /// <param name="container">a molecule container</param>
 /// <param name="atom">the atom to find the neighbor or</param>
 /// <param name="exclude">don't find this atom</param>
 /// <returns>the other atom (or 'atom')</returns>
 private static IAtom FindOtherSinglyBonded(IAtomContainer container, IAtom atom, IAtom exclude)
 {
     foreach (var bond in container.GetConnectedBonds(atom))
     {
         if (!BondOrder.Single.Equals(bond.Order) || bond.Contains(exclude))
         {
             continue;
         }
         return(bond.GetOther(atom));
     }
     return(atom);
 }
        /// <summary>
        /// Create an encoder for axial 2D stereochemistry for the given start and
        /// end atoms.
        /// </summary>
        /// <param name="container">the molecule</param>
        /// <param name="start">start of the cumulated system</param>
        /// <param name="end">end of the cumulated system</param>
        /// <returns>an encoder or null if there are no coordinated</returns>
        internal static IStereoEncoder AxialEncoder(IAtomContainer container, IAtom start, IAtom end)
        {
            var startBonds = container.GetConnectedBonds(start);
            var endBonds   = container.GetConnectedBonds(end);

            if (startBonds.Count() < 2 || endBonds.Count() < 2)
            {
                return(null);
            }

            if (Has2DCoordinates(startBonds) && Has2DCoordinates(endBonds))
            {
                return(Axial2DEncoder(container, start, startBonds, end, endBonds));
            }
            else if (Has3DCoordinates(startBonds) && Has3DCoordinates(endBonds))
            {
                return(Axial3DEncoder(container, start, startBonds, end, endBonds));
            }

            return(null);
        }
Пример #29
0
        /// <summary>
        /// Recursively performs a depth first search in a molecular graphs contained in
        /// the AtomContainer molecule, starting at the root atom and returning when it
        /// hits the target atom.
        /// <para>
        /// CAUTION: This recursive method sets the VISITED flag of each atom
        /// does not reset it after finishing the search. If you want to do the
        /// operation on the same collection of atoms more than once, you have
        /// to set all the VISITED flags to false before each operation
        /// by looping of the atoms and doing a
        /// "atom.Flag = (CDKConstants.VISITED, false);"
        /// </para>
        /// <para>
        /// Note that the path generated by the search will not contain the root atom,
        /// but will contain the target atom
        /// </para>
        /// </summary>
        /// <param name="molecule">The AtomContainer to be searched</param>
        /// <param name="root">The root atom to start the search at</param>
        /// <param name="target">The target</param>
        /// <param name="path">An AtomContainer to be filled with the path</param>
        /// <returns><see langword="true"/> if the target atom was found during this function call</returns>
        public static bool DepthFirstTargetSearch(IAtomContainer molecule, IAtom root, IAtom target, IAtomContainer path)
        {
            var   bonds = molecule.GetConnectedBonds(root);
            IAtom nextAtom;

            root.IsVisited = true;
            bool first = path.IsEmpty();

            if (first)
            {
                path.Atoms.Add(root);
            }
            foreach (var bond in bonds)
            {
                nextAtom = bond.GetOther(root);
                if (!nextAtom.IsVisited)
                {
                    path.Atoms.Add(nextAtom);
                    path.Bonds.Add(bond);
                    if (nextAtom.Equals(target))
                    {
                        if (first)
                        {
                            path.Atoms.Remove(root);
                        }
                        return(true);
                    }
                    else
                    {
                        if (!DepthFirstTargetSearch(molecule, nextAtom, target, path))
                        {
                            // we did not find the target
                            path.Atoms.Remove(nextAtom);
                            path.Bonds.Remove(bond);
                        }
                        else
                        {
                            if (first)
                            {
                                path.Atoms.Remove(root);
                            }
                            return(true);
                        }
                    }
                }
            }
            if (first)
            {
                path.Atoms.Remove(root);
            }
            return(false);
        }
        private static void SetActiveCenters(IAtomContainer reactant, string atomSymbol, int charge)
        {
            foreach (var atomi in reactant.Atoms)
            {
                if (reactant.GetConnectedSingleElectrons(atomi).Count() == 1 && atomi.FormalCharge == charge)
                {
                    foreach (var bondi in reactant.GetConnectedBonds(atomi))
                    {
                        if (bondi.Order == BondOrder.Single)
                        {
                            IAtom atomj = bondi.GetOther(atomi);
                            if (atomj.FormalCharge == 0)
                            {
                                foreach (var bondj in reactant.GetConnectedBonds(atomj))
                                {
                                    if (bondj.Equals(bondi))
                                    {
                                        continue;
                                    }

                                    if (bondj.Order == BondOrder.Single)
                                    {
                                        IAtom atomk = bondj.GetOther(atomj);
                                        if (atomk.Symbol.Equals(atomSymbol, StringComparison.Ordinal) && atomk.FormalCharge == 0)
                                        {
                                            atomi.IsReactiveCenter = true;
                                            atomj.IsReactiveCenter = true;
                                            atomk.IsReactiveCenter = true;
                                            bondi.IsReactiveCenter = true;
                                            bondj.IsReactiveCenter = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }