Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
bdf183f
stash1 all tests still passing
garrettwrong Sep 15, 2026
db5f5a2
remedy bot_align
garrettwrong Sep 15, 2026
a86cacd
remedy cov3d tutorial
garrettwrong Sep 15, 2026
69fd80e
remediate test files
garrettwrong Sep 15, 2026
3f56385
cleanup
garrettwrong Sep 15, 2026
bd2b88e
remedy micrograph sim
garrettwrong Sep 15, 2026
7dc2627
remedy cl cn
garrettwrong Sep 15, 2026
d051b82
minor tol adjustment
garrettwrong Sep 18, 2026
09f6f1e
minor tol adjustment preproc
garrettwrong Sep 18, 2026
26ba5fd
progress
garrettwrong Sep 18, 2026
7832b85
Better handle and log seed init
garrettwrong Sep 21, 2026
0b5e88e
pin denoiser utest seed similar to old sim
garrettwrong Sep 21, 2026
7d32e0c
add very basic sim seeding unit test
garrettwrong Sep 21, 2026
a070aa4
seed frc/fsc test sims
garrettwrong Sep 21, 2026
2c57af3
complete deprecation of randi method
garrettwrong Sep 21, 2026
eb67e97
all randn methods except legacy hardcoded
garrettwrong Sep 21, 2026
22a63b7
resolve choice
garrettwrong Sep 21, 2026
dc62d87
remove Random from random package exports
garrettwrong Sep 21, 2026
5ae1d99
resolve random
garrettwrong Sep 22, 2026
de1b286
continue choice cleanup
garrettwrong Sep 22, 2026
c19b3f5
add missing seed in sim for shift case
garrettwrong Sep 22, 2026
905e51e
add reminder note to NoiseAdder
garrettwrong Sep 22, 2026
b46fbcd
Resolve test_orient_sdp failures. Add missing fixture dtype. Adjust s…
j-c-c Sep 22, 2026
8ff5877
Resolve test_orient_lud.py failures. Adjust shift_step resolution. Ad…
j-c-c Sep 22, 2026
0fe65ca
Resolve test_orient_irls.py failures. Adjust spectral norm constraint…
j-c-c Sep 22, 2026
1a21e7c
Resolve test_orient_symmetric.py failures. Loosen tolerances for esti…
j-c-c Sep 23, 2026
bc7c274
Resolve test_synthetic_volume.py failures. Adjust test tolerance.
j-c-c Sep 24, 2026
956ea06
Resolve test_orient_sync_voting.py failures. Increase max_shift. Add …
j-c-c Sep 25, 2026
d7b6d93
Move mean_aligned_shift_error to utils and add a unit test for it.
j-c-c Sep 25, 2026
e06b8f7
Resolve test_rotation.py failure. Replace hardcoded common_lines test…
j-c-c Sep 25, 2026
ab92b4b
Use groud truth rotations to compute aligned shift error.
j-c-c Sep 25, 2026
a56a735
tox
j-c-c Sep 25, 2026
445a921
Resolve remaining test_orient_d.py failures. Disable fuzzy_mask in sc…
j-c-c Sep 25, 2026
1df3c6f
Update to Numpy>=2.2 and update conda envs.
garrettwrong Sep 25, 2026
468614b
stabilize cov3d kmeans calls
garrettwrong Sep 28, 2026
c00f9df
stabilize cov3d kmeans calls some more
garrettwrong Sep 28, 2026
4e4529a
Resolve test_oriented_source.py sporadic failures. Set Simulation see…
j-c-c Sep 28, 2026
baac57f
Resolve test_oriented_source.py sporadic failures. Set JSync epsilon …
j-c-c Sep 28, 2026
187a3bf
Resolve another test_oriented_source failure. C3/C4 algorithms create…
j-c-c Sep 28, 2026
aafb407
Resolve test_oriented_source.py save-roundtrip failure. Failure was d…
j-c-c Sep 29, 2026
07d5fa8
stabilize the noise tests by adding more images
garrettwrong Sep 29, 2026
cc16936
migrate src code from seed to rng
garrettwrong Oct 1, 2026
06db7f3
migrate test code from seed to rng
garrettwrong Oct 1, 2026
df90f8e
migrate gallery code from seed to rng
garrettwrong Oct 1, 2026
c708851
fix copy paste error per jcc
garrettwrong Oct 1, 2026
64a2842
update minimal scipy version in conda envs and pyproj
garrettwrong Oct 1, 2026
364dad6
change tolerance per discussion with jcc
garrettwrong Oct 1, 2026
18cfb9f
remove semi-fixed seeds from test_orient_symmetric, replace with top …
garrettwrong Oct 2, 2026
c283830
update min_dist_cls for C2 case per jcc
garrettwrong Oct 5, 2026
de73229
more orient sym test patches per JCC
garrettwrong Oct 8, 2026
702e1e6
patch jcc's patch
garrettwrong Oct 8, 2026
8cc01c2
split off the legacy NoiseAdder
garrettwrong Oct 9, 2026
1f0a6a7
minor tweak denoiser test tol (by 1e-7)
garrettwrong Oct 9, 2026
9bd5cd4
remove seed refereces in gallery
garrettwrong Oct 12, 2026
00d7e46
bump white noise estimate from 1 to 2% for random seeded case
garrettwrong Oct 12, 2026
a5d056a
use emdb volume instead of builtins for fuzzy mask unit test
garrettwrong Oct 13, 2026
16a092a
loosen frc/fsc tols
garrettwrong Oct 13, 2026
06b2491
add docstring for legacy white noise adder
garrettwrong Oct 23, 2026
cec9d3a
try to stablize the preproc tests with a seed
garrettwrong Oct 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions environment-accelerate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ channels:
dependencies:
- pip
- python=3.10
- numpy=1.25.0
- scipy=1.13.1
- numpy=2.2.6
- scipy=1.15.1
- finufft=2.5.0 # must be installed via conda if using (conda) optimized backends
- scikit-learn
- scikit-image
Expand Down
4 changes: 2 additions & 2 deletions environment-default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ channels:
dependencies:
- pip
- python=3.10
- numpy=1.25.0
- scipy=1.13.1
- numpy=2.2.6
- scipy=1.15.1
- scikit-learn
- scikit-image
- finufft=2.5.0 # must be installed via conda if using (conda) optimized backends
4 changes: 2 additions & 2 deletions environment-intel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ channels:
dependencies:
- pip
- python=3.10
- numpy=1.25.0
- scipy=1.13.1
- numpy=2.2.6
- scipy=1.15.1
- scikit-learn
- scikit-image
- mkl_fft
Expand Down
4 changes: 2 additions & 2 deletions environment-openblas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ channels:
dependencies:
- pip
- python=3.10
- numpy=1.25.0
- scipy=1.13.1
- numpy=2.2.6
- scipy=1.15.1
- scikit-learn
- scikit-image
- libblas=*=*openblas
4 changes: 2 additions & 2 deletions environment-win64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ channels:
dependencies:
- pip
- python=3.10
- numpy=1.25.0
- scipy=1.13.1
- numpy=2.2.6
- scipy=1.15.1
- scikit-learn
- scikit-image
- mkl=2024.1.* # possible regression impacts eig solver in later versions up to 2025.0
17 changes: 8 additions & 9 deletions gallery/tutorials/aspire_introduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@
from aspire.utils import Rotation

num_rotations = 2
rots = Rotation.generate_random_rotations(n=num_rotations, seed=12345)
rots = Rotation.generate_random_rotations(n=num_rotations, rng=12345)

# %%
# We can access the Numpy array holding the actual stack of 3x3 matrices:
Expand Down Expand Up @@ -370,20 +370,20 @@

# %%
# Generate a Simulation instance based on the original volume data.
sim = Simulation(n=num_imgs, vols=vol)
sim = Simulation(n=num_imgs, vols=vol, rng=42)
# Display the first 10 images
sim.images[:10].show() # Hi Res

# %%
# Repeat for the lower resolution (downsampled) volume vol_ds.
sim = Simulation(n=num_imgs, vols=vol_ds)
sim = Simulation(n=num_imgs, vols=vol_ds, rng=42)
sim.images[:10].show() # Lo Res

# %%
# Note both of those simulations have the same rotations because they
# had the same seed by default, We recreate ``sim`` with a distinct
# seed to get different random samples (of rotations).
sim = Simulation(n=num_imgs, vols=vol_ds, seed=42)
# had the same RNG seed, We recreate ``sim`` with a random
# seed (default) to get different random samples (of rotations).
sim = Simulation(n=num_imgs, vols=vol_ds)
sim.images[:10].show()

# %%
Expand Down Expand Up @@ -446,8 +446,7 @@
# the projection images with noise. Internally the
# ``WhiteNoiseAdder`` creates a ``ScalarFilter`` which is multiplied
# (convolution) by a Gaussian random sample. Similar to before, if
# you require a different sample, this can be controlled via a
# ``seed``.
# you require a different sample, this can be controlled via ``rng``.

# Creating the new simulation with this additional noise is easy:
sim = Simulation(n=num_imgs, vols=vol_ds, noise_adder=white_noise_adder)
Expand Down Expand Up @@ -584,7 +583,7 @@ def noise_function(x, y):
offsets=0,
noise_adder=white_noise_adder,
filter_stack=ctf_filters,
seed=42,
rng=42,
)

# Simulation has two unique accessors ``clean_images`` which disables
Expand Down
4 changes: 2 additions & 2 deletions gallery/tutorials/tutorials/basic_image_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
noise_var = np.var(img.asnumpy()) * 5

# Then create a WhiteNoiseAdder.
noise = WhiteNoiseAdder(var=noise_var, seed=123)
noise = WhiteNoiseAdder(var=noise_var)

# We can apply the WhiteNoiseAdder to our image data.
img_with_noise = noise.forward(img)
Expand Down Expand Up @@ -95,7 +95,7 @@ def noise_function(x, y):
# We can create a custom filter from that function.
f = FunctionFilter(noise_function)
# And use the filter to add the noise to our stack of images.
noise_adder = CustomNoiseAdder(noise_filter=f, seed=123)
noise_adder = CustomNoiseAdder(noise_filter=f)
imgs_with_noise = noise_adder.forward(imgs)

# Let's see the first two noisy images.
Expand Down
6 changes: 3 additions & 3 deletions gallery/tutorials/tutorials/class_averaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@
# We'll make an example data set by concatentating then shuffling
# these.
example_array = np.concatenate((classRound, classOval, classYOvalL, classYOvalR))
np.random.seed(1234567)
np.random.shuffle(example_array)
rng = np.random.default_rng(1234567)
rng.shuffle(example_array)

# So now that we have cooked up an example dataset, lets create an
# ASPIRE source
Expand Down Expand Up @@ -144,7 +144,7 @@
noise_var = var * 2**4

# Then create noise with the ``WhiteNoiseAdder`` class.
noise = WhiteNoiseAdder(var=noise_var, seed=123)
noise = WhiteNoiseAdder(var=noise_var)

# Add noise to the images by performing ``forward``
noisy_im = noise.forward(src.images[:])
Expand Down
22 changes: 9 additions & 13 deletions gallery/tutorials/tutorials/cov3d_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
from aspire.reconstruction import MeanEstimator
from aspire.source.simulation import Simulation
from aspire.utils import eigs
from aspire.utils.random import Random
from aspire.volume import LegacyVolume, Volume
from aspire.volume import AsymmetricVolume, Volume

# %%
# Create Simulation Object
Expand All @@ -30,22 +29,21 @@
num_eigs = 16 # number of eigen-vectors to keep
dtype = np.float32

# Generate a ``Volume`` object for use in the simulation. Here we use a ``LegacyVolume`` and
# set C = 3 to generate 3 unique random volumes.
vols = LegacyVolume(
L=img_size,
C=3,
dtype=dtype,
pixel_size=10,
# Generate a ``Volume`` object for use in the simulation. Here we use C = 3 to generate 3 unique random volumes.
vols = AsymmetricVolume(
L=img_size, C=3, K=16, dtype=dtype, pixel_size=10, rng=0
).generate()

# Create a simulation object with specified filters
sim = Simulation(
L=img_size,
n=num_imgs,
vols=vols,
amplitudes=1,
offsets=0,
filter_stack=RadialCTFFilter(defocus=np.linspace(1.5e4, 2.5e4, 7)),
dtype=dtype,
rng=0,
)

# The Simulation object was created using 3 volumes.
Expand Down Expand Up @@ -107,10 +105,8 @@
# we expect, so we can use this parameter here. Typically, one would take
# the number of clusters to be one plus the number of eigenvectors extracted.

# Since kmeans2 relies on randomness for initialization, important to push random seed to context manager here.
with Random(0):
centers, vol_idx = kmeans2(coords_est.T, num_vols)
centers = centers.squeeze()
centers, vol_idx = kmeans2(coords_est.T, num_vols, minit="points", rng=0)
centers = centers.squeeze()

# %%
# Performance Evaluation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
angles=rots.angles, # pass our rotations as Euler angles
offsets=shifts, # translations (wrt to origin)
amplitudes=amplitudes, # amplification ( 1 is identity)
seed=12345, # RNG seed for reproducibility
rng=12345, # RNG seed for reproducibility
dtype=v.dtype, # match our datatype to the Volume.
noise_adder=white_noise_adder, # optionally prescribe noise
)
Expand Down
12 changes: 6 additions & 6 deletions gallery/tutorials/tutorials/micrograph_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
# particles_per_micrograph: Optional, int
# particle_amplitudes: Optional, np.ndarray
# projection_angles: Optional, np.ndarray
# seed: Optional, int
# rng: Optional, int
# ctf_filters: Optional, list
# noise_adder: Optional, NoiseAdder
# boundary: Optional, int
Expand Down Expand Up @@ -144,7 +144,7 @@
L=100,
C=1,
pixel_size=4,
seed=1234,
rng=1234,
dtype=np.float32,
).generate()

Expand All @@ -163,7 +163,7 @@
particle_amplitudes=1,
micrograph_size=1024,
micrograph_count=n_micrographs,
seed=1234,
rng=1234,
)

# Plot the micrographs
Expand All @@ -189,7 +189,7 @@
micrograph_size=1024,
micrograph_count=n_micrographs,
ctf_filters=ctfs,
seed=1234,
rng=1234,
)

# Plot the micrographs
Expand All @@ -204,7 +204,7 @@
from aspire.noise import WhiteNoiseAdder

# Create our noise using WhiteNoiseAdder
noise = WhiteNoiseAdder(4e-3, seed=1234)
noise = WhiteNoiseAdder(4e-3)

# Add noise to our MicrographSimulation using the noise_adder argument
src = MicrographSimulation(
Expand All @@ -214,7 +214,7 @@
micrograph_size=1024,
micrograph_count=n_micrographs,
ctf_filters=ctfs,
seed=1234,
rng=1234,
)

# Plot the micrographs
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ dependencies = [
"joblib",
"matplotlib >= 3.2.0",
"mrcfile",
"numpy>=1.25.0",
"numpy>=2.2.0",
"packaging",
"pooch>=1.7.0",
"pillow",
"psutil",
"pymanopt",
"PyWavelets",
"scipy >= 1.10.0",
"scipy >= 1.15.0",
"scikit-learn >= 1.5.0",
"scikit-image",
"setuptools >= 0.41",
Expand Down
10 changes: 5 additions & 5 deletions src/aspire/abinitio/J_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import numpy as np
from numpy.linalg import norm

from aspire.utils import J_conjugate, all_pairs, random, trange
from aspire.utils import J_conjugate, all_pairs, trange

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -35,7 +35,7 @@ def __init__(
n,
epsilon=1e-2,
max_iters=1000,
seed=None,
rng=None,
disable_gpu=False,
J_weighting=False,
):
Expand All @@ -46,12 +46,12 @@ def __init__(
:param n: Number of images/rotations.
:param epsilon: Tolerance for the power method.
:param max_iters: Maximum iterations for the power method.
:param seed: Optional seed for power method initial random vector.
:param rng: Optional RNG or seed for power method initial random vector.
"""
self.n_img = n
self.epsilon = epsilon
self.max_iters = max_iters
self.seed = seed
self.rng = np.random.default_rng(rng)
self.J_weighting = J_weighting

# Generate pair mappings
Expand Down Expand Up @@ -123,7 +123,7 @@ def power_method(self, Rijs):

# Initialize candidate eigenvectors
n_Rijs = Rijs.shape[0]
vec = random(n_Rijs, seed=self.seed)
vec = self.rng.random(n_Rijs)
vec = vec / norm(vec)
residual = 1
itr = 0
Expand Down
6 changes: 4 additions & 2 deletions src/aspire/abinitio/commonline_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
from aspire.image import Image
from aspire.operators import PolarFT
from aspire.utils import Rotation, fuzzy_mask
from aspire.utils.random import choice

from .commonline_utils import _generate_shift_phase_and_filter

Expand All @@ -32,6 +31,7 @@ def __init__(
offsets_max_memory=10000,
offsets_equations_factor=1,
mask=True,
rng=None,
):
"""
Initialize an object for estimating 3D orientations using common lines.
Expand Down Expand Up @@ -70,7 +70,9 @@ def __init__(
references in `estimate_shifts`. Defaults to 10GB.
:param mask: Option to mask `src.images` with a fuzzy mask (boolean).
Default, `True`, applies a mask.
:param rng: Optional RNG or seed.
"""
self.rng = np.random.default_rng(rng)
self.src = src
# Note dtype is inferred from self.src
self.dtype = self.src.dtype
Expand Down Expand Up @@ -431,7 +433,7 @@ def _generate_index_pairs(self, n_equations):
idx_i, idx_j = np.triu_indices(self.n_img, k=1)

# Select random pairs based on the size of n_equations
rp = choice(np.arange(len(idx_j)), size=n_equations, replace=False)
rp = self.rng.choice(np.arange(len(idx_j)), size=n_equations, replace=False)

return idx_i[rp], idx_j[rp]

Expand Down
8 changes: 4 additions & 4 deletions src/aspire/abinitio/commonline_c2.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def __init__(
epsilon=1e-3,
max_iters=1000,
min_dist_cls=25,
seed=None,
rng=None,
mask=True,
J_weighting=False,
disable_gpu=False,
Expand All @@ -65,7 +65,7 @@ def __init__(
:param epsilon: Tolerance for the power method.
:param max_iters: Maximum iterations for the power method.
:param min_dist_cls: Minimum distance between mutual common-lines. Default = 25 degrees.
:param seed: Optional seed for RNG.
:param rng: Optional RNG or seed.
:param mask: Option to mask `src.images` with a fuzzy mask (boolean).
Default, `True`, applies a mask.
:param J_weighting: Optionally use `J` weights instead of
Expand All @@ -83,21 +83,21 @@ def __init__(
shift_step=shift_step,
mask=mask,
disable_gpu=disable_gpu,
rng=rng,
**kwargs,
)

self.min_dist_cls = min_dist_cls
self.epsilon = epsilon
self.max_iters = max_iters
self.seed = seed
self.order = 2

# Setup J-synchronization
self.J_sync = JSync(
src.n,
epsilon=self.epsilon,
max_iters=self.max_iters,
seed=self.seed,
rng=self.rng,
disable_gpu=disable_gpu,
J_weighting=J_weighting,
)
Expand Down
Loading