Example #1
0
 /// <summary>
 /// Decide the bond to use for a ring bond. The bond symbol can be present on
 /// either or both bonded atoms. This method takes those bonds, chooses the
 /// correct one or reports an error if there is a conflict.
 /// </summary>
 /// <remarks>
 /// Equivalent SMILES:
 /// <list type="bullet">
 /// <item>C=1CCCCC=1</item>
 /// <item>C=1CCCCC1    (preferred)</item>
 /// <item>C1CCCCC=1</item>
 /// </list>
 /// </remarks>
 /// <param name="a">a bond</param>
 /// <param name="b">other bond</param>
 /// <param name="pos">the position in the string of bond <paramref name="a"/></param>
 /// <param name="buffer"></param>
 /// <returns>the bond to use for this edge</returns>
 /// <exception cref="InvalidSmilesException">ring bonds did not match</exception>
 public Bond DecideBond(Bond a, Bond b, int pos, CharBuffer buffer)
 {
     if (a == b)
     {
         return(a);
     }
     else if (a == Bond.Implicit)
     {
         return(b);
     }
     else if (b == Bond.Implicit)
     {
         return(a);
     }
     if (strict || a.Inverse() != b)
     {
         throw new InvalidSmilesException($"Ring closure bonds did not match, '{a}'!='{b}':" +
                                          InvalidSmilesException.Display(buffer,
                                                                         pos - buffer.Position,
                                                                         lastBondPos - buffer.Position));
     }
     warnings.Add("Ignored invalid Cis/Trans on ring closure, should flip:" +
                  InvalidSmilesException.Display(buffer,
                                                 pos - buffer.Position,
                                                 lastBondPos - buffer.Position));
     return(Bond.Implicit);
 }
Example #2
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}");
                    }
                }
            }
        }