diff --git a/conftest.py b/conftest.py index fa2afb0..6ad838c 100644 --- a/conftest.py +++ b/conftest.py @@ -11,6 +11,12 @@ set_input_validator(True) from fileformats.medimage.dicom import DicomDir +try: + import pydra.tasks.mrtrix3.v3_0 +except ImportError: + OLD_MRTRIX_VERSION = True +else: + OLD_MRTRIX_VERSION = False # Set DEBUG logging for unittests diff --git a/extras/fileformats/extras/medimage/dicom.py b/extras/fileformats/extras/medimage/dicom.py index 2bc3055..108404e 100644 --- a/extras/fileformats/extras/medimage/dicom.py +++ b/extras/fileformats/extras/medimage/dicom.py @@ -5,7 +5,7 @@ import pydicom import numpy as np from fileformats.core import FileSet -from fileformats.core.utils import gen_filename +from fileformats.core.utils import SampleFileGenerator from fileformats.medimage import MedicalImage, DicomCollection, DicomDir, DicomSeries import medimages4tests.dummy.dicom.mri.t1w.siemens.skyra.syngo_d13c @@ -42,15 +42,13 @@ def dicom_series_number(collection: DicomCollection) -> str: @FileSet.generate_sample_data.register -def dicom_dir_generate_sample_data(dcmdir: DicomDir, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None) -> ty.Iterable[Path]: +def dicom_dir_generate_sample_data( + dcmdir: DicomDir, + generator: SampleFileGenerator, +) -> ty.Iterable[Path]: dcm_dir = medimages4tests.dummy.dicom.mri.t1w.siemens.skyra.syngo_d13c.get_image() - # Set series number to random value to make it different - if isinstance(seed, Random): - rng = seed - else: - rng = Random(seed) - series_number = rng.randint(1, SERIES_NUMBER_RANGE) - dest = Path(dest_dir) / gen_filename(seed_or_rng=seed, stem=stem) + series_number = generator.rng.randint(1, SERIES_NUMBER_RANGE) + dest = generator.generate_fspath(DicomDir) dest.mkdir() for dcm_file in dcm_dir.iterdir(): dcm = pydicom.dcmread(dcm_file) @@ -60,13 +58,16 @@ def dicom_dir_generate_sample_data(dcmdir: DicomDir, dest_dir: Path, seed: ty.Un @FileSet.generate_sample_data.register -def dicom_series_generate_sample_data(dcm_series: DicomSeries, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None) -> ty.Iterable[Path]: - rng = Random(seed) - dicom_dir = dicom_dir_generate_sample_data(dcm_series, dest_dir=mkdtemp(), seed=rng, stem=None)[0] - stem = gen_filename(rng, stem=stem) +def dicom_series_generate_sample_data( + dcm_series: DicomSeries, + generator: SampleFileGenerator, +) -> ty.Iterable[Path]: + dicom_dir: Path = dicom_dir_generate_sample_data(dcm_series, generator=generator)[0] + stem = generator.generate_fspath().stem fspaths = [] for i, dicom_file in enumerate(dicom_dir.iterdir(), start=1): - fspaths.append(dicom_file.rename(dest_dir / f"{stem}-{i}.dcm")) + fspaths.append(dicom_file.rename(generator.dest_dir / f"{stem}-{i}.dcm")) + dicom_dir.rmdir() return fspaths diff --git a/extras/fileformats/extras/medimage/nifti.py b/extras/fileformats/extras/medimage/nifti.py index bb40982..433b296 100644 --- a/extras/fileformats/extras/medimage/nifti.py +++ b/extras/fileformats/extras/medimage/nifti.py @@ -4,7 +4,7 @@ import nibabel import numpy as np from fileformats.core import FileSet -from fileformats.core.utils import gen_filename +from fileformats.core.utils import SampleFileGenerator from fileformats.medimage import MedicalImage, Nifti, NiftiGz, Nifti1, NiftiGzX, NiftiX import medimages4tests.dummy.nifti @@ -33,33 +33,37 @@ def nifti_dims(nifti: Nifti) -> ty.Tuple[int, int, int]: @FileSet.generate_sample_data.register def nifti_generate_sample_data( - nifti: Nifti1, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None + nifti: Nifti1, + generator: SampleFileGenerator, ) -> ty.Iterable[Path]: return medimages4tests.dummy.nifti.get_image( - out_file=dest_dir / gen_filename(seed, file_type=Nifti1, stem=stem) + out_file=generator.generate_fspath(file_type=Nifti1) ) @FileSet.generate_sample_data.register def nifti_gz_generate_sample_data( - nifti: NiftiGz, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None + nifti: NiftiGz, + generator: SampleFileGenerator, ) -> ty.Iterable[Path]: return medimages4tests.dummy.nifti.get_image( - out_file=dest_dir / gen_filename(seed, file_type=NiftiGz, stem=stem), + out_file=generator.generate_fspath(file_type=NiftiGz), compressed=True, ) @FileSet.generate_sample_data.register def nifti_gz_x_generate_sample_data( - nifti: NiftiGzX, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None + nifti: NiftiGzX, + generator: SampleFileGenerator, ) -> ty.Iterable[Path]: - return medimages4tests.mri.neuro.t1w.get_image() + return medimages4tests.mri.neuro.t1w.get_image(out_dir=generator.dest_dir) @FileSet.generate_sample_data.register def nifti_x_generate_sample_data( - nifti: NiftiX, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None + nifti: NiftiX, + generator: SampleFileGenerator, ) -> ty.Iterable[Path]: - nifti_gz_x = NiftiGzX(medimages4tests.mri.neuro.t1w.get_image()) + nifti_gz_x = NiftiGzX(medimages4tests.mri.neuro.t1w.get_image(out_dir=generator.dest_dir)) return NiftiX.convert(nifti_gz_x) diff --git a/extras/fileformats/extras/medimage/tests/test_dicom_metadata.py b/extras/fileformats/extras/medimage/tests/test_dicom_metadata.py index 538f5d4..25c306e 100644 --- a/extras/fileformats/extras/medimage/tests/test_dicom_metadata.py +++ b/extras/fileformats/extras/medimage/tests/test_dicom_metadata.py @@ -1,19 +1,23 @@ +import pytest from fileformats.medimage import DicomSeries, DicomDir +from conftest import OLD_MRTRIX_VERSION +@pytest.mark.xfail(condition=OLD_MRTRIX_VERSION, reason="Old MRtrix version") def test_dicom_series_metadata(tmp_path): series = DicomSeries.sample(tmp_path) # Check series number is not a list - assert not isinstance(series["SeriesNumber"], list) + assert not isinstance(series.metadata["SeriesNumber"], list) # check the SOP Instance ID has been converted into a list - assert isinstance(series["SOPInstanceUID"], list) + assert isinstance(series.metadata["SOPInstanceUID"], list) +@pytest.mark.xfail(condition=OLD_MRTRIX_VERSION, reason="Old MRtrix version") def test_dicom_dir_metadata(tmp_path): series = DicomDir.sample(tmp_path) # Check series number is not a list - assert not isinstance(series["SeriesNumber"], list) + assert not isinstance(series.metadata["SeriesNumber"], list) # check the SOP Instance ID has been converted into a list - assert isinstance(series["SOPInstanceUID"], list) + assert isinstance(series.metadata["SOPInstanceUID"], list) diff --git a/extras/fileformats/extras/medimage/tests/test_neuro_converters.py b/extras/fileformats/extras/medimage/tests/test_neuro_converters.py index 862f8f2..cc4d3ca 100644 --- a/extras/fileformats/extras/medimage/tests/test_neuro_converters.py +++ b/extras/fileformats/extras/medimage/tests/test_neuro_converters.py @@ -2,10 +2,10 @@ from fileformats.medimage import ( NiftiGzX, NiftiGzXBvec, - NiftiBvec, Analyze, ) from logging import getLogger +from conftest import OLD_MRTRIX_VERSION logger = getLogger("fileformats") @@ -27,6 +27,7 @@ def test_dicom_to_nifti_select_echo(dummy_magfmap_dicom): assert nifti_gz_x_e2.metadata["EchoNumber"] == 2 +@pytest.mark.xfail(condition=OLD_MRTRIX_VERSION, reason="Old MRtrix version") def test_dicom_to_nifti_select_suffix(dummy_mixedfmap_dicom): nifti_gz_x_ph = NiftiGzX.convert(dummy_mixedfmap_dicom, file_postfix="_ph") @@ -42,6 +43,7 @@ def test_dicom_to_nifti_select_suffix(dummy_mixedfmap_dicom): assert list(nifti_gz_x_real.dims()) == [256, 256, 60] +@pytest.mark.xfail(condition=OLD_MRTRIX_VERSION, reason="Old MRtrix version") def test_dicom_to_nifti_with_extract_volume(dummy_dwi_dicom): nifti_gz_x_e1 = NiftiGzX.convert(dummy_dwi_dicom, extract_volume=30) @@ -57,6 +59,7 @@ def test_dicom_to_nifti_with_jq_edit(dummy_t1w_dicom): assert nifti_gz_x.metadata["EchoTime"] == 2.07 +@pytest.mark.xfail(condition=OLD_MRTRIX_VERSION, reason="Old MRtrix version") def test_dicom_to_niftix_with_fslgrad(dummy_dwi_dicom): logger.debug("Performing FSL grad conversion") @@ -74,12 +77,13 @@ def test_dicom_to_niftix_with_fslgrad(dummy_dwi_dicom): assert all(abs(1 - m) < 1e5 for m in bvec_mags) -# @pytest.mark.skip("Mrtrix isn't installed in test environment yet") +@pytest.mark.xfail(condition=OLD_MRTRIX_VERSION, reason="Old MRtrix version") def test_dicom_to_nifti_as_4d(dummy_t1w_dicom): nifti_gz_x_e1 = NiftiGzX.convert(dummy_t1w_dicom, to_4d=True) assert nifti_gz_x_e1.metadata["dim"][0] == 4 +@pytest.mark.xfail(condition=OLD_MRTRIX_VERSION, reason="Old MRtrix version") def test_dicom_to_analyze(dummy_t1w_dicom): Analyze.convert(dummy_t1w_dicom) diff --git a/fileformats/medimage/dicom.py b/fileformats/medimage/dicom.py index 8c465cf..28698e9 100644 --- a/fileformats/medimage/dicom.py +++ b/fileformats/medimage/dicom.py @@ -67,7 +67,7 @@ def from_paths( for dicom in dicoms: dicom.select_metadata(selected_keys) series_dict[ - (str(dicom["StudyInstanceUID"]), str(dicom["SeriesNumber"])) + (str(dicom.metadata["StudyInstanceUID"]), str(dicom.metadata["SeriesNumber"])) ].append(dicom) return set([cls(s) for s in series_dict.values()]), remaining diff --git a/fileformats/medimage/tests/test_dicom.py b/fileformats/medimage/tests/test_dicom.py index 15f197e..de721f9 100644 --- a/fileformats/medimage/tests/test_dicom.py +++ b/fileformats/medimage/tests/test_dicom.py @@ -34,6 +34,6 @@ def test_dicom_series_metadata(tmp_path): series = DicomSeries.sample(tmp_path) # Check series number is not a list - assert not isinstance(series["SeriesNumber"], list) + assert not isinstance(series.metadata["SeriesNumber"], list) # check the SOP Instance ID has been converted into a list - assert isinstance(series["SOPInstanceUID"], list) + assert isinstance(series.metadata["SOPInstanceUID"], list)