Source code for ewokstomo.tests.test_convertvolume

from pathlib import Path
from unittest.mock import patch
import numpy as np
import pytest
from ewokstomo.tasks.convert_volume import ConvertVolumeTo16Bit


[docs] @pytest.fixture def fake_hdf5_volume(tmp_path): vol_dir = tmp_path / "sample_absorption_32Bit_hdf5" vol_dir.mkdir() h5 = vol_dir / "sample.hdf5" h5.write_text("not really hdf5") return h5
[docs] @pytest.fixture def fake_hdf5_volume_no_32bit(tmp_path): vol_dir = tmp_path / "sample_absorption_hdf5" vol_dir.mkdir() h5 = vol_dir / "sample.hdf5" h5.write_text("not really hdf5") return h5
[docs] @pytest.fixture def fake_tiff_volume(tmp_path): vol_dir = tmp_path / "sample_absorption_32Bit_tiff" vol_dir.mkdir() for i in range(3): (vol_dir / f"sample_{i:06d}.tiff").write_text("fake") return vol_dir / "sample"
[docs] @pytest.fixture def fake_tiff_volume_no_32bit(tmp_path): vol_dir = tmp_path / "sample_absorption_tiff" vol_dir.mkdir() for i in range(3): (vol_dir / f"sample_{i:06d}.tiff").write_text("fake") return vol_dir / "sample"
def _make_nabu_dict(fmt): return {"output": {"file_format": fmt}} def _fake_cast_volume_hdf5( input_volume, output_volume, output_data_type, remove_input_volume ): """Simulate cast_volume for HDF5: write a dummy output file.""" out = Path(output_volume.file_path) out.parent.mkdir(parents=True, exist_ok=True) out.write_text("converted") def _fake_cast_volume_tiff( input_volume, output_volume, output_data_type, remove_input_volume ): """Simulate cast_volume for tiff: create a dummy output directory. MultitiffFVolume exposes its directory via the .url attribute. """ folder = Path(output_volume.url.file_path()) folder.mkdir(parents=True, exist_ok=True) (folder / "slice_000000.tiff").write_bytes(b"dummy")
[docs] @patch("ewokstomo.tasks.convert_volume.get_first_hdf5_entry", return_value="/entry") @patch( "ewokstomo.tasks.convert_volume.cast_volume", side_effect=_fake_cast_volume_hdf5, ) def test_convert_volume_hdf5(mock_cast, mock_entry, fake_hdf5_volume): task = ConvertVolumeTo16Bit( inputs={ "reconstructed_volume_path": str(fake_hdf5_volume), "nabu_dict": _make_nabu_dict("hdf5"), "output_format": "hdf5", } ) task.execute() out = Path(task.outputs.converted_volume_path) assert out.exists() assert out.stat().st_size > 0 assert out.suffix == ".hdf5" assert "16Bit" in str(out) mock_cast.assert_called_once() _, kwargs = mock_cast.call_args assert kwargs["output_data_type"] == np.uint16
[docs] @patch("ewokstomo.tasks.convert_volume.get_first_hdf5_entry", return_value="/entry") @patch( "ewokstomo.tasks.convert_volume.cast_volume", side_effect=_fake_cast_volume_hdf5, ) def test_convert_volume_hdf5_no_32bit_warns( mock_cast, mock_entry, fake_hdf5_volume_no_32bit ): """When '32Bit' is absent from the HDF5 path, a warning must be emitted and the output is placed in an '_16Bit' fallback directory.""" with patch("ewokstomo.tasks.convert_volume.logger") as mock_logger: task = ConvertVolumeTo16Bit( inputs={ "reconstructed_volume_path": str(fake_hdf5_volume_no_32bit), "nabu_dict": _make_nabu_dict("hdf5"), "output_format": "hdf5", } ) task.execute() warning_calls = [ call for call in mock_logger.warning.call_args_list if "32Bit" in str(call) and "Falling back" in str(call) ] assert warning_calls, "Expected a warning about missing '32Bit' in path" out = Path(task.outputs.converted_volume_path) assert out.exists() assert out.stat().st_size > 0 assert out.suffix == ".hdf5" assert str(out.parent).endswith("_16Bit"), ( f"Expected fallback '_16Bit' directory, got: {out.parent}" )
[docs] @patch( "ewokstomo.tasks.convert_volume.cast_volume", side_effect=_fake_cast_volume_tiff, ) def test_convert_volume_tiff(mock_cast, fake_tiff_volume): task = ConvertVolumeTo16Bit( inputs={ "reconstructed_volume_path": str(fake_tiff_volume), "nabu_dict": _make_nabu_dict("tiff"), } ) task.execute() out = Path(task.outputs.converted_volume_path) assert "16Bit" in str(out) assert "sample_absorption_16Bit_tiff" == str(out.parent.stem) assert out.parent.exists() assert any(out.parent.iterdir()) mock_cast.assert_called_once() _, kwargs = mock_cast.call_args assert kwargs["output_data_type"] == np.uint16
[docs] @patch( "ewokstomo.tasks.convert_volume.cast_volume", side_effect=_fake_cast_volume_tiff, ) def test_convert_volume_tiff_no_32bit_warns(mock_cast, fake_tiff_volume_no_32bit): """When '32Bit' is absent from the tiff path, a warning must be emitted and the output is placed in an '_16Bit' fallback directory.""" with patch("ewokstomo.tasks.convert_volume.logger") as mock_logger: task = ConvertVolumeTo16Bit( inputs={ "reconstructed_volume_path": str(fake_tiff_volume_no_32bit), "nabu_dict": _make_nabu_dict("tiff"), } ) task.execute() warning_calls = [ call for call in mock_logger.warning.call_args_list if "32Bit" in str(call) and "Falling back" in str(call) ] assert warning_calls, "Expected a warning about missing '32Bit' in path" out = Path(task.outputs.converted_volume_path) assert "16Bit" in str(out) assert str(out.parent).endswith("_16Bit"), ( f"Expected fallback '_16Bit' directory, got: {out.parent}" ) assert out.parent.exists() assert any(out.parent.iterdir()) mock_cast.assert_called_once()