@@ -144,6 +144,61 @@ def scale_timings(timelist, input_units, output_units, time_repetition):
144144 timelist = [np .max ([0. , _scalefactor * t ]) for t in timelist ]
145145 return timelist
146146
147+ def bids_gen_info (bids_event_files ,
148+ condition_column = 'trial_type' ,
149+ amplitude_column = None ,
150+ time_repetition = False ,
151+ ):
152+ """Generate subject_info structure from a list of BIDS .tsv event files.
153+
154+ Parameters
155+ ----------
156+
157+ bids_event_files : list of str
158+ Filenames of BIDS .tsv event files containing columns including:
159+ 'onset', 'duration', and 'trial_type' or the `condition_column` value.
160+ condition_column : str
161+ Column of files in `bids_event_files` based on the values of which
162+ events will be sorted into different regressors
163+ amplitude_column : str
164+ Column of files in `bids_event_files` based on the values of which
165+ to apply amplitudes to events. If unspecified, all events will be
166+ represented with an amplitude of 1.
167+
168+ Returns
169+ -------
170+
171+ list of Bunch
172+ """
173+ info = []
174+ for bids_event_file in bids_event_files :
175+ with open (bids_event_file ) as f :
176+ f_events = csv .DictReader (f , skipinitialspace = True , delimiter = '\t ' )
177+ events = [{k : v for k , v in row .items ()} for row in f_events ]
178+ conditions = list (set ([i [condition_column ] for i in events ]))
179+ runinfo = Bunch (conditions = [], onsets = [], durations = [], amplitudes = [])
180+ for condition in conditions :
181+ selected_events = [i for i in events if i [condition_column ]== condition ]
182+ onsets = [float (i ['onset' ]) for i in selected_events ]
183+ durations = [float (i ['duration' ]) for i in selected_events ]
184+ if time_repetition :
185+ decimals = math .ceil (- math .log10 (time_repetition ))
186+ onsets = [np .round (i , decimals ) for i in onsets ]
187+ durations = [np .round (i ,decimals ) for i in durations ]
188+ if condition :
189+ runinfo .conditions .append (condition )
190+ else :
191+ runinfo .conditions .append ('e0' )
192+ runinfo .onsets .append (onsets )
193+ runinfo .durations .append (durations )
194+ try :
195+ amplitudes = [float (i [amplitude_column ]) for i in selected_events ]
196+ runinfo .amplitudes .append (amplitudes )
197+ except KeyError :
198+ runinfo .amplitudes .append ([1 ] * len (onsets ))
199+ info .append (runinfo )
200+ return info
201+
147202
148203def gen_info (run_event_files ):
149204 """Generate subject_info structure from a list of event files
@@ -190,6 +245,23 @@ class SpecifyModelInputSpec(BaseInterfaceInputSpec):
190245 desc = 'List of event description files 1, 2 or 3 '
191246 'column format corresponding to onsets, '
192247 'durations and amplitudes' )
248+ bids_event_file = InputMultiPath (
249+ File (exists = True ),
250+ mandatory = True ,
251+ xor = ['subject_info' , 'event_files' , 'bids_event_file' ],
252+ desc = 'TSV event file containing common BIDS fields: `onset`,'
253+ '`duration`, and categorization and amplitude columns' )
254+ bids_condition_column = traits .Str (exists = True ,
255+ mandatory = False ,
256+ default_value = 'trial_type' ,
257+ usedefault = True ,
258+ desc = 'Column of the file passed to `bids_event_file` to the '
259+ 'unique values of which events will be assigned'
260+ 'to regressors' )
261+ bids_amplitude_column = traits .Str (exists = True ,
262+ mandatory = False ,
263+ desc = 'Column of the file passed to `bids_event_file` '
264+ 'according to which to assign amplitudes to events' )
193265 realignment_parameters = InputMultiPath (
194266 File (exists = True ),
195267 desc = 'Realignment parameters returned '
@@ -432,8 +504,15 @@ def _generate_design(self, infolist=None):
432504 if infolist is None :
433505 if isdefined (self .inputs .subject_info ):
434506 infolist = self .inputs .subject_info
435- else :
507+ elif isdefined ( self . inputs . event_files ) :
436508 infolist = gen_info (self .inputs .event_files )
509+ elif isdefined (self .inputs .bids_event_file ):
510+ infolist = bids_gen_info (
511+ self .inputs .bids_event_file ,
512+ self .inputs .bids_condition_column ,
513+ self .inputs .bids_amplitude_column ,
514+ self .inputs .time_repetition ,
515+ )
437516 self ._sessinfo = self ._generate_standard_design (
438517 infolist ,
439518 functional_runs = self .inputs .functional_runs ,
0 commit comments