/// <summary> /// Internal - load the SMARTS patterns for each atom type from MMFFSYMB.sma. /// </summary> /// <param name="smaIn">input stream of MMFFSYMB.sma</param> /// <returns>array of patterns</returns> /// <exception cref="IOException"></exception> internal static AtomTypePattern[] LoadPatterns(Stream smaIn) { var matchers = new List <AtomTypePattern>(); using (var br = new StreamReader(smaIn)) { string line = null; while ((line = br.ReadLine()) != null) { if (SkipLine(line)) { continue; } var cols = Strings.Tokenize(line, ' '); var sma = cols[0]; var symb = cols[1]; try { matchers.Add(new AtomTypePattern(SmartsPattern.Create(sma).SetPrepare(false), symb)); } catch (ArgumentException ex) { throw new IOException(ex.Message); } } return(matchers.ToArray()); } }
/// <summary> /// Create a pattern for the provided SMARTS - if the SMARTS is '?' a pattern /// is not created. /// </summary> /// <param name="smarts">a smarts pattern</param> /// <param name="builder">chem object builder</param> /// <returns>the pattern to match</returns> private static Pattern CreatePattern(string smarts, IChemObjectBuilder builder) { var ptrn = SmartsPattern.Create(smarts, builder); ptrn.SetPrepare(false); // avoid redoing aromaticity etc return(ptrn); }
/// <summary> /// Create a pattern for the provided SMARTS - if the SMARTS is '?' a pattern /// is not created. /// </summary> /// <param name="smarts">a smarts pattern</param> /// <returns>the pattern to match</returns> private static Pattern CreatePattern(string smarts) { var ptrn = SmartsPattern.Create(smarts); ptrn.SetPrepare(false); // avoid redoing aromaticity etc return(ptrn); }
/// <summary> /// Set the SMARTS patterns. /// </summary> /// <param name="smarts">the SMARTS</param> private void SetSmarts(IEnumerable <string> smarts) { keys.Clear(); foreach (var key in smarts) { var qmol = new QueryAtomContainer(); var ptrn = SmartsPattern.Create(key); ptrn.SetPrepare(false); // prepare is done once keys.Add(new Key(key, ptrn)); } }
/// <summary> /// This method calculates occurrences of the Kier & Hall E-state fragments. /// </summary> /// <returns>Counts of the fragments</returns> public Result Calculate(IAtomContainer container) { container = AtomContainerManipulator.RemoveHydrogens(container); var counts = new int[SMARTS.Count]; SmartsPattern.Prepare(container); for (int i = 0; i < SMARTS.Count; i++) { counts[i] = SMARTS[i].MatchAll(container).CountUnique(); } return(new Result(counts)); }
/// <summary> /// Creat a new query pharmacophore group /// </summary> /// <param name="symbol">The symbol for the group</param> /// <param name="smarts">The SMARTS pattern to be used for matching</param> public PharmacophoreQueryAtom(string symbol, string smarts) { this.Symbol = symbol; this.Smarts = smarts; // Note that we allow a special form of SMARTS where the | operator // represents logical or of multi-atom groups (as opposed to ',' // which is for single atom matches) var subSmarts = Strings.Tokenize(smarts, '|'); CompiledSmarts = new SmartsPattern[subSmarts.Count]; for (int i = 0; i < CompiledSmarts.Length; i++) { CompiledSmarts[i] = SmartsPattern.Create(subSmarts[i]).SetPrepare(false); } }
/// <inheritdoc/> public override IBitFingerprint GetBitFingerprint(IAtomContainer atomContainer) { int bitsetLength = PATTERNS.Count; BitArray fingerPrint = new BitArray(bitsetLength); SmartsPattern.Prepare(atomContainer); for (int i = 0; i < PATTERNS.Count; i++) { if (PATTERNS[i].Matches(atomContainer)) { fingerPrint.Set(i, true); } } return(new BitSetFingerprint(fingerPrint)); }
/// <inheritdoc/> public override ICountFingerprint GetCountFingerprint(IAtomContainer atomContainer) { if (!keys.Any()) { throw new CDKException("No substructures were defined"); } // init SMARTS invariants (connectivity, degree, etc) SmartsPattern.Prepare(atomContainer); var map = new SortedDictionary <int, int>(); for (int i = 0; i < keys.Count; i++) { var ptrn = keys[i].Pattern; map[i] = ptrn.MatchAll(atomContainer).CountUnique(); } return(new CountFingerprint(map)); }
/// <inheritdoc/> public override IBitFingerprint GetBitFingerprint(IAtomContainer atomContainer) { if (!keys.Any()) { throw new CDKException("No substructures were defined"); } SmartsPattern.Prepare(atomContainer); var fingerPrint = new BitArray(keys.Count); for (int i = 0; i < keys.Count; i++) { if (keys[i].Pattern.Matches(atomContainer)) { fingerPrint[i] = true; } } return(new BitSetFingerprint(fingerPrint)); }
private void PrepareInput(IAtomContainer input) { SmartsPattern.Prepare(input); }
/// <inheritdoc/> public override IBitFingerprint GetBitFingerprint(IAtomContainer container) { var keys = GetKeys(container.Builder); var fp = new BitArray(keys.Count); // init SMARTS invariants (connectivity, degree, etc) SmartsPattern.Prepare(container); int numAtoms = container.Atoms.Count; var bmap = EdgeToBondMap.WithSpaceFor(container); var adjlist = GraphUtil.ToAdjList(container, bmap); for (int i = 0; i < keys.Count; i++) { var key = keys[i]; var pattern = key.Pattern; switch (key.Smarts) { case "[!*]": break; case "[!0]": foreach (IAtom atom in container.Atoms) { if (atom.MassNumber != null) { fp.Set(i, true); break; } } break; // ring bits case "[R]1@*@*@1": // 3M RING bit22 case "[R]1@*@*@*@1": // 4M RING bit11 case "[R]1@*@*@*@*@1": // 5M RING bit96 case "[R]1@*@*@*@*@*@1": // 6M RING bit163, x2=bit145 case "[R]1@*@*@*@*@*@*@1": // 7M RING, bit19 case "[R]1@*@*@*@*@*@*@*@1": // 8M RING, bit101 // handled separately break; case "(*).(*)": // bit 166 (*).(*) we can match this in SMARTS but it's faster to just // count the number of components or in this case try to traverse the // component, iff there are some atoms not visited we have more than // one component bool[] visit = new bool[numAtoms]; if (numAtoms > 1 && VisitPart(visit, adjlist, 0, -1) < numAtoms) { fp.Set(165, true); } break; default: if (key.Count == 0) { if (pattern.Matches(container)) { fp.Set(i, true); } } else { // check if there are at least 'count' unique hits, key.count = 0 // means find at least one match hence we add 1 to out limit if (pattern.MatchAll(container).GetUniqueAtoms().AtLeast(key.Count + 1)) { fp.Set(i, true); } } break; } } // Ring Bits // threshold=126, see AllRingsFinder.Threshold.PubChem_97 if (numAtoms > 2) { AllCycles allcycles = new AllCycles(adjlist, Math.Min(8, numAtoms), 126); int numArom = 0; foreach (int[] path in allcycles.GetPaths()) { // length is +1 as we repeat the closure vertex switch (path.Length) { case 4: // 3M bit22 fp.Set(21, true); break; case 5: // 4M bit11 fp.Set(10, true); break; case 6: // 5M bit96 fp.Set(95, true); break; case 7: // 6M bit163->bit145, bit124 numArom > 1 if (numArom < 2) { if (IsAromPath(path, bmap)) { numArom++; if (numArom == 2) { fp.Set(124, true); } } } if (fp[162]) { fp.Set(144, true); // >0 } else { fp.Set(162, true); // >1 } break; case 8: // 7M bit19 fp.Set(18, true); break; case 9: // 8M bit101 fp.Set(100, true); break; } } } return(new BitSetFingerprint(fp)); }