/// <summary> Builds the nodes of the RGraph ( resolution graph ), from /// two atom containers (description of the two molecules to compare) /// /// </summary> /// <param name="gr"> the target RGraph /// </param> /// <param name="ac1"> description of the first molecule /// </param> /// <param name="ac2"> description of the second molecule /// </param> private static void nodeConstructor(RGraph gr, IAtomContainer ac1, IAtomContainer ac2) { // resets the target graph. gr.clear(); IBond[] bondsA1 = ac1.Bonds; IBond[] bondsA2 = ac2.Bonds; // compares each bond of G1 to each bond of G2 for (int i = 0; i < bondsA1.Length; i++) { for (int j = 0; j < bondsA2.Length; j++) { if (timeout > -1 && ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 - start) > timeout) throw new CDKException("Timeout exceeded in getOverlaps"); IBond bondA2 = bondsA2[j]; if (bondA2 is IQueryBond) { IQueryBond queryBond = (IQueryBond)bondA2; IQueryAtom atom1 = (IQueryAtom)(bondA2.getAtomAt(0)); IQueryAtom atom2 = (IQueryAtom)(bondA2.getAtomAt(1)); IBond bond = bondsA1[i]; if (queryBond.matches(bond)) { // ok, bonds match if (atom1.matches(bond.getAtomAt(0)) && atom2.matches(bond.getAtomAt(1)) || atom1.matches(bond.getAtomAt(1)) && atom2.matches(bond.getAtomAt(0))) { // ok, atoms match in either order gr.addNode(new RNode(i, j)); } } } else { // if both bonds are compatible then create an association node // in the resolution graph if (((bondsA1[i].Order == bondsA2[j].Order && bondsA1[i].getFlag(CDKConstants.ISAROMATIC) == bondsA2[j].getFlag(CDKConstants.ISAROMATIC)) || (bondsA1[i].getFlag(CDKConstants.ISAROMATIC) && bondsA2[j].getFlag(CDKConstants.ISAROMATIC))) && ((bondsA1[i].getAtomAt(0).Symbol.Equals(bondsA2[j].getAtomAt(0).Symbol) && bondsA1[i].getAtomAt(1).Symbol.Equals(bondsA2[j].getAtomAt(1).Symbol)) || (bondsA1[i].getAtomAt(0).Symbol.Equals(bondsA2[j].getAtomAt(1).Symbol) && bondsA1[i].getAtomAt(1).Symbol.Equals(bondsA2[j].getAtomAt(0).Symbol)))) { gr.addNode(new RNode(i, j)); } } } } }
/// <summary> Build edges of the RGraphs /// This method create the edge of the RGraph and /// calculates the incompatibility and neighbourhood /// relationships between RGraph nodes. /// /// </summary> /// <param name="gr"> the rGraph /// </param> /// <param name="ac1"> Description of the first molecule /// </param> /// <param name="ac2"> Description of the second molecule /// </param> private static void arcConstructor(RGraph gr, IAtomContainer ac1, IAtomContainer ac2) { // each node is incompatible with himself for (int i = 0; i < gr.Graph.Count; i++) { RNode x = (RNode)gr.Graph[i]; SupportClass.BitArraySupport.Set(x.Forbidden, i); } IBond a1; IBond a2; IBond b1; IBond b2; IBond[] bondsA1 = ac1.Bonds; IBond[] bondsA2 = ac2.Bonds; gr.FirstGraphSize = ac1.getBondCount(); gr.SecondGraphSize = ac2.getBondCount(); for (int i = 0; i < gr.Graph.Count; i++) { RNode x = (RNode)gr.Graph[i]; // two nodes are neighbours if their adjacency // relationship in are equivalent in G1 and G2 // else they are incompatible. for (int j = i + 1; j < gr.Graph.Count; j++) { if (timeout > -1 && ((System.DateTime.Now.Ticks - 621355968000000000) / 10000 - start) > timeout) throw new CDKException("Timeout exceeded in getOverlaps"); RNode y = (RNode)gr.Graph[j]; a1 = bondsA1[((RNode)gr.Graph[i]).RMap.Id1]; a2 = bondsA2[((RNode)gr.Graph[i]).RMap.Id2]; b1 = bondsA1[((RNode)gr.Graph[j]).RMap.Id1]; b2 = bondsA2[((RNode)gr.Graph[j]).RMap.Id2]; if (a2 is IQueryBond) { if (a1.Equals(b1) || a2.Equals(b2) || !queryAdjacency(a1, b1, a2, b2)) { SupportClass.BitArraySupport.Set(x.Forbidden, j); SupportClass.BitArraySupport.Set(y.Forbidden, i); } else if (hasCommonAtom(a1, b1)) { SupportClass.BitArraySupport.Set(x.Extension, j); SupportClass.BitArraySupport.Set(y.Extension, i); } } else { if (a1.Equals(b1) || a2.Equals(b2) || (!getCommonSymbol(a1, b1).Equals(getCommonSymbol(a2, b2)))) { SupportClass.BitArraySupport.Set(x.Forbidden, j); SupportClass.BitArraySupport.Set(y.Forbidden, i); } else if (hasCommonAtom(a1, b1)) { SupportClass.BitArraySupport.Set(x.Extension, j); SupportClass.BitArraySupport.Set(y.Extension, i); } } } } }
////////////////////////////////////////////////// // Internal methods /// <summary> Builds the RGraph ( resolution graph ), from two atomContainer /// (description of the two molecules to compare) /// This is the interface point between the CDK model and /// the generic MCSS algorithm based on the RGRaph. /// /// </summary> /// <param name="g1"> Description of the first molecule /// </param> /// <param name="g2"> Description of the second molecule /// </param> /// <returns> the rGraph /// </returns> public static RGraph buildRGraph(IAtomContainer g1, IAtomContainer g2) { RGraph rGraph = new RGraph(); nodeConstructor(rGraph, g1, g2); arcConstructor(rGraph, g1, g2); return rGraph; }