Exemplo n.º 1
0
        /// <summary>
        /// Given a double bond edge traverse the neighbors of one of the endpoints
        /// and accumulate any explicit replacements in the <paramref name="acc"/> accumulator.
        /// </summary>
        /// <param name="g">the chemical graph</param>
        /// <param name="e">a edge in the graph ('double bond type')</param>
        /// <param name="u">a endpoint of the edge <paramref name="e"/></param>
        /// <param name="acc">accumulator for new edges</param>
        /// <returns>does the edge <paramref name="e"/> need to be reconsidered later</returns>
        /// <exception cref="InvalidSmilesException">thrown if the edge could not be converted</exception>
        private bool ReplaceImplWithExpl(Graph g,
                                         Edge e,
                                         int u,
                                         Dictionary <Edge, Edge> acc)
        {
            Edge implicit_ = null;
            Edge explicit_ = null;

            foreach (var f in g.GetEdges(u))
            {
                Edge f2 = acc.ContainsKey(f) ? acc[f] : f;
                var  aa = f2.GetBond(u);
                if (aa == Bond.Single || aa == Bond.Implicit)
                {
                    if (implicit_ != null)
                    {
                        return(true);
                    }
                    implicit_ = f;
                }
                else if (aa == Bond.Double)
                {
                    if (!f.Equals(e))
                    {
                        return(false);
                    }
                }
                else if (aa == Bond.Up || aa == Bond.Down)
                {
                    if (explicit_ != null)
                    {
                        if (acc.ContainsKey(explicit_))
                        {
                            explicit_ = acc[explicit_];
                        }

                        // original bonds are invalid
                        if ((f.Bond == Bond.Up || f.Bond == Bond.Down) &&
                            explicit_.GetBond(u).Inverse() != f.GetBond(u))
                        {
                            throw new InvalidSmilesException("invalid double bond configuration");
                        }

                        if (explicit_.GetBond(u).Inverse() != f2.GetBond(u))
                        {
                            acc[f] = f2.Inverse();
                            BitArray visited = new BitArray(g.Order);
                            visited.Set(u, true);
                            InvertExistingDirectionalLabels(g, visited, acc, f2
                                                            .Other(u));
                        }
                        return(false);
                    }
                    explicit_ = f;
                }
            }

            // no implicit or explicit bond? don't do anything
            if (implicit_ == null || explicit_ == null)
            {
                return(false);
            }

            if (acc.ContainsKey(explicit_))
            {
                explicit_ = acc[explicit_];
            }

            int v = implicit_.Other(u);

            if (!acc.TryGetValue(implicit_, out Edge existing))
            {
                existing = null;
            }
            acc[implicit_] = new Edge(u,
                                      v,
                                      explicit_.GetBond(u)
                                      .Inverse());

            if (existing != null && existing.GetBond(u) != explicit_.GetBond(u).Inverse())
            {
                throw new InvalidSmilesException("unable to assign explicit type for " + implicit_);
            }

            return(false);
        }