Skip to content

Commit 90b861d

Browse files
committed
ENH: Calculate TA and store in run_info
1 parent 13c857f commit 90b861d

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

bids/analysis/analysis.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,13 +388,22 @@ def get_design_matrix(self, names=None, format='long', mode='both',
388388

389389
if sampling_rate == 'TR':
390390
trs = {var.run_info[0].tr for var in self.collection.variables.values()}
391+
tas = {var.run_info[0].ta for var in self.collection.variables.values()}
391392
if not trs:
392393
raise ValueError("Repetition time unavailable; specify sampling_rate "
393394
"explicitly")
394395
elif len(trs) > 1:
395396
raise ValueError("Non-unique Repetition times found ({!r}); specify "
396-
"sampling_rate explicitly")
397-
sampling_rate = 1. / trs.pop()
397+
"sampling_rate explicitly".format(trs))
398+
TR = trs.pop()
399+
if not tas:
400+
warnings.warn("Acquisition time unavailable; assuming TA = TR")
401+
tas = {TR}
402+
elif len(tas) > 1:
403+
raise ValueError("Non-unique acquisition times found ({!r})".format(tas))
404+
405+
sampling_rate = 1. / TR
406+
acquisition_time = tas.pop()
398407
elif sampling_rate == 'highest':
399408
sampling_rate = None
400409
dense_df = coll.to_df(names, format='wide',

bids/variables/entities.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,23 +36,25 @@ class RunNode(Node):
3636
image_file (str): The full path to the corresponding nifti image.
3737
duration (float): Duration of the run, in seconds.
3838
repetition_time (float): TR for the run.
39+
acquisition_time (float): TA for the run.
3940
task (str): The task name for this run.
4041
'''
4142

42-
def __init__(self, entities, image_file, duration, repetition_time):
43+
def __init__(self, entities, image_file, duration, repetition_time, acquisition_time):
4344
self.image_file = image_file
4445
self.duration = duration
4546
self.repetition_time = repetition_time
47+
self.acquisition_time = acquisition_time
4648
super(RunNode, self).__init__('run', entities)
4749

4850
def get_info(self):
4951

5052
return RunInfo(self.entities, self.duration, self.repetition_time,
51-
self.image_file)
53+
self.acquisition_time, self.image_file)
5254

5355

5456
# Stores key information for each Run.
55-
RunInfo = namedtuple('RunInfo', ['entities', 'duration', 'tr', 'image'])
57+
RunInfo = namedtuple('RunInfo', ['entities', 'duration', 'tr', 'ta', 'image'])
5658

5759

5860
class NodeIndex(Node):

bids/variables/io.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,24 @@ def load_variables(layout, types=None, levels=None, skip_empty=True,
8282
return dataset
8383

8484

85+
def _get_timing_info(img_md):
86+
if 'RepetitionTime' in img_md:
87+
tr = img_md['RepetitionTime']
88+
if 'DelayTime' in img_md:
89+
ta = tr - img_md['DelayTime']
90+
elif 'SliceTiming' in img_md:
91+
slicetimes = sorted(img_md['SliceTiming'])
92+
# a, b ... z
93+
# z = final slice onset, b - a = slice duration
94+
ta = slicetimes[-1] + slicetimes[1] - slicetimes[0]
95+
else:
96+
ta = tr
97+
elif 'VolumeTiming' in img_md:
98+
return NotImplemented
99+
100+
return tr, ta
101+
102+
85103
def _load_time_variables(layout, dataset=None, columns=None, scan_length=None,
86104
drop_na=True, events=True, physio=True, stim=True,
87105
regressors=True, skip_empty=True, **selectors):
@@ -141,8 +159,9 @@ def _load_time_variables(layout, dataset=None, columns=None, scan_length=None,
141159
if 'run' in entities:
142160
entities['run'] = int(entities['run'])
143161

144-
tr = layout.get_metadata(img_f, suffix='bold', domains=domains,
145-
full_search=True)['RepetitionTime']
162+
img_md = layout.get_metadata(img_f, suffix='bold', domains=domains,
163+
full_search=True)
164+
tr, ta = _get_timing_info(img_md)
146165

147166
# Get duration of run: first try to get it directly from the image
148167
# header; if that fails, try to get NumberOfVolumes from the
@@ -162,7 +181,8 @@ def _load_time_variables(layout, dataset=None, columns=None, scan_length=None,
162181
raise ValueError(msg)
163182

164183
run = dataset.get_or_create_node('run', entities, image_file=img_f,
165-
duration=duration, repetition_time=tr)
184+
duration=duration, repetition_time=tr,
185+
acquisition_time=ta)
166186
run_info = run.get_info()
167187

168188
# Process event files

0 commit comments

Comments
 (0)