Skip to content
39 changes: 39 additions & 0 deletions DEV_NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Development Notes

Setup friction encountered on this fork during GPU development — kept
here separately so the main README stays clean. Not universal microsim
guidance, just what was hit on this machine.

## GPU backend (cupy) setup

1. **numpy version conflict** — microsim's metadata pins `numpy<2.0`, but
`cupy-cuda12x` requires `numpy>=2.0`. In practice, numpy 2.4.6 worked
fine at runtime with this version of microsim despite the metadata
warning — if `pip` flags the conflict, it's likely safe to ignore,
but verify by running a real simulation before trusting it.

2. **CUDA headers not found** (`RuntimeError: Failed to find CUDA headers`)
— if your system has multiple CUDA toolkit installs (common after
driver updates over time), cupy's JIT compiler may not find headers
even with `CUDA_PATH` set correctly. Installing the toolkit extra
directly into the venv sidesteps the problem:
```bash
pip install "cupy-cuda12x[ctk]"
```

3. **zarr / numcodecs mismatch** (`ImportError: cannot import name
'cbuffer_sizes' from 'numcodecs.blosc'`) — zarr 2.17.x expects an
older numcodecs API:
```bash
pip install "numcodecs<0.13"
```

4. **COSEM data fetching** — loading real segmentation data (e.g. the
`cosem` example) requires the optional extra:
```bash
pip install "microsim[cosem]"
```

None of these are bugs in microsim itself, except where already filed
as upstream PRs (#140, #141) — mostly environment/dependency friction
from multiple existing CUDA/Python installs on a dev machine.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ These are not installed by default, see the
or [cupy](https://docs.cupy.dev/en/stable/install.html) installation instructions,
paying attention to your GPU requirements. Support for torch is planned.

See [DEV_NOTES.md](DEV_NOTES.md) for real setup issues hit on this fork
(numpy/cupy version conflicts, CUDA header errors, zarr/numcodecs mismatch).

## Usage

Construct and run a
Expand Down
9 changes: 6 additions & 3 deletions src/microsim/schema/modality/_simple_psf.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,19 @@ def render(
self,
truth: xrDataArray, # (F, Z, Y, X)
em_rates: xrDataArray, # (C, F, W)
*args: Any,
**kwargs: Any,
objective_lens: ObjectiveLens,
settings: Settings,
xp: NumpyAPI,
) -> xrDataArray:
"""Render a 3D image of the truth for F fluorophores, in C channels.

In this case we don't apply the PSF convolution, as the truth is assumed to be
already convolved with the PSF. Therefore, we simply compute the emission flux
for each fluorophore and each channel.
"""
em_image = em_rates.sum(Axis.W) * truth
em_rates = em_rates.sum(Axis.W)
em_rates = em_rates.copy(data=xp.asarray(em_rates.data))
em_image = em_rates * truth
return DataArray(
em_image,
dims=[Axis.C, Axis.F, Axis.Z, Axis.Y, Axis.X],
Expand Down
14 changes: 14 additions & 0 deletions tests/test_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,17 @@ def test_simulation_write_from_ground_truth(tmp_path: Path) -> None:
)
sim.run()
assert (tmp_path / "output.zarr").exists()


def test_identity_modality_backend_conversion(np_backend: ms.BackendName) -> None:
"""Regression test for #124: em_rates must be converted to the active
backend before use in Identity.render(), same as truth already is."""
sim = ms.Simulation(
truth_space=ms.ShapeScaleSpace(shape=(8, 32, 32), scale=(0.2, 0.1, 0.1)),
output_space={"downscale": 1},
sample=ms.Sample(labels=[MATSLINES]),
modality=ms.Identity(),
settings=ms.Settings(np_backend=np_backend),
)
result = sim.optical_image()
assert result.shape[1:] == sim.truth_space.shape
Loading