public object Visit(ASTSmarts node, object data) { System.Console.Out.WriteLine(IndentString() + node); ++indent; data = node.ChildrenAccept(this, data); --indent; return(data); }
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); }
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); }
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); }