Skip to content

Commit 3240a31

Browse files
authored
Merge pull request #79 from LOAMRI/issue-70
Issue 70
2 parents 7e9d523 + bf51586 commit 3240a31

3 files changed

Lines changed: 100 additions & 6 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<img src="https://raw.githubusercontent.com/LOAMRI/asltk/refs/heads/develop/docs/assets/asltk-logo.png" width=200>
22

33
[![Documentation Stable](https://readthedocs.org/projects/asltk/badge/?version=main)](https://asltk.readthedocs.io/en/main/?badge=main)
4+
![Website](https://img.shields.io/website?url=https%3A%2F%2Fasltk.readthedocs.io%2Fen%2Fmain%2F&up_message=asltk%20documentation&link=https%3A%2F%2Fasltk.readthedocs.io%2Fen%2Fmain%2F)
45
[![codecov](https://codecov.io/gh/LOAMRI/asltk/graph/badge.svg?token=1W8GQ7SLU9)](https://codecov.io/gh/LOAMRI/asltk)
56
[![CI_main](https://github.com/LOAMRI/asltk/actions/workflows/ci_main.yaml/badge.svg)](https://github.com/LOAMRI/asltk/actions/workflows/ci_main.yaml)
67
[![CI_develop](https://github.com/LOAMRI/asltk/actions/workflows/ci_develop.yaml/badge.svg)](https://github.com/LOAMRI/asltk/actions/workflows/ci_develop.yaml)
7-
![Python Versions](https://img.shields.io/badge/python-3.9%20|+-blue)
8+
![Python Versions](https://img.shields.io/badge/python-3.10%20|+-blue)
89
[![PyPI downloads](https://img.shields.io/pypi/dm/asltk?label=PyPI%20downloads)](https://pypi.org/project/asltk/)
910
![Contributors](https://img.shields.io/github/contributors/LOAMRI/asltk)
1011
[![GitHub issues](https://img.shields.io/github/issues-raw/LOAMRI/asltk.svg?maxAge=2592000)]()

asltk/data/brain_atlas/__init__.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@ class BrainAtlas:
1313

1414
ATLAS_JSON_PATH = os.path.join(os.path.dirname(__file__))
1515

16-
def __init__(self, atlas_name: str = 'MNI2009'):
16+
def __init__(self, atlas_name: str = 'MNI2009', resolution: str = '1mm'):
1717
"""
1818
Initializes the BrainAtlas class with a specified atlas name.
1919
If no atlas name is provided, it defaults to 'MNI2009'.
2020
2121
Args:
2222
atlas_name (str, optional): The name of the atlas to be used. Defaults to 'MNI2009'.
2323
"""
24+
self._check_resolution_input(resolution)
25+
2426
self._chosen_atlas = None
27+
self._resolution = resolution
28+
2529
self.set_atlas(atlas_name)
2630

2731
def set_atlas(self, atlas_name: str):
@@ -61,6 +65,7 @@ def set_atlas(self, atlas_name: str):
6165
# Assuming the atlas_data is a dictionary, we can add the path to it
6266
atlas_data['atlas_file_location'] = path
6367
# Assuming the atlas data contains a key for T1-weighted and Label image data
68+
atlas_data['resolution'] = self._resolution
6469
atlas_data['t1_data'] = os.path.join(path, self._collect_t1(path))
6570
atlas_data['label_data'] = os.path.join(
6671
path, self._collect_label(path)
@@ -77,6 +82,13 @@ def get_atlas(self):
7782
"""
7883
return self._chosen_atlas
7984

85+
def set_resolution(self, resolution: str):
86+
self._check_resolution_input(resolution)
87+
self._resolution = resolution
88+
89+
def get_resolution(self):
90+
return self._resolution
91+
8092
def get_atlas_url(self, atlas_name: str):
8193
"""
8294
Get the brain atlas URL of the chosen format in the ASLtk database.
@@ -145,10 +157,13 @@ def _collect_t1(self, path: str): # pragma: no cover
145157
Returns:
146158
str: The filename of the T1-weighted image data.
147159
"""
148-
t1_file = next((f for f in os.listdir(path) if '_t1' in f), None)
160+
t1_file = next(
161+
(f for f in os.listdir(path) if self._resolution + '_t1' in f),
162+
None,
163+
)
149164
if t1_file is None:
150165
raise ValueError(
151-
f"No file with '_t1' found in the atlas directory: {path}"
166+
f"No file with '_t1_' and resolution {self._resolution} found in the atlas directory: {path}"
152167
)
153168

154169
return t1_file
@@ -161,10 +176,20 @@ def _collect_label(self, path: str): # pragma: no cover
161176
Returns:
162177
str: The filename of the label file.
163178
"""
164-
label_file = next((f for f in os.listdir(path) if '_label' in f), None)
179+
label_file = next(
180+
(f for f in os.listdir(path) if self._resolution + '_label' in f),
181+
None,
182+
)
165183
if label_file is None:
166184
raise ValueError(
167-
f"No file with '_label' found in the atlas directory: {path}"
185+
f"No file with '_label' and resolution {self._resolution} found in the atlas directory: {path}"
168186
)
169187

170188
return label_file
189+
190+
def _check_resolution_input(self, resolution):
191+
valid_resolutions = ['1mm', '2mm']
192+
if resolution not in valid_resolutions:
193+
raise ValueError(
194+
f"Invalid resolution '{resolution}'. Valid options are: {valid_resolutions}"
195+
)

tests/data/brain_atlas/test_brain_atlas.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,56 @@ def test_brain_atlas_creation_with_various_names(atlas_name):
122122
assert isinstance(atlas.get_atlas(), dict)
123123

124124

125+
@pytest.mark.parametrize(
126+
'atlas_name',
127+
[
128+
'MNI2009',
129+
'AAL32024',
130+
'HOCSA2006',
131+
'AAT2022',
132+
'AICHA2021',
133+
'DKA2006',
134+
'FCA7N2011',
135+
'HA2003',
136+
'JHA2005',
137+
'LGPHCC2022',
138+
'AAT2022',
139+
],
140+
)
141+
def test_brain_atlas_creation_with_various_names_2mm_resolution(atlas_name):
142+
"""
143+
Test creating BrainAtlas objects with different valid atlas names.
144+
"""
145+
atlas = BrainAtlas(atlas_name=atlas_name, resolution='2mm')
146+
assert isinstance(atlas.get_atlas(), dict)
147+
148+
149+
@pytest.mark.parametrize(
150+
'wrong_resolution',
151+
[
152+
('1'),
153+
('2'),
154+
('3mm'),
155+
('1.5mm'),
156+
('4mm'),
157+
('1x1x1'),
158+
('2x2x2'),
159+
(1),
160+
(2),
161+
],
162+
)
163+
def test_brain_atlas_constructor_raise_error_wrong_resolution(
164+
wrong_resolution,
165+
):
166+
"""
167+
Test that the BrainAtlas constructor raises an error for invalid resolution.
168+
"""
169+
with pytest.raises(ValueError) as e:
170+
BrainAtlas(resolution=wrong_resolution)
171+
172+
assert 'Invalid resolution' in str(e.value)
173+
174+
125175
def test_atlas_download_failure(mocker):
126176
"""
127177
Test that appropriate error is raised when atlas download fails.
@@ -159,3 +209,21 @@ def test_atlas_url_raises_error_when_atlas_not_set():
159209

160210
# Verify the error message
161211
assert 'is not set or does not have a dataset URL' in str(e.value)
212+
213+
214+
def test_brain_atlas_get_resolution():
215+
"""
216+
Test the get_resolution method of the BrainAtlas class.
217+
"""
218+
atlas = BrainAtlas()
219+
atlas.set_resolution('2mm')
220+
assert atlas.get_resolution() == '2mm'
221+
222+
223+
def test_brain_atlas_set_resolution():
224+
"""
225+
Test the set_resolution method of the BrainAtlas class.
226+
"""
227+
atlas = BrainAtlas()
228+
atlas.set_resolution('2mm')
229+
assert atlas.get_resolution() == '2mm'

0 commit comments

Comments
 (0)