示例#1
0
 public object Visit(ASTSmarts node, object data)
 {
     System.Console.Out.WriteLine(IndentString() + node);
     ++indent;
     data = node.ChildrenAccept(this, data);
     --indent;
     return(data);
 }
示例#2
0
        public object Visit(ASTSmarts node, object data)
        {
            string local = "";

            for (int i = 0; i < node.JjtGetNumChildren(); i++)
            {
                INode child = node.JjtGetChild(i);
                if (child is ASTAtom)
                {
                    local = (string)child.JjtAccept(this, local);
                }
                else if (child is ASTLowAndBond)
                {
                    i++;
                    INode nextChild = node.JjtGetChild(i); // the next child should
                                                           // be another smarts
                    string bond = (string)child.JjtAccept(this, local);
                    local = local + bond;
                    local = (string)nextChild.JjtAccept(this, local);
                }
                else if (child is ASTSmarts)
                { // implicit single bond
                    if (local.Length != 0)
                    {
                        local = local + "-";
                    }
                    local = (string)child.JjtAccept(this, local);
                }
                else if (child is ASTExplicitAtom)
                {
                    if (local.Length != 0)
                    {
                        local = local + "-";
                    }
                    local = (string)child.JjtAccept(this, local);
                }
            }
            return(data + local);
        }
示例#3
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);
        }
示例#4
0
        public object Visit(ASTGroup node, object data)
        {
            IAtomContainer fullQuery = (IAtomContainer)data;

            if (fullQuery == null)
            {
                fullQuery = new QueryAtomContainer(builder);
            }

            // keeps track of component grouping
            var components = fullQuery.GetProperty <int[]>("COMPONENT.GROUPING", Array.Empty <int>());
            int maxId      = 0;

            if (components.Length > 0)
            {
                foreach (int id in components)
                {
                    if (id > maxId)
                    {
                        maxId = id;
                    }
                }
            }

            for (int i = 0; i < node.JjtGetNumChildren(); i++)
            {
                ASTSmarts smarts = (ASTSmarts)node.JjtGetChild(i);
                ringAtoms = new RingIdentifierAtom[10];
                query     = new QueryAtomContainer(builder);

                smarts.JjtAccept(this, null);

                // update component info
                if (components.Length > 0 || smarts.ComponentId > 0)
                {
                    components = Arrays.CopyOf(components, 1 + fullQuery.Atoms.Count + query.Atoms.Count);
                    int id = smarts.ComponentId;
                    Arrays.Fill(components, fullQuery.Atoms.Count, components.Length, id);
                    if (id > maxId)
                    {
                        maxId = id;
                    }
                }

                fullQuery.Add(query);
            }

            // only store if there was a component grouping
            if (maxId > 0)
            {
                components[components.Length - 1] = maxId; // we left space to store how many groups there were
                fullQuery.SetProperty("COMPONENT.GROUPING", components);
            }

            // create tetrahedral elements
            foreach (var atom in neighbors.Keys)
            {
                IList <IAtom> localNeighbors = neighbors[atom];
                if (localNeighbors.Count == 4)
                {
                    fullQuery.StereoElements.Add(new TetrahedralChirality(atom, localNeighbors.ToArray(),
                                                                          TetrahedralStereo.Clockwise)); // <- to be modified later
                }
                else if (localNeighbors.Count == 5)
                {
                    localNeighbors.Remove(atom);                                                         // remove central atom (which represented implicit part)
                    fullQuery.StereoElements.Add(new TetrahedralChirality(atom, localNeighbors.ToArray(),
                                                                          TetrahedralStereo.Clockwise)); // <- to be modified later
                }
            }

            // for each double bond, find the stereo bonds. Currently doesn't
            // handle logical bonds i.e. C/C-,=C/C
            foreach (var bond in doubleBonds)
            {
                IAtom      left      = bond.Begin;
                IAtom      right     = bond.End;
                StereoBond leftBond  = FindStereoBond(left);
                StereoBond rightBond = FindStereoBond(right);
                if (leftBond == null || rightBond == null)
                {
                    continue;
                }
                DoubleBondConformation conformation = leftBond.GetDirection(left) == rightBond.GetDirection(right) ? DoubleBondConformation.Together
                       : DoubleBondConformation.Opposite;
                fullQuery.StereoElements.Add(new DoubleBondStereochemistry(bond, new IBond[] { leftBond, rightBond },
                                                                           conformation));
            }

            return(fullQuery);
        }