/// <summary> /// Calculate the count of atoms of the largest chain in the supplied <see cref="IAtomContainer"/>. /// </summary> /// <returns>the number of atoms in the largest chain.</returns> public Result Calculate(IAtomContainer container) { if (checkRingSystem) { Cycles.MarkRingAtomsAndBonds(container); } // make a subset molecule only including acyclic non-hydrogen atoms var included = new HashSet <IAtom>(container.Atoms.Where(atom => !atom.IsInRing && atom.AtomicNumber != 1)); var subset = SubsetMol(container, included); var apsp = new AllPairsShortestPaths(subset); int max = 0; var numAtoms = subset.Atoms.Count; for (int i = 0; i < numAtoms; i++) { for (int j = i + 1; j < numAtoms; j++) { int len = apsp.From(i).GetPathTo(j).Length; if (len > max) { max = len; } } } return(new Result(max)); }
/// <summary> /// Traverse all-pairs of shortest-paths within a chemical graph. /// </summary> private List <string> Traverse() { var paths = new SortedSet <string>(); // All-Pairs Shortest-Paths (APSP) var apsp = new AllPairsShortestPaths(container); for (int i = 0, n = container.Atoms.Count; i < n; i++) { paths.Add(ToAtomPattern(container.Atoms[i])); // only do the comparison for i,j then reverse the path for j,i for (int j = i + 1; j < n; j++) { int nPaths = apsp.From(i).GetNPathsTo(j); // only encode when there is a manageable number of paths if (nPaths > 0 && nPaths < MAX_SHORTEST_PATHS) { foreach (var path in apsp.From(i).GetPathsTo(j)) { paths.Add(Encode(path)); paths.Add(Encode(Reverse(path))); } } } } return(paths.ToList()); }
/// <summary> /// This performs the calculations used to generate the fingerprint /// </summary> private static void Calculate(IList <string> paths, IAtomContainer mol) { var apsp = new AllPairsShortestPaths(mol); int numAtoms = mol.Atoms.Count; for (int i = 0; i < numAtoms; i++) { if (!Include(mol.Atoms[i])) { continue; } for (int j = i + 1; j < numAtoms; j++) { if (!Include(mol.Atoms[j])) { continue; } int dist = apsp.From(i).GetDistanceTo(j); if (dist > MAX_DISTANCE) { continue; } var beg = mol.Atoms[i]; var end = mol.Atoms[j]; paths.Add(EncodePath(dist, beg, end)); paths.Add(EncodePath(dist, end, beg)); if (IsHalogen(mol.Atoms[i]) || IsHalogen(mol.Atoms[j])) { paths.Add(EncodeHalPath(dist, beg, end)); paths.Add(EncodeHalPath(dist, end, beg)); } } } }
private void CalculateShortestPath(List <INode> sources, List <INode> targets, IGraph graph) { if (sources != null && targets != null) { // run algorithm var result = new AllPairsShortestPaths { Directed = Directed, Costs = { Delegate = GetEdgeWeight }, Sources = { Source = sources }, Sinks = { Source = targets } }.Run(graph); // mark the resulting paths MarkPaths(result.Paths, sources, targets); } }
/// <summary> /// Create a new layout refiner for the provided molecule. /// </summary> /// <param name="mol">molecule to refine</param> internal LayoutRefiner(IAtomContainer mol, ISet <IAtom> afix, ISet <IBond> bfix) { this.mol = mol; this.afix = afix; this.bfix = bfix; this.bondMap = EdgeToBondMap.WithSpaceFor(mol); this.adjList = GraphUtil.ToAdjList(mol, bondMap); this.idxs = new Dictionary <IAtom, int>(); foreach (var atom in mol.Atoms) { idxs[atom] = idxs.Count; } this.atoms = mol.Atoms.ToArray(); // buffers for storing coordinates this.buffer1 = new Vector2[atoms.Length]; this.buffer2 = new Vector2[atoms.Length]; this.backup = new Vector2[atoms.Length]; for (int i = 0; i < buffer1.Length; i++) { buffer1[i] = new Vector2(); buffer2[i] = new Vector2(); backup[i] = new Vector2(); } this.stackBackup = new IntStack(atoms.Length); this.visited = new bool[atoms.Length]; this.congestion = new Congestion(mol, adjList); // note, this is lazy so only does the shortest path when needed // and does |V| search at maximum this.apsp = new AllPairsShortestPaths(mol); // index ring systems, idx -> ring system number (rnum) int rnum = 1; this.ringsystems = new int[atoms.Length]; for (int i = 0; i < atoms.Length; i++) { if (atoms[i].IsInRing && ringsystems[i] == 0) { TraverseRing(ringsystems, i, rnum++); } } }