From 1a62a16a17fbd81b1f3f3b4c3ee80aa03149da09 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Wed, 11 Mar 2026 15:05:04 +0000 Subject: [PATCH 01/14] Add new RDF method with flexible bond exclusions, add snap to networkx method --- cmeutils/gsd_utils.py | 11 +++ cmeutils/rdf.py | 196 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 207 insertions(+) create mode 100644 cmeutils/rdf.py diff --git a/cmeutils/gsd_utils.py b/cmeutils/gsd_utils.py index 7bb8bc0..5c55865 100644 --- a/cmeutils/gsd_utils.py +++ b/cmeutils/gsd_utils.py @@ -8,6 +8,17 @@ from boltons.setutils import IndexedSet +def snapshot_to_graph(snap): + graph = nx.Graph() + positions = snap.particles.position + type_ids = snap.particles.typeid + types = snap.particles.types + for i in range(snap.particles.N): + graph.add_node(i, type=types[type_ids[i]], pos=positions[i]) + graph.add_edges_from(snap.bonds.group) + return graph + + def frame_to_freud_system(frame, ref_length=None): """Creates a freud system given a gsd.hoomd.Frame. diff --git a/cmeutils/rdf.py b/cmeutils/rdf.py new file mode 100644 index 0000000..9562a92 --- /dev/null +++ b/cmeutils/rdf.py @@ -0,0 +1,196 @@ +import freud +import gsd +import gsd.hoomd +import networkx as nx +import numpy as np + +from cmeutils.gsd_utils import frame_to_freud_system, snapshot_to_graph + + +def get_rdf( + gsdfile, + A_name=None, + B_name=None, + start=0, + stop=-1, + stride=1, + r_max=None, + r_min=0, + bins=100, + exclude_bond_depth=None, + exclude_all_bonded=False, + update_bond_graph=False, +): + """Uses freud's RDF module to calculate an RDF averaged over a GSD file. + + + Parameters + ---------- + gsdfile : str + Filename of the GSD trajectory. + A_name, B_name : str + Name(s) of particles between which to calculate the RDF (found in + gsd.hoomd.Frame.particles.types) + start : int + Starting frame index for accumulating the RDF. Negative numbers index + from the end. (default 0) + stop : int + Final frame index for accumulating the RDF. If None, the last frame + will be used. (default -1) + stride : int, default = 1 + The stride size when iterating through start:stop + r_max : float + Maximum radius of RDF. If None, half of the minimum box size is used. + r_min : float + Minimum radius of RDF. (default 0) + bins : int + Number of bins to use when calculating the RDF. (default 100) + """ + if any([A_name, B_name]) and not all([A_name, B_name]): + raise ValueError( + "If A_name or B_name is given, the other must be defined as well." + "To calculate an RDF between the same bead type, set A_name and B_name equal to the same value." + "To calculate an RDF between all possible pairs, leave both as ``None``." + ) + + with gsd.hoomd.open(gsdfile, mode="r") as trajectory: + # Grab the first snapshot for some book-keeping. + snap = trajectory[start] + + # Use a value just less than half the minimum box length. + # TODO: Iterate through all boxes, use the smallest one? Edge cases might arise with NPT sims + if r_max is None: + r_max = np.nextafter( + np.min(snap.configuration.box[:3]) * 0.49, 0, dtype=np.float32 + ) + + rdf = freud.density.RDF(bins=bins, r_max=r_max, r_min=r_min) + + # Filter particles by type A and type B + if A_name is not None and B_name is not None: + type_A = snap.particles.typeid == snap.particles.types.index(A_name) + type_B = snap.particles.typeid == snap.particles.types.index(B_name) + # These 2 *_indices variables store global particle indices (Before filtering by type) + # If excluding by bond depth, these need to be passed into filter_nlist + type_A_indices = np.where(type_A)[0] + type_B_indices = np.where(type_B)[0] + exclude_ii = (A_name == B_name) + else: # Use all particles for this RDF + type_A = type_B = np.ones(snap.particles.N, dtype=bool) # Array of True at all indices + type_A_indices = type_B_indices = np.arange(snap.particles.N) + exclude_ii = True + + # Build up pair exclusions if exclude_bond_depth or exclude_all_bonded + # Reuse these for each frame's RDF unless update_bond_graph = True + # If the bonding topology isn't changing, we only need to get bond graph and excluded pairs once + if exclude_bond_depth: + max_idx = snap.particles.N + bond_graph = snapshot_to_graph(snap) + # This gives a seuqunce of tuples [(1, 4), (5, 8)...(i, j)] + excluded_pairs = get_excluded_pairs(bond_graph, exclude_bond_depth) + # Map information of sequence of tuples to an array of unique ints. + # This is used for faster filtering in filter_nlist() (vectorized instead of for loop) + excluded_pairs_encoded = np.array([i * max_idx + j for i, j in excluded_pairs]) + + for snap in trajectory[start:stop:stride]: + A_xyz = snap.particles.position[type_A_indices] + B_xyz = snap.particles.position[type_B_indices] + + # Build up the complete neighborlist + box = snap.configuration.box + system = (box, A_xyz) + aq = freud.locality.AABBQuery.from_system(system) + query_args = {"r_max": r_max, "exclude_ii": exclude_ii} + nlist = aq.query(B_xyz, query_args).toNeighborList() + + # Create new bond graph and excluded pairs for each frame. + # Only needed if bond topology is changing, set by ``update_bond_graph`` + if update_bond_graph: + bond_graph = snapshot_to_graph(snap) + excluded_pairs = get_excluded_pairs(bond_graph, exclude_bond_depth) + excluded_pairs_encoded = np.array([i * max_idx + j for i, j in excluded_pairs]) + + # Filter excluded pairs from all pairs in nlist + if exclude_bond_depth: + nlist = filter_nlist( + nlist=nlist, + excluded_pairs_encoded=excluded_pairs_encoded, + query_indices=type_A_indices, + point_indices=type_B_indices, + max_idx=snap.particles.N + ) + + rdf.compute(aq, neighbors=nlist, reset=False) + return rdf + + +def get_excluded_pairs(bond_graph, excluded_bond_depth): + """Returns a set of (i, j) pairs to exclude based on step distance of a bond graph.""" + #TODO: Vecotrize this instead of doing 2 for loops? Maybe just don't worry about it until there is a reason to + # Not a big deal if bonds aren't changing as its only done once. + excluded_pairs = set() + for i in bond_graph.nodes: + lengths = nx.single_source_shortest_path_length(bond_graph, i, cutoff=excluded_bond_depth) + for j, dist in lengths.items(): + # use j > 1 for 2 reasons: skip adding the same pair twice and its used in filter_nlist + if j > i and dist <= excluded_bond_depth: + excluded_pairs.add((i, j)) + return excluded_pairs + + +def filter_nlist(nlist, excluded_pairs_encoded, query_indices, point_indices, max_idx): + """Filter a freud NeighborList by removing excluded pairs. + + Handles the index space mismatch between the NeighborList (which uses + local indices into type filtered position arrays) and excluded_pairs + (which uses global particle indices from the bond graph). + + Parameters + ---------- + nlist : freud.locality.NeighborList + Neighbor list to filter, as returned by AABBQuery.toNeighborList(). + Query point and point indices are local (0 indexed within their + type subsets). + excluded_pairs_encoded : np.ndarray of int, shape (N_excluded,) + Encoded global particle index pairs to exclude, precomputed as + ``i * max_idx + j`` where ``i < j`` and ``max_idx = N_particles``. + Encodes the output of get_excluded_pairs(). + query_indices : np.ndarray of int, shape (N_query,) + Global particle indices of the query points (type A particles). + Maps local query index to global particle index. + point_indices : np.ndarray of int, shape (N_points,) + Global particle indices of the reference points (type B particles). + Maps local point index to global particle index. + + Returns + ------- + freud.locality.NeighborList + Filtered neighbor list with excluded pairs removed. Local indices + are preserved, so it can be passed directly to freud.density.RDF.compute(). + """ + # Local indices of the neighborlist, since it was created after filtering particle type + i_local = nlist.query_point_indices + j_local = nlist.point_indices + + # excluded_pair indices are global, they came from the the bond graph of all particles + # Convert i_local and j_local to global indices so we can look up against excluded_pairs + i_global = query_indices[i_local] + j_global = point_indices[j_local] + + # Sort all pairs so that the first index is always < the second. + lo = np.minimum(i_global, j_global) + hi = np.maximum(i_global, j_global) + + # Encode each pair as a single integer for vectorized lookup. + # (lo, hi) = lo * max_idx + hi which is unique as long as hi < max_idx + neighbor_pairs_encoded = lo * max_idx + hi + + # vectorized set lookup + keep = ~np.isin(neighbor_pairs_encoded, excluded_pairs_encoded) + return freud.locality.NeighborList.from_arrays( + num_query_points=nlist.num_query_points, + num_points=nlist.num_points, + query_point_indices=i_local[keep], + point_indices=j_local[keep], + vectors=nlist.vectors[keep], + ) From 73f7561af5b5a16aef7f2fd560a95e89e87a28a7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:21:57 +0000 Subject: [PATCH 02/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cmeutils/rdf.py | 46 +++++++++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/cmeutils/rdf.py b/cmeutils/rdf.py index 9562a92..2f00372 100644 --- a/cmeutils/rdf.py +++ b/cmeutils/rdf.py @@ -4,7 +4,7 @@ import networkx as nx import numpy as np -from cmeutils.gsd_utils import frame_to_freud_system, snapshot_to_graph +from cmeutils.gsd_utils import snapshot_to_graph def get_rdf( @@ -54,7 +54,7 @@ def get_rdf( ) with gsd.hoomd.open(gsdfile, mode="r") as trajectory: - # Grab the first snapshot for some book-keeping. + # Grab the first snapshot for some book-keeping. snap = trajectory[start] # Use a value just less than half the minimum box length. @@ -74,10 +74,12 @@ def get_rdf( # If excluding by bond depth, these need to be passed into filter_nlist type_A_indices = np.where(type_A)[0] type_B_indices = np.where(type_B)[0] - exclude_ii = (A_name == B_name) - else: # Use all particles for this RDF - type_A = type_B = np.ones(snap.particles.N, dtype=bool) # Array of True at all indices - type_A_indices = type_B_indices = np.arange(snap.particles.N) + exclude_ii = A_name == B_name + else: # Use all particles for this RDF + type_A = type_B = np.ones( + snap.particles.N, dtype=bool + ) # Array of True at all indices + type_A_indices = type_B_indices = np.arange(snap.particles.N) exclude_ii = True # Build up pair exclusions if exclude_bond_depth or exclude_all_bonded @@ -90,12 +92,14 @@ def get_rdf( excluded_pairs = get_excluded_pairs(bond_graph, exclude_bond_depth) # Map information of sequence of tuples to an array of unique ints. # This is used for faster filtering in filter_nlist() (vectorized instead of for loop) - excluded_pairs_encoded = np.array([i * max_idx + j for i, j in excluded_pairs]) + excluded_pairs_encoded = np.array( + [i * max_idx + j for i, j in excluded_pairs] + ) for snap in trajectory[start:stop:stride]: A_xyz = snap.particles.position[type_A_indices] B_xyz = snap.particles.position[type_B_indices] - + # Build up the complete neighborlist box = snap.configuration.box system = (box, A_xyz) @@ -107,9 +111,13 @@ def get_rdf( # Only needed if bond topology is changing, set by ``update_bond_graph`` if update_bond_graph: bond_graph = snapshot_to_graph(snap) - excluded_pairs = get_excluded_pairs(bond_graph, exclude_bond_depth) - excluded_pairs_encoded = np.array([i * max_idx + j for i, j in excluded_pairs]) - + excluded_pairs = get_excluded_pairs( + bond_graph, exclude_bond_depth + ) + excluded_pairs_encoded = np.array( + [i * max_idx + j for i, j in excluded_pairs] + ) + # Filter excluded pairs from all pairs in nlist if exclude_bond_depth: nlist = filter_nlist( @@ -117,7 +125,7 @@ def get_rdf( excluded_pairs_encoded=excluded_pairs_encoded, query_indices=type_A_indices, point_indices=type_B_indices, - max_idx=snap.particles.N + max_idx=snap.particles.N, ) rdf.compute(aq, neighbors=nlist, reset=False) @@ -126,19 +134,23 @@ def get_rdf( def get_excluded_pairs(bond_graph, excluded_bond_depth): """Returns a set of (i, j) pairs to exclude based on step distance of a bond graph.""" - #TODO: Vecotrize this instead of doing 2 for loops? Maybe just don't worry about it until there is a reason to + # TODO: Vecotrize this instead of doing 2 for loops? Maybe just don't worry about it until there is a reason to # Not a big deal if bonds aren't changing as its only done once. excluded_pairs = set() for i in bond_graph.nodes: - lengths = nx.single_source_shortest_path_length(bond_graph, i, cutoff=excluded_bond_depth) + lengths = nx.single_source_shortest_path_length( + bond_graph, i, cutoff=excluded_bond_depth + ) for j, dist in lengths.items(): - # use j > 1 for 2 reasons: skip adding the same pair twice and its used in filter_nlist + # use j > 1 for 2 reasons: skip adding the same pair twice and its used in filter_nlist if j > i and dist <= excluded_bond_depth: excluded_pairs.add((i, j)) return excluded_pairs -def filter_nlist(nlist, excluded_pairs_encoded, query_indices, point_indices, max_idx): +def filter_nlist( + nlist, excluded_pairs_encoded, query_indices, point_indices, max_idx +): """Filter a freud NeighborList by removing excluded pairs. Handles the index space mismatch between the NeighborList (which uses @@ -171,7 +183,7 @@ def filter_nlist(nlist, excluded_pairs_encoded, query_indices, point_indices, ma # Local indices of the neighborlist, since it was created after filtering particle type i_local = nlist.query_point_indices j_local = nlist.point_indices - + # excluded_pair indices are global, they came from the the bond graph of all particles # Convert i_local and j_local to global indices so we can look up against excluded_pairs i_global = query_indices[i_local] From 93540c9ccbc8cadd88e3fefeb1bb968de692ea07 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Wed, 11 Mar 2026 15:24:28 +0000 Subject: [PATCH 03/14] Add doc strings to method --- cmeutils/gsd_utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmeutils/gsd_utils.py b/cmeutils/gsd_utils.py index 5c55865..67deeba 100644 --- a/cmeutils/gsd_utils.py +++ b/cmeutils/gsd_utils.py @@ -9,6 +9,13 @@ def snapshot_to_graph(snap): + """Convert a HOOMD snapshot into a networkx bond graph. + + Parameters + ---------- + snap : gsd.hoomd.Frame, required + Snapshot (frame) containing particle positions and bond groups. + """ graph = nx.Graph() positions = snap.particles.position type_ids = snap.particles.typeid From f414fe0e23976e47fcfb7643aacd6ff6ffd655f2 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Wed, 11 Mar 2026 16:19:24 +0000 Subject: [PATCH 04/14] Add scaling factor to adj normalization for excluded pairs --- cmeutils/__init__.py | 2 +- cmeutils/rdf.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/cmeutils/__init__.py b/cmeutils/__init__.py index 0d2eabd..fc1ba24 100644 --- a/cmeutils/__init__.py +++ b/cmeutils/__init__.py @@ -1,4 +1,4 @@ from . import gsd_utils, structure from .__version__ import __version__ -__all__ = ["__version__", "gsd_utils", "structure", "dynamics", "visualize"] +__all__ = ["__version__", "gsd_utils", "structure", "dynamics", "rdf", "visualize"] diff --git a/cmeutils/rdf.py b/cmeutils/rdf.py index 2f00372..0357b75 100644 --- a/cmeutils/rdf.py +++ b/cmeutils/rdf.py @@ -85,6 +85,7 @@ def get_rdf( # Build up pair exclusions if exclude_bond_depth or exclude_all_bonded # Reuse these for each frame's RDF unless update_bond_graph = True # If the bonding topology isn't changing, we only need to get bond graph and excluded pairs once + rdf_correction = 1 if exclude_bond_depth: max_idx = snap.particles.N bond_graph = snapshot_to_graph(snap) @@ -96,6 +97,14 @@ def get_rdf( [i * max_idx + j for i, j in excluded_pairs] ) + n_excluded = len(excluded_pairs) + if A_name == B_name or not any([A_name, B_name]): # Using same type or all particles + n_total_pairs = len(type_A_indices) * (len(type_A_indices) - 1) / 2 + else: # RDF is not between same types, or using all particles + n_total_pairs = len(type_A_indices) * len(type_B_indices) + # Overwrite default value only if using exclude_bond_depth + rdf_correction = n_total_pairs / (n_total_pairs - n_excluded) + for snap in trajectory[start:stop:stride]: A_xyz = snap.particles.position[type_A_indices] B_xyz = snap.particles.position[type_B_indices] @@ -106,6 +115,7 @@ def get_rdf( aq = freud.locality.AABBQuery.from_system(system) query_args = {"r_max": r_max, "exclude_ii": exclude_ii} nlist = aq.query(B_xyz, query_args).toNeighborList() + # # Create new bond graph and excluded pairs for each frame. # Only needed if bond topology is changing, set by ``update_bond_graph`` @@ -117,6 +127,7 @@ def get_rdf( excluded_pairs_encoded = np.array( [i * max_idx + j for i, j in excluded_pairs] ) + n_excluded = len(excluded_pairs) # Filter excluded pairs from all pairs in nlist if exclude_bond_depth: @@ -129,7 +140,7 @@ def get_rdf( ) rdf.compute(aq, neighbors=nlist, reset=False) - return rdf + return rdf, rdf_correction def get_excluded_pairs(bond_graph, excluded_bond_depth): From f7f2bdb60070cdb40a8a7d0128dc521286b32913 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 16:19:38 +0000 Subject: [PATCH 05/14] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- cmeutils/__init__.py | 9 ++++++++- cmeutils/rdf.py | 12 ++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/cmeutils/__init__.py b/cmeutils/__init__.py index fc1ba24..8562ddb 100644 --- a/cmeutils/__init__.py +++ b/cmeutils/__init__.py @@ -1,4 +1,11 @@ from . import gsd_utils, structure from .__version__ import __version__ -__all__ = ["__version__", "gsd_utils", "structure", "dynamics", "rdf", "visualize"] +__all__ = [ + "__version__", + "gsd_utils", + "structure", + "dynamics", + "rdf", + "visualize", +] diff --git a/cmeutils/rdf.py b/cmeutils/rdf.py index 0357b75..55cc880 100644 --- a/cmeutils/rdf.py +++ b/cmeutils/rdf.py @@ -98,9 +98,13 @@ def get_rdf( ) n_excluded = len(excluded_pairs) - if A_name == B_name or not any([A_name, B_name]): # Using same type or all particles - n_total_pairs = len(type_A_indices) * (len(type_A_indices) - 1) / 2 - else: # RDF is not between same types, or using all particles + if A_name == B_name or not any( + [A_name, B_name] + ): # Using same type or all particles + n_total_pairs = ( + len(type_A_indices) * (len(type_A_indices) - 1) / 2 + ) + else: # RDF is not between same types, or using all particles n_total_pairs = len(type_A_indices) * len(type_B_indices) # Overwrite default value only if using exclude_bond_depth rdf_correction = n_total_pairs / (n_total_pairs - n_excluded) @@ -115,7 +119,7 @@ def get_rdf( aq = freud.locality.AABBQuery.from_system(system) query_args = {"r_max": r_max, "exclude_ii": exclude_ii} nlist = aq.query(B_xyz, query_args).toNeighborList() - # + # # Create new bond graph and excluded pairs for each frame. # Only needed if bond topology is changing, set by ``update_bond_graph`` From d5c896d6924f6e777454757745bd1dd8cda445b4 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 09:26:31 +0000 Subject: [PATCH 06/14] Update doc strings --- cmeutils/rdf.py | 61 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/cmeutils/rdf.py b/cmeutils/rdf.py index 55cc880..05215f6 100644 --- a/cmeutils/rdf.py +++ b/cmeutils/rdf.py @@ -1,3 +1,5 @@ +import itertools + import freud import gsd import gsd.hoomd @@ -23,6 +25,17 @@ def get_rdf( ): """Uses freud's RDF module to calculate an RDF averaged over a GSD file. + Notes + ----- + This method lets you set a bond-depth exclusion to prevent neighbors of the + same molecule to be used in the RDF calculations. Bond depth is counted in + terms of steps away on a connected bond graph. + + For example, ``excluded_bond_depth=1`` excludes pairs directly bonded together, + ``excluded_bond_depth=2`` excludes both pairs (i, j) and (i, k) in (i-j-k), and so on. + This can be set to any positive integer value, and isn't limited to particles belonging + to the same bond, angle or dihedral. To exclude all intramolecular pairs use + the ``exclude_all_bonded`` parameter instead. Parameters ---------- @@ -45,6 +58,25 @@ def get_rdf( Minimum radius of RDF. (default 0) bins : int Number of bins to use when calculating the RDF. (default 100) + exclude_bond_depth : int, optional (default None) + Excludes all pairs within a depth (distance on a bond graph) + from the RDF calculation. + exclude_all_bonded : bool, optional (default False) + Excludes all pairs belonging to the same molecule from the + RDF calculation. + update_bond_graph : bool, optional (default False) + Updates the bond graph to find excluded pairs for each + frame used in the RDF calclation. This may significantly + slow the RDF calcualtion. This should always be False + unless the bonds in the trajectory are changing. + + Returns + ------- + tuple(rdf, rdf_correction) : (freud.density.RDF, float) + Calculated RDF. Access r values with ``rdf.bin_centers`` and g(r) with ``rdf.rdf`` + rdf_correction is always 1 unless ``exclude_bond_depth`` or ``exclude_all_bonded`` are used. + This corrects the g(r) normalization to account for excluded pairs. + To include this in the results, g(r) = rdf.rdf * rdf_correction """ if any([A_name, B_name]) and not all([A_name, B_name]): raise ValueError( @@ -53,6 +85,11 @@ def get_rdf( "To calculate an RDF between all possible pairs, leave both as ``None``." ) + if all([exclude_bond_depth, exclude_all_bonded]): + raise ValueError( + "Only use one of excluded_bond_depth and exclude_all_bonded." + ) + with gsd.hoomd.open(gsdfile, mode="r") as trajectory: # Grab the first snapshot for some book-keeping. snap = trajectory[start] @@ -147,18 +184,26 @@ def get_rdf( return rdf, rdf_correction -def get_excluded_pairs(bond_graph, excluded_bond_depth): +def get_excluded_pairs( + bond_graph, excluded_bond_depth=None, exclude_all_bonded=False +): """Returns a set of (i, j) pairs to exclude based on step distance of a bond graph.""" # TODO: Vecotrize this instead of doing 2 for loops? Maybe just don't worry about it until there is a reason to # Not a big deal if bonds aren't changing as its only done once. excluded_pairs = set() - for i in bond_graph.nodes: - lengths = nx.single_source_shortest_path_length( - bond_graph, i, cutoff=excluded_bond_depth - ) - for j, dist in lengths.items(): - # use j > 1 for 2 reasons: skip adding the same pair twice and its used in filter_nlist - if j > i and dist <= excluded_bond_depth: + if excluded_bond_depth: + for i in bond_graph.nodes: + lengths = nx.single_source_shortest_path_length( + bond_graph, i, cutoff=excluded_bond_depth + ) + for j, dist in lengths.items(): + # use j > i for 2 reasons: skip adding the same pair twice and its used in filter_nlist + if j > i and dist <= excluded_bond_depth: + excluded_pairs.add((i, j)) + elif exclude_all_bonded: + for component in nx.connected_components(bond_graph): + component = sorted(component) + for i, j in itertools.combinations(component, 2): excluded_pairs.add((i, j)) return excluded_pairs From 33e59137171dab5b025959cf542f91f8cc665ac2 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 11:22:07 +0000 Subject: [PATCH 07/14] Re-arrange some functions, update tests, add new test assets --- cmeutils/__init__.py | 1 - cmeutils/geometry.py | 44 ++++ cmeutils/gsd_utils.py | 44 ++++ cmeutils/rdf.py | 268 ---------------------- cmeutils/structure.py | 376 ++++++++++++++++--------------- cmeutils/tests/base_test.py | 8 + cmeutils/tests/test_geometry.py | 12 + cmeutils/tests/test_gsd.py | 6 + cmeutils/tests/test_structure.py | 111 +++++---- 9 files changed, 380 insertions(+), 490 deletions(-) delete mode 100644 cmeutils/rdf.py diff --git a/cmeutils/__init__.py b/cmeutils/__init__.py index 8562ddb..6de519e 100644 --- a/cmeutils/__init__.py +++ b/cmeutils/__init__.py @@ -6,6 +6,5 @@ "gsd_utils", "structure", "dynamics", - "rdf", "visualize", ] diff --git a/cmeutils/geometry.py b/cmeutils/geometry.py index c28eec0..7c72362 100644 --- a/cmeutils/geometry.py +++ b/cmeutils/geometry.py @@ -1,5 +1,49 @@ import numpy as np from numpy.linalg import svd +from rowan import vector_vector_rotation + + +def get_quaternions(n_views=20): + """Generate quaternions over the specified number of views. + + The first (n_view - 3) views will be the views even distributed on a sphere, + while the last three views will be the face-on, edge-on, and corner-on + views, respectively. + + These quaternions are useful as input to `view_orientation` kwarg in + `freud.diffraction.Diffractometer.compute`. + + Parameters + ---------- + n_views : int, default 20 + The number of views to compute. + + Returns + ------- + list of numpy.ndarray + Quaternions as (4,) arrays. + """ + if n_views <= 3 or not isinstance(n_views, int): + raise ValueError("Please set n_views to an integer greater than 3.") + # Calculate points for even distribution on a sphere + ga = np.pi * (3 - 5**0.5) + theta = ga * np.arange(n_views - 3) + z = np.linspace(1 - 1 / (n_views - 3), 1 / (n_views - 3), n_views - 3) + radius = np.sqrt(1 - z * z) + points = np.zeros((n_views, 3)) + points[:-3, 0] = radius * np.cos(theta) + points[:-3, 1] = radius * np.sin(theta) + points[:-3, 2] = z + + # face on + points[-3] = np.array([0, 0, 1]) + # edge on + points[-2] = np.array([0, 1, 1]) + # corner on + points[-1] = np.array([1, 1, 1]) + + unit_z = np.array([0, 0, 1]) + return [vector_vector_rotation(i, unit_z) for i in points] def get_backbone_vector(coordinates): diff --git a/cmeutils/gsd_utils.py b/cmeutils/gsd_utils.py index 67deeba..ae88af5 100644 --- a/cmeutils/gsd_utils.py +++ b/cmeutils/gsd_utils.py @@ -353,6 +353,50 @@ def identify_snapshot_connections(snapshot): return snapshot +def get_centers(gsdfile, new_gsdfile): + """Create a gsd file containing the molecule centers from an existing gsd + file. + + + This function calculates the centers of a trajectory given a GSD file + and stores them into a new GSD file just for centers. By default it will + calculate the centers of an entire trajectory. + + Parameters + ---------- + gsdfile : str + Filename of the GSD trajectory. + new_gsdfile : str + Filename of new GSD for centers. + """ + with ( + gsd.hoomd.open(new_gsdfile, "w") as new_traj, + gsd.hoomd.open(gsdfile, "r") as traj, + ): + snap = traj[0] + cluster_idx = get_molecule_cluster(snap=snap) + for snap in traj: + new_snap = gsd.hoomd.Frame() + new_snap.configuration.box = snap.configuration.box + f_box = freud.box.Box.from_box(snap.configuration.box) + # Use the freud box to unwrap the particle positions + unwrapped_positions = f_box.unwrap( + snap.particles.position, snap.particles.image + ) + uw_centers = [] + for i in range(max(cluster_idx) + 1): + cluster_uw_pos = unwrapped_positions[np.where(cluster_idx == i)] + uw_centers.append(np.mean(cluster_uw_pos, axis=0)) + uw_centers = np.stack(uw_centers) + new_snap.particles.position = f_box.wrap(uw_centers) + new_snap.particles.N = len(uw_centers) + new_snap.particles.types = ["A"] + new_snap.particles.image = f_box.get_images(uw_centers) + new_snap.particles.typeid = np.zeros(len(uw_centers)) + new_snap.validate() + new_traj.append(new_snap) + + def _fill_connection_info(snapshot, connections, type_): p_types = snapshot.particles.types p_typeid = snapshot.particles.typeid diff --git a/cmeutils/rdf.py b/cmeutils/rdf.py deleted file mode 100644 index 05215f6..0000000 --- a/cmeutils/rdf.py +++ /dev/null @@ -1,268 +0,0 @@ -import itertools - -import freud -import gsd -import gsd.hoomd -import networkx as nx -import numpy as np - -from cmeutils.gsd_utils import snapshot_to_graph - - -def get_rdf( - gsdfile, - A_name=None, - B_name=None, - start=0, - stop=-1, - stride=1, - r_max=None, - r_min=0, - bins=100, - exclude_bond_depth=None, - exclude_all_bonded=False, - update_bond_graph=False, -): - """Uses freud's RDF module to calculate an RDF averaged over a GSD file. - - Notes - ----- - This method lets you set a bond-depth exclusion to prevent neighbors of the - same molecule to be used in the RDF calculations. Bond depth is counted in - terms of steps away on a connected bond graph. - - For example, ``excluded_bond_depth=1`` excludes pairs directly bonded together, - ``excluded_bond_depth=2`` excludes both pairs (i, j) and (i, k) in (i-j-k), and so on. - This can be set to any positive integer value, and isn't limited to particles belonging - to the same bond, angle or dihedral. To exclude all intramolecular pairs use - the ``exclude_all_bonded`` parameter instead. - - Parameters - ---------- - gsdfile : str - Filename of the GSD trajectory. - A_name, B_name : str - Name(s) of particles between which to calculate the RDF (found in - gsd.hoomd.Frame.particles.types) - start : int - Starting frame index for accumulating the RDF. Negative numbers index - from the end. (default 0) - stop : int - Final frame index for accumulating the RDF. If None, the last frame - will be used. (default -1) - stride : int, default = 1 - The stride size when iterating through start:stop - r_max : float - Maximum radius of RDF. If None, half of the minimum box size is used. - r_min : float - Minimum radius of RDF. (default 0) - bins : int - Number of bins to use when calculating the RDF. (default 100) - exclude_bond_depth : int, optional (default None) - Excludes all pairs within a depth (distance on a bond graph) - from the RDF calculation. - exclude_all_bonded : bool, optional (default False) - Excludes all pairs belonging to the same molecule from the - RDF calculation. - update_bond_graph : bool, optional (default False) - Updates the bond graph to find excluded pairs for each - frame used in the RDF calclation. This may significantly - slow the RDF calcualtion. This should always be False - unless the bonds in the trajectory are changing. - - Returns - ------- - tuple(rdf, rdf_correction) : (freud.density.RDF, float) - Calculated RDF. Access r values with ``rdf.bin_centers`` and g(r) with ``rdf.rdf`` - rdf_correction is always 1 unless ``exclude_bond_depth`` or ``exclude_all_bonded`` are used. - This corrects the g(r) normalization to account for excluded pairs. - To include this in the results, g(r) = rdf.rdf * rdf_correction - """ - if any([A_name, B_name]) and not all([A_name, B_name]): - raise ValueError( - "If A_name or B_name is given, the other must be defined as well." - "To calculate an RDF between the same bead type, set A_name and B_name equal to the same value." - "To calculate an RDF between all possible pairs, leave both as ``None``." - ) - - if all([exclude_bond_depth, exclude_all_bonded]): - raise ValueError( - "Only use one of excluded_bond_depth and exclude_all_bonded." - ) - - with gsd.hoomd.open(gsdfile, mode="r") as trajectory: - # Grab the first snapshot for some book-keeping. - snap = trajectory[start] - - # Use a value just less than half the minimum box length. - # TODO: Iterate through all boxes, use the smallest one? Edge cases might arise with NPT sims - if r_max is None: - r_max = np.nextafter( - np.min(snap.configuration.box[:3]) * 0.49, 0, dtype=np.float32 - ) - - rdf = freud.density.RDF(bins=bins, r_max=r_max, r_min=r_min) - - # Filter particles by type A and type B - if A_name is not None and B_name is not None: - type_A = snap.particles.typeid == snap.particles.types.index(A_name) - type_B = snap.particles.typeid == snap.particles.types.index(B_name) - # These 2 *_indices variables store global particle indices (Before filtering by type) - # If excluding by bond depth, these need to be passed into filter_nlist - type_A_indices = np.where(type_A)[0] - type_B_indices = np.where(type_B)[0] - exclude_ii = A_name == B_name - else: # Use all particles for this RDF - type_A = type_B = np.ones( - snap.particles.N, dtype=bool - ) # Array of True at all indices - type_A_indices = type_B_indices = np.arange(snap.particles.N) - exclude_ii = True - - # Build up pair exclusions if exclude_bond_depth or exclude_all_bonded - # Reuse these for each frame's RDF unless update_bond_graph = True - # If the bonding topology isn't changing, we only need to get bond graph and excluded pairs once - rdf_correction = 1 - if exclude_bond_depth: - max_idx = snap.particles.N - bond_graph = snapshot_to_graph(snap) - # This gives a seuqunce of tuples [(1, 4), (5, 8)...(i, j)] - excluded_pairs = get_excluded_pairs(bond_graph, exclude_bond_depth) - # Map information of sequence of tuples to an array of unique ints. - # This is used for faster filtering in filter_nlist() (vectorized instead of for loop) - excluded_pairs_encoded = np.array( - [i * max_idx + j for i, j in excluded_pairs] - ) - - n_excluded = len(excluded_pairs) - if A_name == B_name or not any( - [A_name, B_name] - ): # Using same type or all particles - n_total_pairs = ( - len(type_A_indices) * (len(type_A_indices) - 1) / 2 - ) - else: # RDF is not between same types, or using all particles - n_total_pairs = len(type_A_indices) * len(type_B_indices) - # Overwrite default value only if using exclude_bond_depth - rdf_correction = n_total_pairs / (n_total_pairs - n_excluded) - - for snap in trajectory[start:stop:stride]: - A_xyz = snap.particles.position[type_A_indices] - B_xyz = snap.particles.position[type_B_indices] - - # Build up the complete neighborlist - box = snap.configuration.box - system = (box, A_xyz) - aq = freud.locality.AABBQuery.from_system(system) - query_args = {"r_max": r_max, "exclude_ii": exclude_ii} - nlist = aq.query(B_xyz, query_args).toNeighborList() - # - - # Create new bond graph and excluded pairs for each frame. - # Only needed if bond topology is changing, set by ``update_bond_graph`` - if update_bond_graph: - bond_graph = snapshot_to_graph(snap) - excluded_pairs = get_excluded_pairs( - bond_graph, exclude_bond_depth - ) - excluded_pairs_encoded = np.array( - [i * max_idx + j for i, j in excluded_pairs] - ) - n_excluded = len(excluded_pairs) - - # Filter excluded pairs from all pairs in nlist - if exclude_bond_depth: - nlist = filter_nlist( - nlist=nlist, - excluded_pairs_encoded=excluded_pairs_encoded, - query_indices=type_A_indices, - point_indices=type_B_indices, - max_idx=snap.particles.N, - ) - - rdf.compute(aq, neighbors=nlist, reset=False) - return rdf, rdf_correction - - -def get_excluded_pairs( - bond_graph, excluded_bond_depth=None, exclude_all_bonded=False -): - """Returns a set of (i, j) pairs to exclude based on step distance of a bond graph.""" - # TODO: Vecotrize this instead of doing 2 for loops? Maybe just don't worry about it until there is a reason to - # Not a big deal if bonds aren't changing as its only done once. - excluded_pairs = set() - if excluded_bond_depth: - for i in bond_graph.nodes: - lengths = nx.single_source_shortest_path_length( - bond_graph, i, cutoff=excluded_bond_depth - ) - for j, dist in lengths.items(): - # use j > i for 2 reasons: skip adding the same pair twice and its used in filter_nlist - if j > i and dist <= excluded_bond_depth: - excluded_pairs.add((i, j)) - elif exclude_all_bonded: - for component in nx.connected_components(bond_graph): - component = sorted(component) - for i, j in itertools.combinations(component, 2): - excluded_pairs.add((i, j)) - return excluded_pairs - - -def filter_nlist( - nlist, excluded_pairs_encoded, query_indices, point_indices, max_idx -): - """Filter a freud NeighborList by removing excluded pairs. - - Handles the index space mismatch between the NeighborList (which uses - local indices into type filtered position arrays) and excluded_pairs - (which uses global particle indices from the bond graph). - - Parameters - ---------- - nlist : freud.locality.NeighborList - Neighbor list to filter, as returned by AABBQuery.toNeighborList(). - Query point and point indices are local (0 indexed within their - type subsets). - excluded_pairs_encoded : np.ndarray of int, shape (N_excluded,) - Encoded global particle index pairs to exclude, precomputed as - ``i * max_idx + j`` where ``i < j`` and ``max_idx = N_particles``. - Encodes the output of get_excluded_pairs(). - query_indices : np.ndarray of int, shape (N_query,) - Global particle indices of the query points (type A particles). - Maps local query index to global particle index. - point_indices : np.ndarray of int, shape (N_points,) - Global particle indices of the reference points (type B particles). - Maps local point index to global particle index. - - Returns - ------- - freud.locality.NeighborList - Filtered neighbor list with excluded pairs removed. Local indices - are preserved, so it can be passed directly to freud.density.RDF.compute(). - """ - # Local indices of the neighborlist, since it was created after filtering particle type - i_local = nlist.query_point_indices - j_local = nlist.point_indices - - # excluded_pair indices are global, they came from the the bond graph of all particles - # Convert i_local and j_local to global indices so we can look up against excluded_pairs - i_global = query_indices[i_local] - j_global = point_indices[j_local] - - # Sort all pairs so that the first index is always < the second. - lo = np.minimum(i_global, j_global) - hi = np.maximum(i_global, j_global) - - # Encode each pair as a single integer for vectorized lookup. - # (lo, hi) = lo * max_idx + hi which is unique as long as hi < max_idx - neighbor_pairs_encoded = lo * max_idx + hi - - # vectorized set lookup - keep = ~np.isin(neighbor_pairs_encoded, excluded_pairs_encoded) - return freud.locality.NeighborList.from_arrays( - num_query_points=nlist.num_query_points, - num_points=nlist.num_points, - query_point_indices=i_local[keep], - point_indices=j_local[keep], - vectors=nlist.vectors[keep], - ) diff --git a/cmeutils/structure.py b/cmeutils/structure.py index 66467d5..4294b0b 100644 --- a/cmeutils/structure.py +++ b/cmeutils/structure.py @@ -1,17 +1,18 @@ +import itertools import warnings import freud import gsd import gsd.hoomd +import networkx as nx import numpy as np -from rowan import vector_vector_rotation from cmeutils.geometry import ( angle_between_vectors, dihedral_angle, get_plane_normal, ) -from cmeutils.gsd_utils import frame_to_freud_system, get_molecule_cluster +from cmeutils.gsd_utils import frame_to_freud_system, snapshot_to_graph from cmeutils.plotting import get_histogram @@ -406,69 +407,33 @@ def dihedral_distribution( return np.array(dihedrals) -def get_quaternions(n_views=20): - """Get the quaternions for the specified number of views. - - The first (n_view - 3) views will be the views even distributed on a sphere, - while the last three views will be the face-on, edge-on, and corner-on - views, respectively. - - These quaternions are useful as input to `view_orientation` kwarg in - `freud.diffraction.Diffractometer.compute`. - - Parameters - ---------- - n_views : int, default 20 - The number of views to compute. - - Returns - ------- - list of numpy.ndarray - Quaternions as (4,) arrays. - """ - if n_views <= 3 or not isinstance(n_views, int): - raise ValueError("Please set n_views to an integer greater than 3.") - # Calculate points for even distribution on a sphere - ga = np.pi * (3 - 5**0.5) - theta = ga * np.arange(n_views - 3) - z = np.linspace(1 - 1 / (n_views - 3), 1 / (n_views - 3), n_views - 3) - radius = np.sqrt(1 - z * z) - points = np.zeros((n_views, 3)) - points[:-3, 0] = radius * np.cos(theta) - points[:-3, 1] = radius * np.sin(theta) - points[:-3, 2] = z - - # face on - points[-3] = np.array([0, 0, 1]) - # edge on - points[-2] = np.array([0, 1, 1]) - # corner on - points[-1] = np.array([1, 1, 1]) - - unit_z = np.array([0, 0, 1]) - return [vector_vector_rotation(i, unit_z) for i in points] - - def gsd_rdf( gsdfile, - A_name, - B_name, + A_name=None, + B_name=None, start=0, stop=-1, stride=1, r_max=None, r_min=0, bins=100, - exclude_bonded=True, + exclude_bond_depth=None, + exclude_all_bonded=False, + update_bond_graph=False, ): - """Compute intermolecular RDF from a GSD file. + """Uses freud's RDF module to calculate an RDF averaged over a GSD file. - This function calculates the radial distribution function given a GSD file - and the names of the particle types. By default it will calculate the RDF - for the entire trajectory. + Notes + ----- + This method lets you set a bond-depth exclusion to prevent neighbors of the + same molecule to be used in the RDF calculations. Bond depth is counted in + terms of steps away on a connected bond graph. - It is assumed that the bonding, number of particles, and simulation box do - not change during the simulation. + For example, ``excluded_bond_depth=1`` excludes pairs directly bonded together, + ``excluded_bond_depth=2`` excludes both pairs (i, j) and (i, k) in (i-j-k), and so on. + This can be set to any positive integer value, and isn't limited to particles belonging + to the same bond, angle or dihedral. To exclude all intramolecular pairs use + the ``exclude_all_bonded`` parameter instead. Parameters ---------- @@ -486,71 +451,135 @@ def gsd_rdf( stride : int, default = 1 The stride size when iterating through start:stop r_max : float - Maximum radius of RDF. If None, half of the maximum box size is used. - (default -1) + Maximum radius of RDF. If None, half of the minimum box size is used. r_min : float Minimum radius of RDF. (default 0) bins : int Number of bins to use when calculating the RDF. (default 100) - exclude_bonded : bool - Whether to remove particles in same molecule from the neighbor list. - (default True) + exclude_bond_depth : int, optional (default None) + Excludes all pairs within a depth (distance on a bond graph) + from the RDF calculation. + exclude_all_bonded : bool, optional (default False) + Excludes all pairs belonging to the same molecule from the + RDF calculation. + update_bond_graph : bool, optional (default False) + Updates the bond graph to find excluded pairs for each + frame used in the RDF calclation. This may significantly + slow the RDF calcualtion. This should always be False + unless the bonds in the trajectory are changing. Returns ------- - (freud.density.RDF, float) + tuple(rdf, rdf_correction) : (freud.density.RDF, float) + Calculated RDF. Access r values with ``rdf.bin_centers`` and g(r) with ``rdf.rdf`` + rdf_correction is always 1 unless ``exclude_bond_depth`` or ``exclude_all_bonded`` are used. + This corrects the g(r) normalization to account for excluded pairs. + To include this in the results, g(r) = rdf.rdf * rdf_correction """ + if any([A_name, B_name]) and not all([A_name, B_name]): + raise ValueError( + "If A_name or B_name is given, the other must be defined as well." + "To calculate an RDF between the same bead type, set A_name and B_name equal to the same value." + "To calculate an RDF between all possible pairs, leave both as ``None``." + ) + + if all([exclude_bond_depth, exclude_all_bonded]): + raise ValueError( + "Only use one of excluded_bond_depth and exclude_all_bonded." + ) + with gsd.hoomd.open(gsdfile, mode="r") as trajectory: - snap = trajectory[0] + # Grab the first snapshot for some book-keeping. + snap = trajectory[start] + # Use a value just less than half the minimum box length. + # TODO: Iterate through all boxes, use the smallest one? Edge cases might arise with NPT sims if r_max is None: - # Use a value just less than half the maximum box length. r_max = np.nextafter( - np.max(snap.configuration.box[:3]) * 0.49, 0, dtype=np.float32 + np.min(snap.configuration.box[:3]) * 0.49, 0, dtype=np.float32 ) rdf = freud.density.RDF(bins=bins, r_max=r_max, r_min=r_min) - type_A = snap.particles.typeid == snap.particles.types.index(A_name) - type_B = snap.particles.typeid == snap.particles.types.index(B_name) + # Filter particles by type A and type B + if A_name is not None and B_name is not None: + type_A = snap.particles.typeid == snap.particles.types.index(A_name) + type_B = snap.particles.typeid == snap.particles.types.index(B_name) + # These 2 *_indices variables store global particle indices (Before filtering by type) + # If excluding by bond depth, these need to be passed into filter_nlist + type_A_indices = np.where(type_A)[0] + type_B_indices = np.where(type_B)[0] + exclude_ii = A_name == B_name + else: # Use all particles for this RDF + type_A = type_B = np.ones( + snap.particles.N, dtype=bool + ) # Array of True at all indices + type_A_indices = type_B_indices = np.arange(snap.particles.N) + exclude_ii = True + + # Build up pair exclusions if exclude_bond_depth or exclude_all_bonded + # Reuse these for each frame's RDF unless update_bond_graph = True + # If the bonding topology isn't changing, we only need to get bond graph and excluded pairs once + rdf_correction = 1 + if exclude_bond_depth: + max_idx = snap.particles.N + bond_graph = snapshot_to_graph(snap) + # This gives a seuqunce of tuples [(1, 4), (5, 8)...(i, j)] + excluded_pairs = get_excluded_pairs(bond_graph, exclude_bond_depth) + # Map information of sequence of tuples to an array of unique ints. + # This is used for faster filtering in filter_nlist() (vectorized instead of for loop) + excluded_pairs_encoded = np.array( + [i * max_idx + j for i, j in excluded_pairs] + ) - if exclude_bonded: - molecules = get_molecule_cluster(snap=snap) - molecules_A = molecules[type_A] - molecules_B = molecules[type_B] + n_excluded = len(excluded_pairs) + if A_name == B_name or not any( + [A_name, B_name] + ): # Using same type or all particles + n_total_pairs = ( + len(type_A_indices) * (len(type_A_indices) - 1) / 2 + ) + else: # RDF is not between same types, or using all particles + n_total_pairs = len(type_A_indices) * len(type_B_indices) + # Overwrite default value only if using exclude_bond_depth + rdf_correction = n_total_pairs / (n_total_pairs - n_excluded) for snap in trajectory[start:stop:stride]: - A_pos = snap.particles.position[type_A] - if A_name == B_name: - B_pos = A_pos - exclude_ii = True - ab_ratio = 1 - else: - B_pos = snap.particles.position[type_B] - exclude_ii = False - ab_ratio = len(A_pos) / len(B_pos) + A_xyz = snap.particles.position[type_A_indices] + B_xyz = snap.particles.position[type_B_indices] + # Build up the complete neighborlist box = snap.configuration.box - system = (box, A_pos) + system = (box, A_xyz) aq = freud.locality.AABBQuery.from_system(system) - nlist = aq.query( - B_pos, {"r_max": r_max, "exclude_ii": exclude_ii} - ).toNeighborList() - - if exclude_bonded: - pre_filter = len(nlist) - nlist.filter( - molecules_A[nlist.point_indices] - != molecules_B[nlist.query_point_indices] + query_args = {"r_max": r_max, "exclude_ii": exclude_ii} + nlist = aq.query(B_xyz, query_args).toNeighborList() + # + + # Create new bond graph and excluded pairs for each frame. + # Only needed if bond topology is changing, set by ``update_bond_graph`` + if update_bond_graph: + bond_graph = snapshot_to_graph(snap) + excluded_pairs = get_excluded_pairs( + bond_graph, exclude_bond_depth + ) + excluded_pairs_encoded = np.array( + [i * max_idx + j for i, j in excluded_pairs] + ) + n_excluded = len(excluded_pairs) + + # Filter excluded pairs from all pairs in nlist + if exclude_bond_depth: + nlist = filter_nlist( + nlist=nlist, + excluded_pairs_encoded=excluded_pairs_encoded, + query_indices=type_A_indices, + point_indices=type_B_indices, + max_idx=snap.particles.N, ) - post_filter = len(nlist) rdf.compute(aq, neighbors=nlist, reset=False) - - normalization = post_filter / pre_filter if exclude_bonded else 1 - normalization *= ab_ratio - - return rdf, normalization + return rdf, rdf_correction def structure_factor( @@ -680,50 +709,6 @@ def diffraction_pattern( return dp -def get_centers(gsdfile, new_gsdfile): - """Create a gsd file containing the molecule centers from an existing gsd - file. - - - This function calculates the centers of a trajectory given a GSD file - and stores them into a new GSD file just for centers. By default it will - calculate the centers of an entire trajectory. - - Parameters - ---------- - gsdfile : str - Filename of the GSD trajectory. - new_gsdfile : str - Filename of new GSD for centers. - """ - with ( - gsd.hoomd.open(new_gsdfile, "w") as new_traj, - gsd.hoomd.open(gsdfile, "r") as traj, - ): - snap = traj[0] - cluster_idx = get_molecule_cluster(snap=snap) - for snap in traj: - new_snap = gsd.hoomd.Frame() - new_snap.configuration.box = snap.configuration.box - f_box = freud.box.Box.from_box(snap.configuration.box) - # Use the freud box to unwrap the particle positions - unwrapped_positions = f_box.unwrap( - snap.particles.position, snap.particles.image - ) - uw_centers = [] - for i in range(max(cluster_idx) + 1): - cluster_uw_pos = unwrapped_positions[np.where(cluster_idx == i)] - uw_centers.append(np.mean(cluster_uw_pos, axis=0)) - uw_centers = np.stack(uw_centers) - new_snap.particles.position = f_box.wrap(uw_centers) - new_snap.particles.N = len(uw_centers) - new_snap.particles.types = ["A"] - new_snap.particles.image = f_box.get_images(uw_centers) - new_snap.particles.typeid = np.zeros(len(uw_centers)) - new_snap.validate() - new_traj.append(new_snap) - - def order_parameter(aa_gsd, cg_gsd, mapping, r_max, a_max, large=6, start=-10): """Calculate the order parameter of a system. @@ -887,54 +872,85 @@ def concentration_profile(snap, A_indices, B_indices, n_bins=70, box_axis=0): return d_profile[:-1], A_count, B_count, total_count -def all_atom_rdf( - gsdfile, - start=0, - stop=-1, - stride=1, - r_max=None, - r_min=0, - bins=100, +def get_excluded_pairs( + bond_graph, excluded_bond_depth=None, exclude_all_bonded=False ): - """Compute intermolecular RDF from a GSD file. + """Returns a set of (i, j) pairs to exclude based on step distance of a bond graph.""" + # TODO: Vecotrize this instead of doing 2 for loops? Maybe just don't worry about it until there is a reason to + # Not a big deal if bonds aren't changing as its only done once. + excluded_pairs = set() + if excluded_bond_depth: + for i in bond_graph.nodes: + lengths = nx.single_source_shortest_path_length( + bond_graph, i, cutoff=excluded_bond_depth + ) + for j, dist in lengths.items(): + # use j > i for 2 reasons: skip adding the same pair twice and its used in filter_nlist + if j > i and dist <= excluded_bond_depth: + excluded_pairs.add((i, j)) + elif exclude_all_bonded: + for component in nx.connected_components(bond_graph): + component = sorted(component) + for i, j in itertools.combinations(component, 2): + excluded_pairs.add((i, j)) + return excluded_pairs + + +def filter_nlist( + nlist, excluded_pairs_encoded, query_indices, point_indices, max_idx +): + """Filter a freud NeighborList by removing excluded pairs. - This function calculates the radial distribution function given a GSD file - for all atoms. By default it will calculate the RDF - for the entire trajectory. - It is assumed that the bonding, number of particles, and simulation box do - not change during the simulation. + Handles the index space mismatch between the NeighborList (which uses + local indices into type filtered position arrays) and excluded_pairs + (which uses global particle indices from the bond graph). Parameters ---------- - gsdfile : str - Filename of the GSD trajectory. - start : int, default 0 - Starting frame index for accumulating the RDF. Negative numbers index - from the end. - stop : int, default -1 - Final frame index for accumulating the RDF. If None, the last frame - will be used. - stride : int, default 1 - The stride size when iterating through start:stop - r_max : float, default None - Maximum radius of RDF. If None, half of the maximum box size is used. - r_min : float, default 0 - Minimum radius of RDF. - bins : int, default 100 - Number of bins to use when calculating the RDF. + nlist : freud.locality.NeighborList + Neighbor list to filter, as returned by AABBQuery.toNeighborList(). + Query point and point indices are local (0 indexed within their + type subsets). + excluded_pairs_encoded : np.ndarray of int, shape (N_excluded,) + Encoded global particle index pairs to exclude, precomputed as + ``i * max_idx + j`` where ``i < j`` and ``max_idx = N_particles``. + Encodes the output of get_excluded_pairs(). + query_indices : np.ndarray of int, shape (N_query,) + Global particle indices of the query points (type A particles). + Maps local query index to global particle index. + point_indices : np.ndarray of int, shape (N_points,) + Global particle indices of the reference points (type B particles). + Maps local point index to global particle index. Returns ------- - freud.density.RDF + freud.locality.NeighborList + Filtered neighbor list with excluded pairs removed. Local indices + are preserved, so it can be passed directly to freud.density.RDF.compute(). """ - with gsd.hoomd.open(gsdfile, mode="r") as trajectory: - snap = trajectory[start] - if r_max is None: - # Use a value just less than half the maximum box length. - r_max = np.nextafter( - np.max(snap.configuration.box[:3]) * 0.5, 0, dtype=np.float32 - ) - rdf = freud.density.RDF(bins=bins, r_max=r_max, r_min=r_min) - for snap in trajectory[start:stop:stride]: - rdf.compute(snap, reset=False) - return rdf + # Local indices of the neighborlist, since it was created after filtering particle type + i_local = nlist.query_point_indices + j_local = nlist.point_indices + + # excluded_pair indices are global, they came from the the bond graph of all particles + # Convert i_local and j_local to global indices so we can look up against excluded_pairs + i_global = query_indices[i_local] + j_global = point_indices[j_local] + + # Sort all pairs so that the first index is always < the second. + lo = np.minimum(i_global, j_global) + hi = np.maximum(i_global, j_global) + + # Encode each pair as a single integer for vectorized lookup. + # (lo, hi) = lo * max_idx + hi which is unique as long as hi < max_idx + neighbor_pairs_encoded = lo * max_idx + hi + + # vectorized set lookup + keep = ~np.isin(neighbor_pairs_encoded, excluded_pairs_encoded) + return freud.locality.NeighborList.from_arrays( + num_query_points=nlist.num_query_points, + num_points=nlist.num_points, + query_point_indices=i_local[keep], + point_indices=j_local[keep], + vectors=nlist.vectors[keep], + ) diff --git a/cmeutils/tests/base_test.py b/cmeutils/tests/base_test.py index 3d2ea86..0840e18 100644 --- a/cmeutils/tests/base_test.py +++ b/cmeutils/tests/base_test.py @@ -50,6 +50,14 @@ def snap_bond(self, gsdfile_bond): snap = f[-1] return snap + @pytest.fixture + def AB_chain_gsd(self): + return path.join(asset_dir, "AB-traj.gsd") + + @pytest.fixture + def LJ_gsd(self): + return path.join(asset_dir, "lj-fluid.gsd") + @pytest.fixture def butane_gsd(self): return path.join(asset_dir, "butanes.gsd") diff --git a/cmeutils/tests/test_geometry.py b/cmeutils/tests/test_geometry.py index 8335bb5..ad4f706 100644 --- a/cmeutils/tests/test_geometry.py +++ b/cmeutils/tests/test_geometry.py @@ -9,6 +9,7 @@ angle_between_vectors, get_backbone_vector, get_plane_normal, + get_quaternions, moit, radial_grid_positions, spherical_grid_positions, @@ -38,6 +39,17 @@ def test_moit(self): _moit = moit(points=[(-1, 0, 0), (1, 0, 0)], masses=[1, 1]) assert np.array_equal(_moit, np.array([0, 2.0, 2.0])) + def test_get_quaternions(self): + with pytest.raises(ValueError): + get_quaternions(0) + + with pytest.raises(ValueError): + get_quaternions(5.3) + + qs = get_quaternions() + assert len(qs) == 20 + assert len(qs[0]) == 4 + def test_get_plane_normal(self): points = np.array([[1, 0, 0], [0, 1, 0], [-1, 0, 0], [0, -1, 0]]) ctr, norm = get_plane_normal(points) diff --git a/cmeutils/tests/test_gsd.py b/cmeutils/tests/test_gsd.py index 6c926cb..0272ec4 100644 --- a/cmeutils/tests/test_gsd.py +++ b/cmeutils/tests/test_gsd.py @@ -12,6 +12,7 @@ ellipsoid_gsd, frame_to_freud_system, get_all_types, + get_centers, get_molecule_cluster, get_type_position, identify_snapshot_connections, @@ -32,6 +33,11 @@ class TestGSD(BaseTest): + def test_get_centers(self, gsdfile): + new_gsdfile = "centers.gsd" + centers = get_centers(gsdfile, new_gsdfile) + assert isinstance(centers, type(None)) + def test_frame_to_freud_system(self, butane_gsd): with gsd.hoomd.open(butane_gsd) as traj: frame = traj[0] diff --git a/cmeutils/tests/test_structure.py b/cmeutils/tests/test_structure.py index ff6779d..14f9f2e 100644 --- a/cmeutils/tests/test_structure.py +++ b/cmeutils/tests/test_structure.py @@ -3,16 +3,15 @@ import freud import numpy as np import pytest +from scipy.integrate import trapezoid +from cmeutils.geometry import get_quaternions from cmeutils.structure import ( - all_atom_rdf, angle_distribution, bond_distribution, concentration_profile, diffraction_pattern, dihedral_distribution, - get_centers, - get_quaternions, gsd_rdf, order_parameter, structure_factor, @@ -296,37 +295,76 @@ def test_structure_factor_bad_method(self, gsdfile_bond): with pytest.raises(ValueError): structure_factor(gsdfile_bond, k_min=0.2, k_max=5, method="a") - def test_gsd_rdf(self, gsdfile_bond): - rdf_ex, norm = gsd_rdf(gsdfile_bond, "A", "B") - rdf_noex, norm2 = gsd_rdf(gsdfile_bond, "A", "B", exclude_bonded=False) - assert np.isclose(norm2, 2 / 3, 1e-4) - assert not np.array_equal(rdf_noex, rdf_ex) - - def test_gsd_rdf_samename(self, gsdfile_bond): - rdf_ex, norm = gsd_rdf(gsdfile_bond, "A", "A") - rdf_noex, norm2 = gsd_rdf(gsdfile_bond, "A", "A", exclude_bonded=False) - assert norm2 == 1 - assert not np.array_equal(rdf_noex, rdf_ex) - - def test_gsd_rdf_pair_order(self, gsdfile_bond): - rdf, norm = gsd_rdf(gsdfile_bond, "A", "B") - rdf_y = rdf.rdf * norm - rdf2, norm2 = gsd_rdf(gsdfile_bond, "B", "A") - rdf_y2 = rdf2.rdf * norm2 - - for i, j in zip(rdf_y, rdf_y2): - assert np.allclose(i, j, atol=1e-4) - - def test_get_quaternions(self): - with pytest.raises(ValueError): - get_quaternions(0) + def test_gsd_rdf(self, AB_chain_gsd): + rdf, scale_factor = gsd_rdf( + gsdfile=AB_chain_gsd, + start=0, + stop=10, + exclude_bond_depth=0, + exclude_all_bonded=False, + ) + assert isinstance(rdf, freud.density.RDF) + rdf.rdf + assert scale_factor == 1 - with pytest.raises(ValueError): - get_quaternions(5.3) + def test_gsd_rdf_exclusions(self, AB_chain_gsd): + """Exclude bonded neighbor.""" + rdf, scale_factor = gsd_rdf( + gsdfile=AB_chain_gsd, + start=0, + stop=10, + exclude_bond_depth=1, + exclude_all_bonded=False, + ) + assert scale_factor != 1 + # In this GSD file, the bond length is ~1, so the first peak shows up around r=1 + zero_indices = np.where(rdf.bin_centers < 1.5)[0] + zero_array = np.zeros_like(zero_indices) + rdf_values = rdf.rdf[zero_indices] + assert np.allclose(rdf_values, zero_array) + + rdf, scale_factor = gsd_rdf( + gsdfile=AB_chain_gsd, + start=0, + stop=10, + exclude_bond_depth=2, + exclude_all_bonded=False, + ) + assert scale_factor != 1 + # The second peak shows up around r=2, should be gone + zero_indices = np.where(rdf.bin_centers < 2.5)[0] + zero_array = np.zeros_like(zero_indices) + rdf_values = rdf.rdf[zero_indices] + assert np.allclose(rdf_values, zero_array) + + def test_gsd_rdf_r_max(self, LJ_gsd): + """Test 2 RDFs with different r_cuts. The values of the shared r_cut region should be very close""" + rdf, scale_factor = gsd_rdf( + gsdfile=LJ_gsd, + start=0, + stop=10, + r_max=3, + exclude_bond_depth=0, + exclude_all_bonded=False, + ) + rdf2, scale_factor2 = gsd_rdf( + gsdfile=LJ_gsd, + start=0, + stop=10, + r_max=4, + exclude_bond_depth=0, + exclude_all_bonded=False, + ) - qs = get_quaternions() - assert len(qs) == 20 - assert len(qs[0]) == 4 + check_indices = np.where(rdf.bin_centers < 3)[0] + check_indices2 = np.where(rdf2.bin_centers < 3)[0] + rdf_integral = trapezoid( + rdf.rdf[check_indices], rdf.bin_centers[check_indices] + ) + rdf2_integral = trapezoid( + rdf2.rdf[check_indices2], rdf2.bin_centers[check_indices2] + ) + assert np.isclose(rdf_integral, rdf2_integral, rtol=0.05) def test_order_parameter(self, p3ht_gsd, p3ht_cg_gsd, mapping): r_max = 2 @@ -339,15 +377,6 @@ def test_order_parameter(self, p3ht_gsd, p3ht_cg_gsd, mapping): assert np.isclose(order[0], 0.33125) assert len(cl_idx[0]) == 160 - def test_all_atom_rdf(self, gsdfile): - rdf = all_atom_rdf(gsdfile) - assert isinstance(rdf, freud.density.RDF) - - def test_get_centers(self, gsdfile): - new_gsdfile = "centers.gsd" - centers = get_centers(gsdfile, new_gsdfile) - assert isinstance(centers, type(None)) - def test_conc_profiel(self, slab_snapshot): A_indices = np.arange(20) B_indices = np.arange(20, 40) From e69619f4bd3d1f7b1664b016a7e5e078cade5b8c Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 11:28:27 +0000 Subject: [PATCH 08/14] Add new asset gsd files --- cmeutils/tests/assets/AB-traj.gsd | Bin 0 -> 5648 bytes cmeutils/tests/assets/lj-fluid.gsd | Bin 0 -> 248546 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 cmeutils/tests/assets/AB-traj.gsd create mode 100644 cmeutils/tests/assets/lj-fluid.gsd diff --git a/cmeutils/tests/assets/AB-traj.gsd b/cmeutils/tests/assets/AB-traj.gsd new file mode 100644 index 0000000000000000000000000000000000000000..58755f52389973d4cc8d717d905456fdb65b4b46 GIT binary patch literal 5648 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 Zs;)rQ6{xxbRac Date: Thu, 12 Mar 2026 12:41:35 +0000 Subject: [PATCH 09/14] More unit tests --- cmeutils/tests/test_structure.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cmeutils/tests/test_structure.py b/cmeutils/tests/test_structure.py index 14f9f2e..6a00fc9 100644 --- a/cmeutils/tests/test_structure.py +++ b/cmeutils/tests/test_structure.py @@ -295,6 +295,24 @@ def test_structure_factor_bad_method(self, gsdfile_bond): with pytest.raises(ValueError): structure_factor(gsdfile_bond, k_min=0.2, k_max=5, method="a") + def test_rdf_bad_args(self, AB_chain_gsd): + with pytest.raises(ValueError): + gsd_rdf( + gsdfile=AB_chain_gsd, + start=0, + stop=10, + exclude_bond_depth=2, + exclude_all_bonded=True, + ) + + with pytest.raises(ValueError): + gsd_rdf( + gsdfile=AB_chain_gsd, + A_name="A", + start=0, + stop=10, + ) + def test_gsd_rdf(self, AB_chain_gsd): rdf, scale_factor = gsd_rdf( gsdfile=AB_chain_gsd, From 244726cb82cf33a4f1e61f740e6d00ee00924c9a Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 12:51:17 +0000 Subject: [PATCH 10/14] Add corrections to handle exclude all bonded pairs --- cmeutils/structure.py | 15 +++++++++++---- cmeutils/tests/test_structure.py | 11 +++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/cmeutils/structure.py b/cmeutils/structure.py index 4294b0b..3989011 100644 --- a/cmeutils/structure.py +++ b/cmeutils/structure.py @@ -521,11 +521,13 @@ def gsd_rdf( # Reuse these for each frame's RDF unless update_bond_graph = True # If the bonding topology isn't changing, we only need to get bond graph and excluded pairs once rdf_correction = 1 - if exclude_bond_depth: + if exclude_bond_depth or exclude_all_bonded: max_idx = snap.particles.N bond_graph = snapshot_to_graph(snap) # This gives a seuqunce of tuples [(1, 4), (5, 8)...(i, j)] - excluded_pairs = get_excluded_pairs(bond_graph, exclude_bond_depth) + excluded_pairs = get_excluded_pairs( + bond_graph, exclude_bond_depth, exclude_all_bonded + ) # Map information of sequence of tuples to an array of unique ints. # This is used for faster filtering in filter_nlist() (vectorized instead of for loop) excluded_pairs_encoded = np.array( @@ -542,7 +544,12 @@ def gsd_rdf( else: # RDF is not between same types, or using all particles n_total_pairs = len(type_A_indices) * len(type_B_indices) # Overwrite default value only if using exclude_bond_depth - rdf_correction = n_total_pairs / (n_total_pairs - n_excluded) + if n_total_pairs == n_excluded: + warnings.warn( + "Exclusions resulted in no pairs being used to calculate this RDF." + ) + else: + rdf_correction = n_total_pairs / (n_total_pairs - n_excluded) for snap in trajectory[start:stop:stride]: A_xyz = snap.particles.position[type_A_indices] @@ -569,7 +576,7 @@ def gsd_rdf( n_excluded = len(excluded_pairs) # Filter excluded pairs from all pairs in nlist - if exclude_bond_depth: + if exclude_bond_depth or exclude_all_bonded: nlist = filter_nlist( nlist=nlist, excluded_pairs_encoded=excluded_pairs_encoded, diff --git a/cmeutils/tests/test_structure.py b/cmeutils/tests/test_structure.py index 6a00fc9..63e740f 100644 --- a/cmeutils/tests/test_structure.py +++ b/cmeutils/tests/test_structure.py @@ -325,6 +325,17 @@ def test_gsd_rdf(self, AB_chain_gsd): rdf.rdf assert scale_factor == 1 + def test_gsd_rdf_exclude_all_bonded(self, AB_chain_gsd): + rdf, scale_factor = gsd_rdf( + gsdfile=AB_chain_gsd, + start=0, + stop=10, + exclude_all_bonded=True, + ) + assert isinstance(rdf, freud.density.RDF) + assert scale_factor == 1 + assert np.array_equal(rdf.rdf, np.zeros_like(rdf.rdf)) + def test_gsd_rdf_exclusions(self, AB_chain_gsd): """Exclude bonded neighbor.""" rdf, scale_factor = gsd_rdf( From 78a7cf1c6ceb458dcadc1e914b360029a1ecba9f Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 12:56:05 +0000 Subject: [PATCH 11/14] one more unit test --- cmeutils/tests/test_structure.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmeutils/tests/test_structure.py b/cmeutils/tests/test_structure.py index 63e740f..fe94999 100644 --- a/cmeutils/tests/test_structure.py +++ b/cmeutils/tests/test_structure.py @@ -332,7 +332,6 @@ def test_gsd_rdf_exclude_all_bonded(self, AB_chain_gsd): stop=10, exclude_all_bonded=True, ) - assert isinstance(rdf, freud.density.RDF) assert scale_factor == 1 assert np.array_equal(rdf.rdf, np.zeros_like(rdf.rdf)) @@ -395,6 +394,17 @@ def test_gsd_rdf_r_max(self, LJ_gsd): ) assert np.isclose(rdf_integral, rdf2_integral, rtol=0.05) + def test_gsd_rdf_update_bond_graph(self, LJ_gsd): + """Test 2 RDFs with different r_cuts. The values of the shared r_cut region should be very close""" + rdf, scale_factor = gsd_rdf( + gsdfile=LJ_gsd, + start=0, + stop=10, + r_max=3, + exclude_bond_depth=2, + update_bond_graph=True, + ) + def test_order_parameter(self, p3ht_gsd, p3ht_cg_gsd, mapping): r_max = 2 a_max = 30 From 17be3ea1986b86692ab9bee632326211a6620eb2 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 15:19:41 +0000 Subject: [PATCH 12/14] Fix typos --- cmeutils/structure.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/cmeutils/structure.py b/cmeutils/structure.py index 3989011..636a60a 100644 --- a/cmeutils/structure.py +++ b/cmeutils/structure.py @@ -429,8 +429,8 @@ def gsd_rdf( same molecule to be used in the RDF calculations. Bond depth is counted in terms of steps away on a connected bond graph. - For example, ``excluded_bond_depth=1`` excludes pairs directly bonded together, - ``excluded_bond_depth=2`` excludes both pairs (i, j) and (i, k) in (i-j-k), and so on. + For example, ``exclude_bond_depth=1`` excludes pairs directly bonded together, + ``exclude_bond_depth=2`` excludes both pairs (i, j) and (i, k) in (i-j-k), and so on. This can be set to any positive integer value, and isn't limited to particles belonging to the same bond, angle or dihedral. To exclude all intramolecular pairs use the ``exclude_all_bonded`` parameter instead. @@ -464,8 +464,8 @@ def gsd_rdf( RDF calculation. update_bond_graph : bool, optional (default False) Updates the bond graph to find excluded pairs for each - frame used in the RDF calclation. This may significantly - slow the RDF calcualtion. This should always be False + frame used in the RDF calculation. This may significantly + slow the RDF calculation. This should always be False unless the bonds in the trajectory are changing. Returns @@ -478,9 +478,9 @@ def gsd_rdf( """ if any([A_name, B_name]) and not all([A_name, B_name]): raise ValueError( - "If A_name or B_name is given, the other must be defined as well." - "To calculate an RDF between the same bead type, set A_name and B_name equal to the same value." - "To calculate an RDF between all possible pairs, leave both as ``None``." + "If A_name or B_name is given, the other must be defined as well. " + "To calculate an RDF between the same bead type, set A_name and B_name equal to the same value. " + "To calculate an RDF between all possible pairs, leave both as ``None``. " ) if all([exclude_bond_depth, exclude_all_bonded]): @@ -524,7 +524,7 @@ def gsd_rdf( if exclude_bond_depth or exclude_all_bonded: max_idx = snap.particles.N bond_graph = snapshot_to_graph(snap) - # This gives a seuqunce of tuples [(1, 4), (5, 8)...(i, j)] + # This gives a seuquence of tuples [(1, 4), (5, 8)...(i, j)] excluded_pairs = get_excluded_pairs( bond_graph, exclude_bond_depth, exclude_all_bonded ) @@ -565,10 +565,10 @@ def gsd_rdf( # Create new bond graph and excluded pairs for each frame. # Only needed if bond topology is changing, set by ``update_bond_graph`` - if update_bond_graph: + if update_bond_graph and (exclude_bond_depth or exclude_all_bonded): bond_graph = snapshot_to_graph(snap) excluded_pairs = get_excluded_pairs( - bond_graph, exclude_bond_depth + bond_graph, exclude_bond_depth, exclude_all_bonded ) excluded_pairs_encoded = np.array( [i * max_idx + j for i, j in excluded_pairs] @@ -883,8 +883,6 @@ def get_excluded_pairs( bond_graph, excluded_bond_depth=None, exclude_all_bonded=False ): """Returns a set of (i, j) pairs to exclude based on step distance of a bond graph.""" - # TODO: Vecotrize this instead of doing 2 for loops? Maybe just don't worry about it until there is a reason to - # Not a big deal if bonds aren't changing as its only done once. excluded_pairs = set() if excluded_bond_depth: for i in bond_graph.nodes: From f9e45d747198b761e97f8093406fc713f49c5321 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 16:46:15 +0000 Subject: [PATCH 13/14] remove update bond graph param --- cmeutils/structure.py | 23 ++--------------------- cmeutils/tests/test_structure.py | 11 ----------- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/cmeutils/structure.py b/cmeutils/structure.py index 636a60a..889cbc3 100644 --- a/cmeutils/structure.py +++ b/cmeutils/structure.py @@ -419,7 +419,6 @@ def gsd_rdf( bins=100, exclude_bond_depth=None, exclude_all_bonded=False, - update_bond_graph=False, ): """Uses freud's RDF module to calculate an RDF averaged over a GSD file. @@ -462,16 +461,11 @@ def gsd_rdf( exclude_all_bonded : bool, optional (default False) Excludes all pairs belonging to the same molecule from the RDF calculation. - update_bond_graph : bool, optional (default False) - Updates the bond graph to find excluded pairs for each - frame used in the RDF calculation. This may significantly - slow the RDF calculation. This should always be False - unless the bonds in the trajectory are changing. Returns ------- tuple(rdf, rdf_correction) : (freud.density.RDF, float) - Calculated RDF. Access r values with ``rdf.bin_centers`` and g(r) with ``rdf.rdf`` + Access r values with ``rdf.bin_centers`` and g(r) with ``rdf.rdf`` rdf_correction is always 1 unless ``exclude_bond_depth`` or ``exclude_all_bonded`` are used. This corrects the g(r) normalization to account for excluded pairs. To include this in the results, g(r) = rdf.rdf * rdf_correction @@ -518,7 +512,7 @@ def gsd_rdf( exclude_ii = True # Build up pair exclusions if exclude_bond_depth or exclude_all_bonded - # Reuse these for each frame's RDF unless update_bond_graph = True + # Reuse these for each frame's RDF # If the bonding topology isn't changing, we only need to get bond graph and excluded pairs once rdf_correction = 1 if exclude_bond_depth or exclude_all_bonded: @@ -561,19 +555,6 @@ def gsd_rdf( aq = freud.locality.AABBQuery.from_system(system) query_args = {"r_max": r_max, "exclude_ii": exclude_ii} nlist = aq.query(B_xyz, query_args).toNeighborList() - # - - # Create new bond graph and excluded pairs for each frame. - # Only needed if bond topology is changing, set by ``update_bond_graph`` - if update_bond_graph and (exclude_bond_depth or exclude_all_bonded): - bond_graph = snapshot_to_graph(snap) - excluded_pairs = get_excluded_pairs( - bond_graph, exclude_bond_depth, exclude_all_bonded - ) - excluded_pairs_encoded = np.array( - [i * max_idx + j for i, j in excluded_pairs] - ) - n_excluded = len(excluded_pairs) # Filter excluded pairs from all pairs in nlist if exclude_bond_depth or exclude_all_bonded: diff --git a/cmeutils/tests/test_structure.py b/cmeutils/tests/test_structure.py index fe94999..9c11abb 100644 --- a/cmeutils/tests/test_structure.py +++ b/cmeutils/tests/test_structure.py @@ -394,17 +394,6 @@ def test_gsd_rdf_r_max(self, LJ_gsd): ) assert np.isclose(rdf_integral, rdf2_integral, rtol=0.05) - def test_gsd_rdf_update_bond_graph(self, LJ_gsd): - """Test 2 RDFs with different r_cuts. The values of the shared r_cut region should be very close""" - rdf, scale_factor = gsd_rdf( - gsdfile=LJ_gsd, - start=0, - stop=10, - r_max=3, - exclude_bond_depth=2, - update_bond_graph=True, - ) - def test_order_parameter(self, p3ht_gsd, p3ht_cg_gsd, mapping): r_max = 2 a_max = 30 From 8fc34584023d99ef5044d619a443ab6df455f681 Mon Sep 17 00:00:00 2001 From: chrisjonesBSU Date: Thu, 12 Mar 2026 21:39:09 +0000 Subject: [PATCH 14/14] Bump version, update numpy pin --- cmeutils/__version__.py | 2 +- environment-dev.yml | 2 +- environment.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cmeutils/__version__.py b/cmeutils/__version__.py index 3e8d9f9..5b60188 100644 --- a/cmeutils/__version__.py +++ b/cmeutils/__version__.py @@ -1 +1 @@ -__version__ = "1.4.0" +__version__ = "1.5.0" diff --git a/environment-dev.yml b/environment-dev.yml index 73f9889..fea946f 100644 --- a/environment-dev.yml +++ b/environment-dev.yml @@ -8,7 +8,7 @@ dependencies: - gsd >=3.0 - hoomd >=5.0 - mbuild >=1.0 - - numpy >=2.0,<2.3 + - numpy >=2.0 - pip - python >= 3.10,<=3.13 - matplotlib diff --git a/environment.yml b/environment.yml index ca08476..28f7bee 100644 --- a/environment.yml +++ b/environment.yml @@ -8,7 +8,7 @@ dependencies: - gsd >=3.0 - hoomd >=5.0 - mbuild >=1.0 - - numpy >=2.0,<2.3 + - numpy >=2.0 - pip - python >= 3.10,<=3.13 - matplotlib