コード例 #1
0
ファイル: SmartsStereoMatch.cs プロジェクト: ch-hristov/NCDK
        /// <summary>
        /// Verify the tetrahedral stereochemistry (clockwise/anticlockwise) of atom
        /// <paramref name="u"/> is preserved in the target when the <paramref name="mapping"/> is used.
        /// </summary>
        /// <param name="u">tetrahedral index in the target</param>
        /// <param name="mapping">mapping of vertices</param>
        /// <returns>the tetrahedral configuration is preserved</returns>
        private bool CheckTetrahedral(int u, int[] mapping)
        {
            int v = mapping[u];

            if (targetTypes[v] != StereoType.Unset && targetTypes[v] != StereoType.Tetrahedral)
            {
                return(false);
            }

            ITetrahedralChirality queryElement  = (ITetrahedralChirality)queryElements[u];
            ITetrahedralChirality targetElement = (ITetrahedralChirality)targetElements[v];

            SMARTSAtom queryAtom  = (SMARTSAtom)query.Atoms[u];
            IAtom      targetAtom = target.Atoms[v];

            int[] us = Neighbors(queryElement, queryMap);
            us = Map(u, v, us, mapping);
            int p = PermutationParity(us);

            // check if unspecified was allowed
            if (targetTypes[v] == StereoType.Unset)
            {
                if (queryAtom is SMARTSAtom)
                {
                    return(((SMARTSAtom)queryAtom).ChiralityMatches(targetAtom, 0, p));
                }
                else
                {
                    return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, 0));
                }
            }

            // target was non-tetrahedral
            if (targetTypes[v] != StereoType.Tetrahedral)
            {
                return(false);
            }

            int[] vs = Neighbors(targetElement, targetMap);
            int   q  = PermutationParity(vs) * Parity(targetElement.Stereo);

            if (queryAtom is SMARTSAtom)
            {
                return(((SMARTSAtom)queryAtom).ChiralityMatches(targetAtom, q, p));
            }
            else
            {
                q *= p;
                if (q < 0)
                {
                    return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, (int)StereoConfigurations.Left));
                }
                else if (q > 0)
                {
                    return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, (int)StereoConfigurations.Right));
                }
                else
                {
                    return(((QueryAtom)queryAtom).Expression.Matches(targetAtom, 0));
                }
            }
        }
コード例 #2
0
        public object Visit(ASTSmarts node, object data)
        {
            SMARTSAtom atom = null;
            SMARTSBond bond = null;

            ASTAtom first = (ASTAtom)node.JjtGetChild(0);

            atom = (SMARTSAtom)first.JjtAccept(this, null);
            if (data != null)
            { // this is a sub smarts
                bond = (SMARTSBond)((object[])data)[1];
                IAtom prev = (SMARTSAtom)((object[])data)[0];
                if (bond == null)
                { // since no bond was specified it could be aromatic or single
                    bond = new AromaticOrSingleQueryBond(builder);
                    bond.SetAtoms(new[] { prev, atom });
                }
                else
                {
                    bond.SetAtoms(new[] { prev, atom });
                }
                if (neighbors.ContainsKey(prev))
                {
                    neighbors[prev].Add(atom);
                }
                query.Bonds.Add(bond);
                bond = null;
            }
            // first ATOM in expression
            query.Atoms.Add(atom);

            if (BitArrays.GetValue(tetrahedral, query.Atoms.Count - 1))
            {
                List <IAtom> localNeighbors = new List <IAtom>(query.GetConnectedAtoms(atom))
                {
                    atom
                };
                neighbors[atom] = localNeighbors;
            }

            // now process the rest of the bonds/atoms
            for (int i = 1; i < node.JjtGetNumChildren(); i++)
            {
                INode child = node.JjtGetChild(i);
                if (child is ASTLowAndBond)
                {
                    bond = (SMARTSBond)child.JjtAccept(this, data);
                }
                else if (child is ASTAtom)
                {
                    SMARTSAtom newAtom = (SMARTSAtom)child.JjtAccept(this, null);
                    if (bond == null)
                    { // since no bond was specified it could be aromatic or single
                        bond = new AromaticOrSingleQueryBond(builder);
                    }
                    bond.SetAtoms(new[] { atom, newAtom });
                    query.Bonds.Add(bond);
                    query.Atoms.Add(newAtom);

                    if (neighbors.ContainsKey(atom))
                    {
                        neighbors[atom].Add(newAtom);
                    }
                    if (BitArrays.GetValue(tetrahedral, query.Atoms.Count - 1))
                    {
                        List <IAtom> localNeighbors = new List <IAtom>(query.GetConnectedAtoms(newAtom))
                        {
                            newAtom
                        };
                        neighbors[newAtom] = localNeighbors;
                    }

                    atom = newAtom;
                    bond = null;
                }
                else if (child is ASTSmarts)
                { // another smarts
                    child.JjtAccept(this, new object[] { atom, bond });
                    bond = null;
                }
                else if (child is ASTRingIdentifier)
                {
                    HandleRingClosure(atom, (ASTRingIdentifier)child);
                }
                else
                {
                    throw new InvalidOperationException("Unhandled node type: " + child.GetType());
                }
            }

            return(query);
        }