Skip to content

Commit b838dbb

Browse files
authored
[ENH] convert sample sizes (#919)
* allow for sample sizes to be converted * formatting * add more tests
1 parent 895c154 commit b838dbb

File tree

2 files changed

+91
-5
lines changed

2 files changed

+91
-5
lines changed

nimare/io.py

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,45 @@ def _analysis_to_dict(study, analysis):
6262
"z": [p.z for p in analysis.points] or [None],
6363
},
6464
}
65-
sample_size = study.metadata.get("sample_size")
66-
if sample_size:
67-
result["metadata"]["sample_sizes"] = [sample_size]
65+
66+
sample_sizes = analysis.metadata.get("sample_sizes")
67+
sample_size = None
68+
69+
# Validate sample sizes if present
70+
if sample_sizes is not None and not isinstance(sample_sizes, (list, tuple)):
71+
raise TypeError(
72+
f"Expected sample_sizes to be list or tuple, but got {type(sample_sizes)}"
73+
)
74+
75+
if not sample_sizes:
76+
# Try to get single sample size from analysis or study metadata
77+
sample_size = analysis.metadata.get("sample_size")
78+
if sample_size is None:
79+
sample_size = study.metadata.get("sample_size")
80+
81+
# Validate single sample size if present
82+
if sample_size is not None and not isinstance(sample_size, (int, float)):
83+
raise TypeError(f"Expected sample_size to be numeric, but got {type(sample_size)}")
84+
85+
# Add sample size info to result if available
86+
if sample_sizes or sample_size is not None:
87+
try:
88+
result["metadata"]["sample_sizes"] = sample_sizes or [sample_size]
89+
except TypeError as e:
90+
raise TypeError(f"Error converting sample size data to list: {str(e)}") from e
91+
92+
# Handle annotations if present
6893
if analysis.annotations:
6994
result["labels"] = {}
70-
for annotation in analysis.annotations.values():
71-
result["labels"].update(annotation)
95+
try:
96+
for annotation in analysis.annotations.values():
97+
if not isinstance(annotation, dict):
98+
raise TypeError(
99+
f"Expected annotation to be dict, but got {type(annotation)}"
100+
)
101+
result["labels"].update(annotation)
102+
except (TypeError, AttributeError) as e:
103+
raise ValueError(f"Invalid annotation format: {str(e)}") from e
72104

73105
return result
74106

nimare/tests/test_io.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,60 @@ def test_convert_nimads_to_dataset(example_nimads_studyset, example_nimads_annot
2222
assert isinstance(dset2, nimare.dataset.Dataset)
2323

2424

25+
def test_convert_nimads_to_dataset_sample_sizes(
26+
example_nimads_studyset, example_nimads_annotation
27+
):
28+
"""Conversion of nimads JSON to nimare dataset."""
29+
studyset = Studyset(example_nimads_studyset)
30+
for study in studyset.studies:
31+
for analysis in study.analyses:
32+
analysis.metadata["sample_sizes"] = [2, 20]
33+
34+
dset = io.convert_nimads_to_dataset(studyset)
35+
36+
assert isinstance(dset, nimare.dataset.Dataset)
37+
assert "sample_sizes" in dset.metadata.columns
38+
39+
40+
def test_convert_nimads_to_dataset_single_sample_size(
41+
example_nimads_studyset, example_nimads_annotation
42+
):
43+
"""Test conversion of nimads JSON to nimare dataset with a single sample size value."""
44+
studyset = Studyset(example_nimads_studyset)
45+
for study in studyset.studies:
46+
for analysis in study.analyses:
47+
analysis.metadata["sample_size"] = 20
48+
49+
dset = io.convert_nimads_to_dataset(studyset)
50+
51+
assert isinstance(dset, nimare.dataset.Dataset)
52+
assert "sample_sizes" in dset.metadata.columns
53+
54+
55+
def test_analysis_to_dict_invalid_sample_sizes_type(example_nimads_studyset):
56+
"""Test _analysis_to_dict raises ValueError when sample_sizes is not a list/tuple."""
57+
studyset = Studyset(example_nimads_studyset)
58+
# Set sample_sizes to an int rather than list/tuple
59+
for study in studyset.studies:
60+
for analysis in study.analyses:
61+
analysis.metadata["sample_sizes"] = 5
62+
with pytest.raises(TypeError):
63+
# Trigger conversion which internally calls _analysis_to_dict
64+
io.convert_nimads_to_dataset(studyset)
65+
66+
67+
def test_analysis_to_dict_invalid_annotations_format(example_nimads_studyset):
68+
"""Test _analysis_to_dict raises ValueError when annotations are in an invalid format."""
69+
studyset = Studyset(example_nimads_studyset)
70+
# Here we assume that the annotation is expected to be a dict
71+
# Set annotation to an invalid format (e.g., a string)
72+
for study in studyset.studies:
73+
for analysis in study.analyses:
74+
analysis.metadata["annotations"] = "invalid_format"
75+
with pytest.raises(TypeError):
76+
io.convert_nimads_to_dataset(studyset)
77+
78+
2579
def test_convert_sleuth_to_dataset_smoke():
2680
"""Smoke test for Sleuth text file conversion."""
2781
sleuth_file = os.path.join(get_test_data_path(), "test_sleuth_file.txt")

0 commit comments

Comments
 (0)