Skip to content

Commit 9a0d69d

Browse files
committed
rip out async/threading and replace with mmap
1 parent f8f26ee commit 9a0d69d

1 file changed

Lines changed: 28 additions & 28 deletions

File tree

src/aspire/source/relion.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import logging
22
import os.path
3-
from concurrent import futures
4-
from multiprocessing import cpu_count
53

64
import mrcfile
75
import numpy as np
@@ -246,44 +244,46 @@ def _images(self, indices):
246244
# Log the indices in case needed to debug a crash
247245
logger.debug(f"Indices: {indices}")
248246

249-
def load_single_mrcs(filepath, indices):
250-
arr = mrcfile.open(filepath, mode="r", permissive=True).data
251-
# if the stack only contains one image, arr will have shape (resolution, resolution)
252-
# the code below reshapes it to (1, resolution, resolution)
253-
if len(arr.shape) == 2:
254-
arr = arr.reshape((1,) + arr.shape)
247+
def _load_single_mrcs(filepath, indices):
248+
"""
249+
Local utility to wrap up loading a slice of MRC data.
250+
251+
:param filepath: String filepath to MRC file.
252+
:param indices: Requested indices from STAR file.
253+
:return: Slice of array data (as mmap).
254+
"""
255255
# __mrc_index is the 1-based index of the particle in the stack
256-
data = arr[self._metadata["__mrc_index"][indices] - 1, :, :]
256+
mrc_indices = self._metadata["__mrc_index"][indices] - 1
257257

258-
return indices, data
258+
with mrcfile.mmap(filepath, mode="r", permissive=True) as fh:
259+
arr = fh.data
260+
# if the stack only contains one image, arr will have shape (resolution, resolution)
261+
# the code below reshapes it to (1, resolution, resolution)
262+
if len(arr.shape) == 2:
263+
arr = arr.reshape((1,) + arr.shape)
264+
data = arr[mrc_indices, :, :]
259265

260-
n_workers = self.n_workers
261-
if n_workers < 0:
262-
n_workers = cpu_count() - 1
266+
return data
263267

268+
# Array to hold requested data
264269
im = np.empty(
265270
(len(indices), self._original_resolution, self._original_resolution),
266271
dtype=self.dtype,
267272
)
268273

269-
filepaths, filepath_indices = np.unique(
274+
# Map all requested indices to a set of files and images per file.
275+
requested_filepaths, requested_filepath_indices = np.unique(
270276
self._metadata["__mrc_filepath"], return_inverse=True
271277
)
272-
n_workers = min(n_workers, len(filepaths))
273-
274-
with futures.ThreadPoolExecutor(n_workers) as executor:
275-
to_do = []
276-
for i, filepath in enumerate(filepaths):
277-
this_filepath_indices = np.where(filepath_indices == i)[0]
278-
future = executor.submit(
279-
load_single_mrcs, filepath, this_filepath_indices
280-
)
281-
to_do.append(future)
282278

283-
for future in futures.as_completed(to_do):
284-
data_indices, data = future.result()
285-
for idx, d in enumerate(data_indices):
286-
im[np.where(indices == d)] = data[idx, :, :]
279+
# Loop over the requested files and load (slice) the requested images per file.
280+
for _i, _filepath in enumerate(requested_filepaths):
281+
_filepath_indices = np.where(requested_filepath_indices == _i)[0]
282+
_data = _load_single_mrcs(_filepath, _filepath_indices)
283+
284+
# Pack this files data contribution into `im` array.
285+
for idx, d in enumerate(_filepath_indices):
286+
im[np.where(indices == d)] = _data[idx, :, :]
287287

288288
logger.debug(f"Loading {len(indices)} images complete")
289289

0 commit comments

Comments
 (0)