From 108c8b122f01c644d25740549df320ce06d2fd51 Mon Sep 17 00:00:00 2001 From: Ebrahim Ebrahim Date: Fri, 2 Aug 2024 12:34:22 -0400 Subject: [PATCH] Implement bval and bvec in-memory resources (#35) --- src/abcdmicro/resource.py | 38 ++++++++++++++++++++---- tests/test_event.py | 15 ++++++++++ tests/test_resource.py | 62 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 tests/test_event.py create mode 100644 tests/test_resource.py diff --git a/src/abcdmicro/resource.py b/src/abcdmicro/resource.py index f5b5258..ec972f5 100644 --- a/src/abcdmicro/resource.py +++ b/src/abcdmicro/resource.py @@ -1,15 +1,21 @@ from __future__ import annotations +from abc import ABC, abstractmethod +from dataclasses import dataclass -class Resource: - """Base class for resources.""" +import numpy as np +from numpy.typing import NDArray -class VolumeResource(Resource): +class VolumeResource(ABC): """Base class for resources representing a volume or volume stack. An n-D array where n >= 3 and where three of the dimensions are spatial and have associated header information describing a patient coordinate system.""" + @abstractmethod + def get_array(self) -> NDArray[np.floating]: + """Get the underlying volume data array""" + class InMemoryVolumeResource(VolumeResource): """A volume resource that is loaded into memory. @@ -17,19 +23,41 @@ class InMemoryVolumeResource(VolumeResource): and have associated header information describing a patient coordinate system.""" -class BvalResource(Resource): +class BvalResource(ABC): """Base class for resources representing a list of b-values associated with a 4D DWI volume stack.""" + @abstractmethod + def get(self) -> NDArray[np.floating]: + """Get the underlying array of b-values""" + +@dataclass class InMemoryBvalResource(BvalResource): """A b-value list that is loaded into memory.""" + array: NDArray[np.floating] + """The underlying array of b-values""" + + def get(self) -> NDArray[np.floating]: + return self.array + -class BvecResource(Resource): +class BvecResource(ABC): """Base class for resources representing a list of b-vectors associated with a 4D DWI volume stack.""" + @abstractmethod + def get(self) -> NDArray[np.floating]: + """Get the underlying array of b-vectors""" + +@dataclass class InMemoryBvecResource(BvecResource): """A b-vector list that is loaded into memory.""" + + array: NDArray[np.floating] + """The underlying array of b-vectors""" + + def get(self) -> NDArray[np.floating]: + return self.array diff --git a/tests/test_event.py b/tests/test_event.py new file mode 100644 index 0000000..1c75066 --- /dev/null +++ b/tests/test_event.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +from pathlib import Path + +from abcdmicro.event import AbcdEvent + + +def test_create_event(): + AbcdEvent( + subject_id="NDAR_INV00U4FTRU", + eventname="baseline_year_1_arm_1", + image_download_path=Path("/this/is/a/path/for/images"), + tabular_data_path=Path("/this/is/a/path/for/tables"), + abcd_version="5.1", + ) diff --git a/tests/test_resource.py b/tests/test_resource.py new file mode 100644 index 0000000..04c2c87 --- /dev/null +++ b/tests/test_resource.py @@ -0,0 +1,62 @@ +from __future__ import annotations + +import numpy as np +import pytest + +from abcdmicro.resource import ( + BvalResource, + BvecResource, + InMemoryBvalResource, + InMemoryBvecResource, + VolumeResource, +) + + +def test_bval_abstractness(): + with pytest.raises(TypeError): + BvalResource() # type: ignore[abstract] + + +def test_bvec_abstractness(): + with pytest.raises(TypeError): + BvecResource() # type: ignore[abstract] + + +def test_volume_abstractness(): + with pytest.raises(TypeError): + VolumeResource() # type: ignore[abstract] + + +@pytest.fixture() +def bval_array(): + return np.array([500.0, 1000.0, 200.0]) + + +@pytest.fixture() +def bvec_array(): + return np.array( + [ + [ + 1.0, + 1.0, + 1.0, + ], + [2.0, 0.0, -4.0], + ] + ) + + +@pytest.fixture() +def volume_array(): + rng = np.random.default_rng(1337) + return rng.random(size=(3, 4, 5, 6), dtype=float) + + +def test_bval_inmemory_get(bval_array): + bval = InMemoryBvalResource(array=bval_array) + assert (bval.get() == bval_array).all() + + +def test_bvec_inmemory_get(bvec_array): + bvec = InMemoryBvecResource(array=bvec_array) + assert (bvec.get() == bvec_array).all()