Skip to content

Commit 711d403

Browse files
authored
Merge pull request #500 from dbic/bf-participant-nas
ENH+BF: consistent n/a for age/sex, also handle ?M for months
2 parents 6b80704 + ad75d50 commit 711d403

File tree

2 files changed

+59
-2
lines changed

2 files changed

+59
-2
lines changed

heudiconv/bids.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,36 @@ class BIDSError(Exception):
4747
BIDS_VERSION = "1.4.1"
4848

4949

50+
def maybe_na(val):
51+
"""Return 'n/a' if non-None value represented as str is not empty
52+
53+
Primarily for the consistent use of lower case 'n/a' so 'N/A' and 'NA'
54+
are also treated as 'n/a'
55+
"""
56+
if val is not None:
57+
val = str(val)
58+
val = val.strip()
59+
return 'n/a' if (not val or val in ('N/A', 'NA')) else val
60+
61+
62+
def treat_age(age):
63+
"""Age might encounter 'Y' suffix or be a float"""
64+
age = str(age)
65+
if age.endswith('M'):
66+
age = age.rstrip('M')
67+
age = float(age) / 12
68+
age = ('%.2f' if age != int(age) else '%d') % age
69+
else:
70+
age = age.rstrip('Y')
71+
if age:
72+
# strip all leading 0s but allow to scan a newborn (age 0Y)
73+
age = '0' if not age.lstrip('0') else age.lstrip('0')
74+
if age.startswith('.'):
75+
# we had float point value, let's prepend 0
76+
age = '0' + age
77+
return age
78+
79+
5080
def populate_bids_templates(path, defaults={}):
5181
"""Premake BIDS text files with templates"""
5282

@@ -278,12 +308,13 @@ def add_participant_record(studydir, subject, age, sex):
278308
"control group)")])),
279309
]),
280310
sort_keys=False)
311+
281312
# Add a new participant
282313
with open(participants_tsv, 'a') as f:
283314
f.write(
284315
'\t'.join(map(str, [participant_id,
285-
age.lstrip('0').rstrip('Y') if age else 'N/A',
286-
sex if sex else 'n/a',
316+
maybe_na(treat_age(age)),
317+
maybe_na(sex),
287318
'control'])) + '\n')
288319

289320

heudiconv/tests/test_bids.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""Test functions in heudiconv.bids module.
2+
"""
3+
4+
from heudiconv.bids import (
5+
maybe_na,
6+
treat_age,
7+
)
8+
9+
10+
def test_maybe_na():
11+
for na in '', ' ', None, 'n/a', 'N/A', 'NA':
12+
assert maybe_na(na) == 'n/a'
13+
for notna in 0, 1, False, True, 'value':
14+
assert maybe_na(notna) == str(notna)
15+
16+
17+
def test_treat_age():
18+
assert treat_age(0) == '0'
19+
assert treat_age('0') == '0'
20+
assert treat_age('0000') == '0'
21+
assert treat_age('0000Y') == '0'
22+
assert treat_age('000.1Y') == '0.1'
23+
assert treat_age('1M') == '0.08'
24+
assert treat_age('12M') == '1'
25+
assert treat_age('0000.1') == '0.1'
26+
assert treat_age(0000.1) == '0.1'

0 commit comments

Comments
 (0)