Example #1
0
        /// <summary>
        /// Close the ring bond with the specified 'rnum'.
        /// </summary>
        /// <param name="rnum">ring number</param>
        /// <param name="buffer"></param>
        /// <exception cref="InvalidSmilesException">bond types did not match</exception>
        private void CloseRing(int rnum, CharBuffer buffer)
        {
            var rbond = rings[rnum];

            rings[rnum] = null;
            int u = rbond.u;
            int v = stack.Peek();

            if (u == v)
            {
                throw new InvalidSmilesException("Endpoints of ringbond are the same - loops are not allowed",
                                                 buffer);
            }

            if (g.Adjacent(u, v))
            {
                throw new InvalidSmilesException("Endpoints of ringbond are already connected - multi-edges are not allowed",
                                                 buffer);
            }

            bond = DecideBond(rbond.bond, bond.Inverse(), rbond.pos, buffer);

            var e = new Edge(u, v, bond);

            if (bond.IsDirectional)
            {
                BitArrays.EnsureCapacity(checkDirectionalBonds, Math.Max(u, v) + 1);
                checkDirectionalBonds.Set(u, true);
                checkDirectionalBonds.Set(v, true);
                if (rbond.bond.IsDirectional)
                {
                    bondStrPos[e] = rbond.pos;
                }
                else
                {
                    bondStrPos[e] = lastBondPos;
                }
            }

            g.AddEdge(e);
            bond = Bond.Implicit;
            // adjust the arrangement replacing where this ring number was openned
            arrangement[rbond.u].Replace(-rnum, stack.Peek());
            if (arrangement.ContainsKey(v))
            {
                arrangement[v].Add(rbond.u);
            }
            openRings--;
        }
Example #2
0
        /// <summary>
        /// Add an atom and bond with the atom on the stack (if available and non-dot bond).
        /// </summary>
        /// <param name="a">an atom to add</param>
        /// <param name="buffer"></param>
        private void AddAtom(IAtom a, CharBuffer buffer)
        {
            int v = g.AddAtom(a);

            if (!stack.IsEmpty)
            {
                int u = stack.Pop();

                if (bond != Bond.Dot)
                {
                    var e = new Edge(u, v, bond);
                    if (bond.IsDirectional)
                    {
                        bondStrPos[e] = lastBondPos;
                        BitArrays.EnsureCapacity(checkDirectionalBonds, Math.Max(u, v) + 1);
                        checkDirectionalBonds.Set(u, true);
                        checkDirectionalBonds.Set(v, true);
                    }
                    g.AddEdge(e);
                    if (arrangement.ContainsKey(u))
                    {
                        arrangement[u].Add(v);
                    }
                }
                else
                {
                    start.Add(v); // start of a new run
                }
            }
            stack.Push(v);
            bond = Bond.Implicit;

            // configurations used to create topologies after parsing
            if (configuration != Configuration.Unknown)
            {
                g.AddFlags(Graph.HAS_ATM_STRO);
                configurations.Add(v, configuration);
                configuration = Configuration.Unknown;
            }
        }
Example #3
0
        /// <summary>
        /// Create the topologies (stereo configurations) for the chemical graph. The
        /// topologies define spacial arrangement around atoms.
        /// </summary>
        private void CreateTopologies(CharBuffer buffer)
        {
            // create topologies (stereo configurations)
            foreach (var e in configurations)
            {
                AddTopology(e.Key,
                            Topology.ToExplicit(g, e.Key, e.Value));
            }

            for (int v = BitArrays.NextSetBit(checkDirectionalBonds, 0); v >= 0; v = BitArrays.NextSetBit(checkDirectionalBonds, v + 1))
            {
                int nUpV   = 0;
                int nDownV = 0;
                int nUpW   = 0;
                int nDownW = 0;
                int w      = -1;

                {
                    int d = g.Degree(v);
                    for (int j = 0; j < d; ++j)
                    {
                        Edge e    = g.EdgeAt(v, j);
                        Bond bond = e.GetBond(v);
                        if (bond == Bond.Up)
                        {
                            nUpV++;
                        }
                        else if (bond == Bond.Down)
                        {
                            nDownV++;
                        }
                        else if (bond == Bond.Double)
                        {
                            w = e.Other(v);
                        }
                    }
                }

                if (w < 0)
                {
                    continue;
                }

                BitArrays.EnsureCapacity(checkDirectionalBonds, w + 1);
                checkDirectionalBonds.Set(w, false);

                {
                    int d = g.Degree(w);
                    for (int j = 0; j < d; ++j)
                    {
                        Edge e    = g.EdgeAt(w, j);
                        Bond bond = e.GetBond(w);
                        if (bond == Bond.Up)
                        {
                            nUpW++;
                        }
                        else if (bond == Bond.Down)
                        {
                            nDownW++;
                        }
                    }
                }

                if (nUpV + nDownV == 0 || nUpW + nDownW == 0)
                {
                    continue;
                }

                if (nUpV > 1 || nDownV > 1)
                {
                    int offset1 = -1, offset2 = -1;
                    foreach (var e in g.GetEdges(v))
                    {
                        if (e.Bond.IsDirectional)
                        {
                            if (offset1 < 0)
                            {
                                offset1 = bondStrPos[e];
                            }
                            else
                            {
                                offset2 = bondStrPos[e];
                            }
                        }
                    }
                    var errorPos = InvalidSmilesException.Display(buffer,
                                                                  offset1 - buffer.Length,
                                                                  offset2 - buffer.Length);
                    if (strict)
                    {
                        throw new InvalidSmilesException($"Ignored invalid Cis/Trans specification: {errorPos}");
                    }
                    else
                    {
                        warnings.Add($"Ignored invalid Cis/Trans specification: {errorPos}");
                    }
                }
                if (nUpW > 1 || nDownW > 1)
                {
                    int offset1 = -1;
                    int offset2 = -1;
                    foreach (var e in g.GetEdges(w))
                    {
                        if (e.Bond.IsDirectional)
                        {
                            if (offset1 < 0)
                            {
                                offset1 = bondStrPos[e];
                            }
                            else
                            {
                                offset2 = bondStrPos[e];
                            }
                        }
                    }
                    var errorPos = InvalidSmilesException.Display(buffer,
                                                                  offset1 - buffer.Length,
                                                                  offset2 - buffer.Length);
                    if (strict)
                    {
                        throw new InvalidSmilesException($"Ignored invalid Cis/Trans specification: {errorPos}");
                    }
                    else
                    {
                        warnings.Add($"Ignored invalid Cis/Trans specification: {errorPos}");
                    }
                }
            }
        }
Example #4
0
 /// <summary>
 ///  Adds a new node to the RGraph.
 /// </summary>
 /// <param name="newNode">The node to add to the graph</param>
 public void AddNode(RNode newNode)
 {
     graph.Add(newNode);
     BitArrays.EnsureCapacity(graphBitSet, graph.Count);
     graphBitSet.Set(graph.Count - 1, true);
 }
Example #5
0
        /// <summary>
        /// Create the topologies (stereo configurations) for the chemical graph. The
        /// topologies define spacial arrangement around atoms.
        /// </summary>
        private void CreateTopologies(CharBuffer buffer)
        {
            // create topologies (stereo configurations)
            foreach (var e in configurations)
            {
                AddTopology(e.Key,
                            Topology.ToExplicit(g, e.Key, e.Value));
            }

            for (int v = BitArrays.NextSetBit(checkDirectionalBonds, 0); v >= 0; v = BitArrays.NextSetBit(checkDirectionalBonds, v + 1))
            {
                int nUpV   = 0;
                int nDownV = 0;
                int nUpW   = 0;
                int nDownW = 0;
                int w      = -1;

                {
                    int d = g.Degree(v);
                    for (int j = 0; j < d; ++j)
                    {
                        Edge e    = g.EdgeAt(v, j);
                        Bond bond = e.GetBond(v);
                        if (bond == Bond.Up)
                        {
                            nUpV++;
                        }
                        else if (bond == Bond.Down)
                        {
                            nDownV++;
                        }
                        else if (bond == Bond.Double)
                        {
                            w = e.Other(v);
                        }
                    }
                }

                if (w < 0)
                {
                    continue;
                }

                BitArrays.EnsureCapacity(checkDirectionalBonds, w + 1);
                checkDirectionalBonds.Set(w, false);

                {
                    int d = g.Degree(w);
                    for (int j = 0; j < d; ++j)
                    {
                        Edge e    = g.EdgeAt(w, j);
                        Bond bond = e.GetBond(w);
                        if (bond == Bond.Up)
                        {
                            nUpW++;
                        }
                        else if (bond == Bond.Down)
                        {
                            nDownW++;
                        }
                    }
                }

                if (nUpV + nDownV == 0 || nUpW + nDownW == 0)
                {
                    continue;
                }

                if (nUpV > 1)
                {
                    throw new InvalidSmilesException("Multiple directional bonds on atom " + v, buffer);
                }
                if (nDownV > 1)
                {
                    throw new InvalidSmilesException("Multiple directional bonds on atom " + v, buffer);
                }
                if (nUpW > 1)
                {
                    throw new InvalidSmilesException("Multiple directional bonds on atom " + w, buffer);
                }
                if (nDownW > 1)
                {
                    throw new InvalidSmilesException("Multiple directional bonds on atom " + w, buffer);
                }
            }
        }