Exemple #1
0
        /// <summary>
        /// Labels para stereocenter in isolated rings. Any elements which are now
        /// known to not be stereo centers are also eliminated.
        /// </summary>
        /// <param name="symmetry">the symmetry classes of each atom</param>
        private void LabelIsolatedPara(int[] symmetry)
        {
            // auxiliary array, has the symmetry class already been 'visited'
            var visited = new bool[symmetry.Length + 1];

            foreach (var isolated in ringSearch.Isolated())
            {
                var potential   = new List <StereoElement>();
                var trueCentres = new List <StereoElement>();
                var cyclic      = new BitArray(1000);

                foreach (var v in isolated)
                {
                    cyclic.Set(v, true);
                    if (stereocenters[v] == CenterType.Potential)
                    {
                        potential.Add(elements[v]);
                    }
                    else if (stereocenters[v] == CenterType.True)
                    {
                        trueCentres.Add(elements[v]);
                    }
                }

                // there is only 1 potential and 0 true stereocenters in this cycle
                // the element is not a stereocenter
                if (potential.Count + trueCentres.Count < 2)
                {
                    foreach (var element in potential)
                    {
                        stereocenters[element.focus] = CenterType.None;
                    }
                    continue;
                }

                List <StereoElement> paraElements = new List <StereoElement>();
                foreach (var element in potential)
                {
                    switch (element.type)
                    {
                    case CoordinateType.Tetracoordinate:
                    {
                        int[] ws       = element.neighbors;
                        int   nUnique  = 0;
                        bool  terminal = true;

                        foreach (var w in ws)
                        {
                            if (!cyclic[w])
                            {
                                if (!visited[symmetry[w]])
                                {
                                    visited[symmetry[w]] = true;
                                    nUnique++;
                                }
                                else
                                {
                                    if (g[w].Length > 1)
                                    {
                                        terminal = false;
                                    }
                                }
                            }
                        }

                        // reset for next element
                        foreach (var w in ws)
                        {
                            visited[symmetry[w]] = false;
                        }

                        int deg = g[element.focus].Length;

                        if (deg == 3 || (deg == 4 && nUnique == 2))
                        {
                            paraElements.Add(element);
                        }

                        // remove those we know cannot possibly be stereocenters
                        if (deg == 4 && nUnique == 1 && terminal)
                        {
                            stereocenters[element.focus] = CenterType.None;
                        }
                    }
                    break;

                    case CoordinateType.Tricoordinate:
                    {
                        Tricoordinate either = (Tricoordinate)element;
                        if (stereocenters[either.other] == CenterType.True)
                        {
                            paraElements.Add(element);
                        }
                    }
                    break;
                    }
                }

                if (paraElements.Count + trueCentres.Count >= 2)
                {
                    foreach (var para in paraElements)
                    {
                        stereocenters[para.focus] = CenterType.Para;
                    }
                }
                else
                {
                    foreach (var para in paraElements)
                    {
                        stereocenters[para.focus] = CenterType.None;
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Create <see cref="StereoElement"/>
        /// instance for atoms which support stereochemistry. Each new element is
        /// considered a potential stereo center - any atoms which have not been
        /// assigned an element are non stereo centers.
        /// </summary>
        /// <returns>the number of elements created</returns>
        private int CreateElements()
        {
            bool[] tricoordinate = new bool[g.Length];
            int    nElements     = 0;

            // all atoms we don't define as potential are considered
            // non-stereogenic
            Arrays.Fill(stereocenters, CenterType.None);

            for (int i = 0; i < g.Length; i++)
            {
                // determine hydrogen count, connectivity and valence
                int h = container.Atoms[i].ImplicitHydrogenCount.Value;
                int x = g[i].Length + h;
                int d = g[i].Length;
                int v = h;

                if (x < 2 || x > 4 || h > 1)
                {
                    continue;
                }

                int piNeighbor = 0;
                foreach (var w in g[i])
                {
                    if (GetAtomicNumber(container.Atoms[w]) == 1 &&
                        container.Atoms[w].MassNumber == null)
                    {
                        h++;
                    }
                    switch (bondMap[i, w].Order)
                    {
                    case BondOrder.Single:
                        v++;
                        break;

                    case BondOrder.Double:
                        v         += 2;
                        piNeighbor = w;
                        break;

                    default:
                        // triple, quadruple or unset? can't be a stereo centre
                        goto GoNext_VERTICES;
                    }
                }

                // check the type of stereo chemistry supported
                switch (SupportedType(i, v, d, h, x))
                {
                case CoordinateType.Bicoordinate:
                    stereocenters[i] = CenterType.Potential;
                    elements[i]      = new Bicoordinate(i, g[i]);
                    nElements++;
                    int u = g[i][0];
                    int w = g[i][1];
                    if (tricoordinate[u])
                    {
                        stereocenters[u] = CenterType.Potential;
                        elements[u]      = new Tricoordinate(u, i, g[u]);
                    }
                    if (tricoordinate[w])
                    {
                        stereocenters[w] = CenterType.Potential;
                        elements[w]      = new Tricoordinate(w, i, g[w]);
                    }
                    break;

                case CoordinateType.Tricoordinate:
                    u = i;
                    w = piNeighbor;

                    tricoordinate[u] = true;

                    if (!tricoordinate[w])
                    {
                        if (elements[w] != null && elements[w].type == CoordinateType.Bicoordinate)
                        {
                            stereocenters[u] = CenterType.Potential;
                            elements[u]      = new Tricoordinate(u, w, g[u]);
                        }
                        continue;
                    }

                    stereocenters[w] = CenterType.Potential;
                    stereocenters[u] = CenterType.Potential;
                    elements[u]      = new Tricoordinate(u, w, g[u]);
                    elements[w]      = new Tricoordinate(w, u, g[w]);
                    nElements++;
                    break;

                case CoordinateType.Tetracoordinate:
                    elements[i]      = new Tetracoordinate(i, g[i]);
                    stereocenters[i] = CenterType.Potential;
                    nElements++;
                    break;

                default:
                    stereocenters[i] = CenterType.None;
                    break;
                }

GoNext_VERTICES:
                ;
            }

            // link up tetracoordinate atoms accross cumulate systems
            for (int v = 0; v < g.Length; v++)
            {
                if (elements[v] != null && elements[v].type == CoordinateType.Bicoordinate)
                {
                    int u = elements[v].neighbors[0];
                    int w = elements[v].neighbors[1];
                    if (elements[u] != null && elements[w] != null && elements[u].type == CoordinateType.Tricoordinate &&
                        elements[w].type == CoordinateType.Tricoordinate)
                    {
                        ((Tricoordinate)elements[u]).other = w;
                        ((Tricoordinate)elements[w]).other = u;
                    }
                }
            }

            return(nElements);
        }