/// <summary> /// Returns a Dictionary with the AtomNumbers, the first number corresponds to the first (or the largest /// AtomContainer) atomContainer. /// </summary> /// <remarks>Only for similar and aligned molecules with coordinates!</remarks> /// <param name="firstAtomContainer">the (largest) first aligned AtomContainer which is the reference</param> /// <param name="secondAtomContainer">the second aligned AtomContainer</param> /// <param name="mappedAtoms"></param> /// <exception cref="CDKException">if there is an error in the UniversalIsomorphismTester</exception> public static void MapAtomsOfAlignedStructures(IAtomContainer firstAtomContainer, IAtomContainer secondAtomContainer, IDictionary <int, int> mappedAtoms) { // Dictionary atoms onto each other if (firstAtomContainer.Atoms.Count < 1 & secondAtomContainer.Atoms.Count < 1) { return; } try { var list = new UniversalIsomorphismTester().GetSubgraphAtomsMap(firstAtomContainer, secondAtomContainer); for (int i = 0; i < list.Count; i++) { var map = list[i]; var atom1 = firstAtomContainer.Atoms[map.Id1]; var atom2 = secondAtomContainer.Atoms[map.Id2]; if (CheckAtomMapping(firstAtomContainer, secondAtomContainer, firstAtomContainer.Atoms.IndexOf(atom1), secondAtomContainer.Atoms.IndexOf(atom2))) { mappedAtoms.Add(firstAtomContainer.Atoms.IndexOf(atom1), secondAtomContainer.Atoms.IndexOf(atom2)); } else { Trace.TraceError("Error: Atoms are not similar !!"); } } } catch (CDKException e) { throw new CDKException($"Error in UniversalIsomorphismTester due to: {e.Message}", e); } }
public void TestSingleAtomMatching2() { var sp = CDK.SmilesParser; var target = sp.ParseSmiles("CNC"); var queryac = sp.ParseSmiles("C"); var query = QueryAtomContainerCreator.CreateSymbolAndBondOrderQueryContainer(queryac); var matches = uiTester.GetIsomorphMaps(target, query).ToReadOnlyList(); Assert.AreEqual(2, matches.Count); Assert.AreEqual(1, matches[0].Count); Assert.AreEqual(1, matches[1].Count); var map1 = matches[0][0]; var map2 = matches[1][0]; Assert.AreEqual(0, map1.Id1); Assert.AreEqual(0, map1.Id2); Assert.AreEqual(2, map2.Id1); Assert.AreEqual(0, map2.Id2); var atomMappings = UniversalIsomorphismTester.MakeAtomsMapsOfBondsMaps(matches, target, query); Assert.IsTrue(Compares.AreDeepEqual(matches, atomMappings)); }
public void TestSingleAtomMismatching() { var sp = CDK.SmilesParser; var target = sp.ParseSmiles("C"); var query = sp.ParseSmiles("N"); var tester = new UniversalIsomorphismTester(); Assert.IsFalse(tester.IsIsomorph(target, query), "Single carbon and nitrogen should not match"); Assert.IsFalse(tester.IsIsomorph(query, target), "Single nitrogen and carbon should not match"); }
public void TestSingleAtomMatching() { var sp = CDK.SmilesParser; var target = sp.ParseSmiles("C"); var query = sp.ParseSmiles("C"); var tester = new UniversalIsomorphismTester(); Assert.IsTrue(tester.IsIsomorph(target, query)); Assert.IsTrue(tester.IsIsomorph(query, target)); }
static void Main() { UniversalIsomorphismTester universalIsomorphismTester = new UniversalIsomorphismTester(); #region SmilesParser sp = new SmilesParser(); IAtomContainer atomContainer = sp.ParseSmiles("CC(=O)OC(=O)C"); // acetic acid anhydride IAtomContainer SMILESquery = sp.ParseSmiles("CC"); // ethylene IQueryAtomContainer query = QueryAtomContainerCreator.CreateBasicQueryContainer(SMILESquery); bool isSubstructure = universalIsomorphismTester.IsSubgraph(atomContainer, query); #endregion }
/// <summary> /// Gets the fragments from a target matching a set of query fragments. /// </summary> /// <remarks> /// This method returns a list of lists. Each list contains the atoms of the target <see cref="IAtomContainer"/> /// that arise in the mapping of bonds in the target molecule to the bonds in the query fragment. /// The query fragments should be constructed /// using the <see cref="QueryAtomContainerCreator.CreateAnyAtomAnyBondContainer(IAtomContainer, bool)"/> method of the <see cref="QueryAtomContainerCreator"/> /// CDK class, since we are only interested in connectivity and not actual atom or bond type information. /// </remarks> /// <param name="atomContainer">The target <see cref="IAtomContainer"/></param> /// <param name="queries">An array of query fragments</param> /// <returns>A list of lists, each list being the atoms that match the query fragments</returns> public static List <List <int> > GetFragments(IAtomContainer atomContainer, QueryAtomContainer[] queries) { var universalIsomorphismTester = new UniversalIsomorphismTester(); var uniqueSubgraphs = new List <List <int> >(); foreach (var query in queries) { IReadOnlyList <IReadOnlyList <RMap> > subgraphMaps = null; try { // we get the list of bond mappings subgraphMaps = universalIsomorphismTester.GetSubgraphMaps(atomContainer, query).ToReadOnlyList(); } catch (CDKException e) { Console.Error.WriteLine(e.StackTrace); } if (subgraphMaps == null) { continue; } if (!subgraphMaps.Any()) { continue; } // get the atom paths in the unique set of bond maps uniqueSubgraphs.AddRange(GetUniqueBondSubgraphs(subgraphMaps, atomContainer)); } // lets run a check on the length of each returned fragment and delete // any that don't match the length of out query fragments. Note that since // sometimes a fragment might be a ring, it will have number of atoms // equal to the number of bonds, where as a fragment with no rings // will have number of atoms equal to the number of bonds+1. So we need to check // fragment size against all unique query sizes - I get lazy and don't check // unique query sizes, but the size of each query var ret = new List <List <int> >(uniqueSubgraphs.Count); foreach (var fragment in uniqueSubgraphs) { foreach (var query in queries) { if (fragment.Count == query.Atoms.Count) { ret.Add(fragment); break; } } } return(ret); }
void Main() { UniversalIsomorphismTester universalIsomorphismTester = null; #region 1 SmilesParser sp = new SmilesParser(); IAtomContainer atomContainer = sp.ParseSmiles("CC(=O)OC(=O)C"); QueryAtomContainer query = SMARTSParser.Parse("C*C"); bool queryMatch = universalIsomorphismTester.IsSubgraph(atomContainer, query); #endregion #region 2 SMARTSParser parser = new SMARTSParser(new StringReader("C*C")); ASTStart start = parser.Start(); #endregion }
/// <summary> /// Determine the number of amino acids groups the supplied <see cref="IAtomContainer"/>. /// </summary> /// <returns>the number of aromatic atoms of this AtomContainer</returns> public Result Calculate(IAtomContainer container) { container = (IAtomContainer)container.Clone(); var results = new List <int>(substructureSet.Count); var universalIsomorphismTester = new UniversalIsomorphismTester(); foreach (var substructure in substructureSet) { var maps = universalIsomorphismTester.GetSubgraphMaps(container, substructure); results.Add(maps.Count()); } return(new Result(results)); }
/// <summary> /// Perform a full structure search /// </summary> /// <param name="query"></param> /// <param name="target"></param> /// <param name="switches"></param> /// <returns></returns> public bool FullStructureMatch( ICdkMol query, ICdkMol target, string FullStructureSearchType = null) { CdkMol q = query as CdkMol; CdkMol t = target as CdkMol; var fs = new UniversalIsomorphismTester(); if (fs.isIsomorph(q.NativeMol, t.NativeMol)) { return(true); } else { return(false); } }
/// <summary> /// Perform a full structure search /// </summary> /// <param name="query"></param> /// <param name="target"></param> /// <param name="switches"></param> /// <returns></returns> public bool FullStructureMatch( INativeMolMx query, INativeMolMx target, string FullStructureSearchType = null) { if (query == null || target == null) { return(false); } CdkMol q = query as CdkMol; q.UpdateNativeMolecule(); // be sure up to date if (q?.NativeMol == null) { return(false); } CdkMol t = target as CdkMol; t.UpdateNativeMolecule(); if (t?.NativeMol == null) { return(false); } var fs = new UniversalIsomorphismTester(); if (fs.IsIsomorph(q.NativeMol, t.NativeMol)) { return(true); } else { return(false); } }
public void TestSearchNoConditions2944080() { var smilesParser = CDK.SmilesParser; var mol1 = smilesParser.ParseSmiles("CCC(CC)(C(=O)NC(=O)NC(C)=O)Br"); var mol2 = smilesParser.ParseSmiles("CCCC(=O)NC(N)=O"); //Test for atom mapping between the mols var maplist = uiTester.Search(mol1, mol2, new BitArray(mol1.Atoms.Count), UniversalIsomorphismTester.GetBitSet(mol2), false, false); Assert.IsNotNull(maplist); Assert.AreEqual(1, maplist.Count()); }
/// <summary> /// The method takes an XML files like the following: /// <pre> /// <replace-set> /// <replace>O=N=O</replace> /// <replacement>[O-][N+]=O</replacement> /// </replace-set> /// </pre> /// </summary> /// <remarks> /// All parts in ac which are the same as replace will be changed according to replacement. /// Currently the following changes are done: BondOrder, FormalCharge. /// For detection of fragments like replace, we rely on <see cref="UniversalIsomorphismTester"/>. /// doc may contain several replace-sets and a replace-set may contain several replace fragments, which will all be normalized according to replacement. /// </remarks> /// <param name="ac">The atomcontainer to normalize.</param> /// <param name="doc">The configuration file.</param> /// <returns>Did a replacement take place?</returns> /// <exception cref="InvalidSmilesException"> doc contains an invalid smiles.</exception> public static bool Normalize(IAtomContainer ac, XDocument doc) { var nl = doc.Elements("replace-set"); var sp = new SmilesParser(); bool change = false; foreach (var child in nl) { var replaces = child.Elements("replace"); var replacement = child.Elements("replacement"); string replacementstring; { var en = replacement.GetEnumerator(); en.MoveNext(); replacementstring = en.Current.Value; if (replacementstring.IndexOf('\n') > -1 || replacementstring.Length < 1) { en.MoveNext(); replacementstring = en.Current.Value; } } var replacementStructure = sp.ParseSmiles(replacementstring); foreach (var replace in replaces) { string replacestring; { var en = replace.Nodes().GetEnumerator(); en.MoveNext(); replacestring = ((XText)en.Current).Value; if (replacestring.IndexOf('\n') > -1 || replacestring.Length < 1) { en.MoveNext(); replacestring = ((XText)en.Current).Value; } } var replaceStructure = sp.ParseSmiles(replacestring); IReadOnlyList <RMap> l = null; var universalIsomorphismTester = new UniversalIsomorphismTester(); while ((l = universalIsomorphismTester.GetSubgraphMap(ac, replaceStructure)) != null) { var l2 = UniversalIsomorphismTester.MakeAtomsMapOfBondsMap(l, ac, replaceStructure); foreach (var rmap in l) { var acbond = ac.Bonds[rmap.Id1]; var replacebond = replacementStructure.Bonds[rmap.Id2]; acbond.Order = replacebond.Order; change = true; } foreach (var rmap in l2) { var acatom = ac.Atoms[rmap.Id1]; var replaceatom = replacementStructure.Atoms[rmap.Id2]; acatom.FormalCharge = replaceatom.FormalCharge; change = true; } } } } return(change); }