/// <summary> /// Find the bonds of a <paramref name="molecule"/> which this model determined were aromatic. /// </summary> /// <example> /// <include file='IncludeExamples.xml' path='Comments/Codes[@id="NCDK.Aromaticities.Aromaticity_Example.cs+FindBonds"]/*' /> /// </example> /// <param name="molecule">the molecule to apply the model to</param> /// <returns>the set of bonds which are aromatic</returns> /// <exception cref="CDKException">a problem occurred with the cycle perception - one can retry with a simpler cycle set</exception> public IEnumerable <IBond> FindBonds(IAtomContainer molecule) { // build graph data-structures for fast cycle perception var bondMap = EdgeToBondMap.WithSpaceFor(molecule); var graph = GraphUtil.ToAdjList(molecule, bondMap); // initial ring/cycle search and get the contribution from each atom RingSearch ringSearch = new RingSearch(molecule, graph); var electrons = model.Contribution(molecule, ringSearch); // obtain the subset of electron contributions which are >= 0 (i.e. // allowed to be aromatic) - we then find the cycles in this subgraph // and 'lift' the indices back to the original graph using the subset // as a lookup var subset = Subset(electrons); var subgraph = GraphUtil.Subgraph(graph, subset); // for each cycle if the electron sum is valid add the bonds of the // cycle to the set or aromatic bonds foreach (var cycle in cycles.Find(molecule, subgraph, subgraph.Length).GetPaths()) { if (CheckElectronSum(cycle, electrons, subset)) { for (int i = 1; i < cycle.Length; i++) { yield return(bondMap[subset[cycle[i]], subset[cycle[i - 1]]]); } } } yield break; }
/// <summary>Check the electron contribution is the same as expected.</summary> static void Test(IAtomContainer m, params int[] expected) { AtomContainerManipulator.PercieveAtomTypesAndConfigureAtoms(m); Assert.IsTrue(Compares.AreDeepEqual(expected, model.Contribution(m, new RingSearch(m)))); }