/// <summary> /// The cycle path is accepted if it does not have chord. /// </summary> /// <param name="path">a path</param> /// <param name="graph">the adjacency of atoms</param> /// <returns>accept the path as unchorded</returns> private static bool Accept(int[] path, int[][] graph) { BitArray vertices = new BitArray(0); foreach (var v in path) { BitArrays.SetValue(vertices, v, true); } for (int j = 1; j < path.Length; j++) { int v = path[j]; int prev = path[j - 1]; int next = path[(j + 1) % (path.Length - 1)]; foreach (var w in graph[v]) { // chord found if (w != prev && w != next && BitArrays.GetValue(vertices, w)) { return(false); } } } return(true); }
public override bool Matches(IAtom atom) { if (!((IQueryAtom)query.Atoms[0]).Matches(atom)) { return(false); } if (query.Atoms.Count == 1) { return(true); } IAtomContainer target = Invariants(atom).Target; if (!cache.TryGetValue(target, out BitArray v)) { BitArray hits = new BitArray(0); foreach (var mapping in Pattern.CreateSubstructureFinder(query).MatchAll(target)) { BitArrays.SetValue(hits, mapping[0], true); } v = hits; cache[target] = v; } return(BitArrays.GetValue(v, target.Atoms.IndexOf(atom))); }
public bool this[int index] { get { return(BitArrays.GetValue(bitset, index)); } set { BitArrays.SetValue(bitset, index, value); } }
/// <summary> /// Check if the atom at index <paramref name="v"/> is a member of a small ring /// (n=3). This is the only time a 3 valent nitrogen is allowed by InChI to /// be potentially stereogenic. /// </summary> /// <param name="v">atom index</param> /// <returns>the atom is a member of a 3 member ring</returns> private bool InThreeMemberRing(int v) { var adj = new BitArray(0); foreach (var w in g[v]) { BitArrays.SetValue(adj, w, true); } // is a neighbors neighbor adjacent? foreach (var w in g[v]) { foreach (var u in g[w]) { if (BitArrays.GetValue(adj, u)) { return(true); } } } return(false); }
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); }