@@ -233,65 +233,91 @@ def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
233
233
getattr (heuristic , 'DEFAULT_FIELDS' , {}))
234
234
235
235
236
- def update_complex_name (metadata , this_prefix_basename , suffix ):
236
+ def update_complex_name (metadata , filename , suffix ):
237
237
"""
238
- Insert `_part-<magnitude|phase>` entity into filename if data are from a sequence
239
- with magnitude/phase part.
238
+ Insert `_rec-<magnitude|phase>` entity into filename if data are from a
239
+ sequence with magnitude/phase part.
240
+
241
+ Parameters
242
+ ----------
243
+ metadata : dict
244
+ Scan metadata dictionary from BIDS sidecar file.
245
+ filename : str
246
+ Incoming filename
247
+ suffix : str
248
+ An index used for cases where a single scan produces multiple files,
249
+ but the differences between those files are unknown.
250
+
251
+ Returns
252
+ -------
253
+ filename : str
254
+ Updated filename with rec entity added in appropriate position.
240
255
"""
241
- # Functional scans separate magnitude/phase differently
242
- unsupported_types = ['_bold' , '_phase' ]
243
- if any (ut in this_prefix_basename for ut in unsupported_types ):
244
- return this_prefix_basename
256
+ # Some scans separate magnitude/phase differently
257
+ unsupported_types = ['_bold' , '_phase' ,
258
+ '_magnitude' , '_magnitude1' , '_magnitude2' ,
259
+ '_phasediff' , '_phase1' , '_phase2' ]
260
+ if any (ut in filename for ut in unsupported_types ):
261
+ return filename
245
262
246
263
# Check to see if it is magnitude or phase part:
247
264
if 'M' in metadata .get ('ImageType' ):
248
- mag_or_phase = 'mag '
265
+ mag_or_phase = 'magnitude '
249
266
elif 'P' in metadata .get ('ImageType' ):
250
267
mag_or_phase = 'phase'
251
268
else :
252
269
mag_or_phase = suffix
253
270
254
271
# Determine scan suffix
255
- filetype = '_' + this_prefix_basename .split ('_' )[- 1 ]
272
+ filetype = '_' + filename .split ('_' )[- 1 ]
256
273
257
- # Insert part label
258
- if not ('_part -%s' % mag_or_phase ) in this_prefix_basename :
259
- # If "_part -" is specified, prepend the 'mag_or_phase' value.
260
- if '_part -' in this_prefix_basename :
274
+ # Insert rec label
275
+ if not ('_rec -%s' % mag_or_phase ) in filename :
276
+ # If "_rec -" is specified, prepend the 'mag_or_phase' value.
277
+ if '_rec -' in filename :
261
278
raise BIDSError (
262
- "Part label for images will be automatically set, remove "
263
- "from heuristic"
279
+ "Reconstruction label for images will be automatically set, "
280
+ "remove from heuristic"
264
281
)
265
282
266
- # If not, insert "_part-" + 'mag_or_phase' into the prefix_basename
267
- # **before** "_run", "_echo" or "_sbref", whichever appears first:
283
+ # Insert it **before** the following string(s), whichever appears first.
268
284
for label in ['_dir' , '_run' , '_mod' , '_echo' , '_recording' , '_proc' , '_space' , filetype ]:
269
- if label == filetype :
270
- this_prefix_basename = this_prefix_basename .replace (
271
- filetype , "_part-%s%s" % (mag_or_phase , filetype )
272
- )
273
- break
274
- elif (label in this_prefix_basename ):
275
- this_prefix_basename = this_prefix_basename .replace (
276
- label , "_part-%s%s" % (mag_or_phase , label )
285
+ if (label == filetype ) or (label in filename ):
286
+ filename = filename .replace (
287
+ label , "_rec-%s%s" % (mag_or_phase , label )
277
288
)
278
289
break
279
290
280
- return this_prefix_basename
291
+ return filename
281
292
282
293
283
- def update_multiecho_name (metadata , this_prefix_basename , echo_times ):
294
+ def update_multiecho_name (metadata , filename , echo_times ):
284
295
"""
285
296
Insert `_echo-<num>` entity into filename if data are from a multi-echo
286
297
sequence.
298
+
299
+ Parameters
300
+ ----------
301
+ metadata : dict
302
+ Scan metadata dictionary from BIDS sidecar file.
303
+ filename : str
304
+ Incoming filename
305
+ echo_times : list
306
+ List of all echo times from scan. Used to determine the echo *number*
307
+ (i.e., index) if field is missing from metadata.
308
+
309
+ Returns
310
+ -------
311
+ filename : str
312
+ Updated filename with echo entity added, if appropriate.
287
313
"""
288
314
# Field maps separate echoes differently
289
315
unsupported_types = [
290
316
'_magnitude' , '_magnitude1' , '_magnitude2' ,
291
317
'_phasediff' , '_phase1' , '_phase2' , '_fieldmap'
292
318
]
293
- if any (ut in this_prefix_basename for ut in unsupported_types ):
294
- return this_prefix_basename
319
+ if any (ut in filename for ut in unsupported_types ):
320
+ return filename
295
321
296
322
# Get the EchoNumber from json file info. If not present, use EchoTime
297
323
if 'EchoNumber' in metadata .keys ():
@@ -300,57 +326,62 @@ def update_multiecho_name(metadata, this_prefix_basename, echo_times):
300
326
echo_number = echo_times .index (metadata ['EchoTime' ]) + 1
301
327
302
328
# Determine scan suffix
303
- filetype = '_' + this_prefix_basename .split ('_' )[- 1 ]
329
+ filetype = '_' + filename .split ('_' )[- 1 ]
304
330
305
331
# Insert it **before** the following string(s), whichever appears first.
306
332
for label in ['_recording' , '_proc' , '_space' , filetype ]:
307
- if label == filetype :
308
- this_prefix_basename = this_prefix_basename .replace (
309
- filetype , "_echo-%s%s" % (echo_number , filetype )
310
- )
311
- break
312
- elif (label in this_prefix_basename ):
313
- this_prefix_basename = this_prefix_basename .replace (
333
+ if (label == filetype ) or (label in filename ):
334
+ filename = filename .replace (
314
335
label , "_echo-%s%s" % (echo_number , label )
315
336
)
316
337
break
317
338
318
- return this_prefix_basename
339
+ return filename
319
340
320
341
321
- def update_uncombined_name (metadata , this_prefix_basename , channel_names ):
342
+ def update_uncombined_name (metadata , filename , channel_names ):
322
343
"""
323
344
Insert `_ch-<num>` entity into filename if data are from a sequence
324
345
with "save uncombined".
346
+
347
+ Parameters
348
+ ----------
349
+ metadata : dict
350
+ Scan metadata dictionary from BIDS sidecar file.
351
+ filename : str
352
+ Incoming filename
353
+ channel_names : list
354
+ List of all channel names from scan. Used to determine the channel
355
+ *number* (i.e., index) if field is missing from metadata.
356
+
357
+ Returns
358
+ -------
359
+ filename : str
360
+ Updated filename with ch entity added, if appropriate.
325
361
"""
326
362
# In case any scan types separate channels differently
327
363
unsupported_types = []
328
- if any (ut in this_prefix_basename for ut in unsupported_types ):
329
- return this_prefix_basename
364
+ if any (ut in filename for ut in unsupported_types ):
365
+ return filename
330
366
331
367
# Determine the channel number
332
368
channel_number = '' .join ([c for c in metadata ['CoilString' ] if c .isdigit ()])
333
369
if not channel_number :
334
370
channel_number = channel_names .index (metadata ['CoilString' ]) + 1
335
- channel_number = channel_number .zfill (2 )
371
+ channel_number = str ( channel_number ) .zfill (2 )
336
372
337
373
# Determine scan suffix
338
- filetype = '_' + this_prefix_basename .split ('_' )[- 1 ]
374
+ filetype = '_' + filename .split ('_' )[- 1 ]
339
375
340
376
# Insert it **before** the following string(s), whichever appears first.
341
377
# Choosing to put channel near the end since it's not in the specification yet.
342
378
for label in ['_recording' , '_proc' , '_space' , filetype ]:
343
- if label == filetype :
344
- this_prefix_basename = this_prefix_basename .replace (
345
- filetype , "_ch-%s%s" % (channel_number , filetype )
346
- )
347
- break
348
- elif (label in this_prefix_basename ):
349
- this_prefix_basename = this_prefix_basename .replace (
379
+ if (label == filetype ) or (label in filename ):
380
+ filename = filename .replace (
350
381
label , "_ch-%s%s" % (channel_number , label )
351
382
)
352
383
break
353
- return this_prefix_basename
384
+ return filename
354
385
355
386
356
387
def convert (items , converter , scaninfo_suffix , custom_callable , with_prov ,
@@ -655,27 +686,16 @@ def save_converted_files(res, item_dicoms, bids_options, outtype, prefix, outnam
655
686
# echo times for all bids_files and see if they are all the same or not.
656
687
657
688
# Collect some metadata across all images
658
- echo_times , channel_names , image_types = [], [], []
659
- for b in bids_files :
660
- if not b :
689
+ echo_times , channel_names , image_types = set (), set (), set ()
690
+ for metadata in bids_metas :
691
+ if not metadata :
661
692
continue
662
- metadata = load_json (b )
663
- echo_times .append (metadata .get ('EchoTime' , None ))
664
- channel_names .append (metadata .get ('CoilString' , None ))
665
- image_types .append (metadata .get ('ImageType' , None ))
666
- echo_times = [v for v in echo_times if v ]
667
- echo_times = sorted (list (set (echo_times )))
668
- channel_names = [v for v in channel_names if v ]
669
- channel_names = sorted (list (set (channel_names )))
670
- image_types = [v for v in image_types if v ]
671
-
672
- is_multiecho = len (echo_times ) > 1 # Check for varying echo times
673
- is_uncombined = len (channel_names ) > 1 # Check for uncombined data
674
-
675
- # Determine if data are complex (magnitude + phase)
676
- magnitude_found = any (['M' in it for it in image_types ])
677
- phase_found = any (['P' in it for it in image_types ])
678
- is_complex = magnitude_found and phase_found
693
+ echo_times .add (metadata .get ('EchoTime' , nan ))
694
+ channel_names .add (metadata .get ('CoilString' , nan ))
695
+ image_types .update (metadata .get ('ImageType' , [nan ]))
696
+ is_multiecho = len (set (filter (bool , echo_times ))) > 1 # Check for varying echo times
697
+ is_uncombined = len (set (filter (bool , channel_names ))) > 1 # Check for uncombined data
698
+ is_complex = 'M' in image_types and 'P' in image_types # Determine if data are complex (magnitude + phase)
679
699
680
700
### Loop through the bids_files, set the output name and save files
681
701
for fl , suffix , bids_file , bids_meta in zip (res_files , suffixes , bids_files , bids_metas ):
@@ -686,23 +706,22 @@ def save_converted_files(res, item_dicoms, bids_options, outtype, prefix, outnam
686
706
# and we don't want to modify it for all the bids_files):
687
707
this_prefix_basename = prefix_basename
688
708
689
- # Update name if multi-echo
690
- if bids_file and is_multiecho :
691
- this_prefix_basename = update_multiecho_name (
692
- bids_meta , this_prefix_basename , echo_times
693
- )
709
+ # Update name for certain criteria
710
+ if bids_file :
711
+ if is_multiecho :
712
+ this_prefix_basename = update_multiecho_name (
713
+ bids_meta , this_prefix_basename , echo_times
714
+ )
694
715
695
- # Update name if complex data
696
- if bids_file and is_complex :
697
- this_prefix_basename = update_complex_name (
698
- bids_meta , this_prefix_basename , suffix
699
- )
716
+ if is_complex :
717
+ this_prefix_basename = update_complex_name (
718
+ bids_meta , this_prefix_basename , suffix
719
+ )
700
720
701
- # Update name if uncombined (channel-level) data
702
- if bids_file and is_uncombined :
703
- this_prefix_basename = update_uncombined_name (
704
- bids_meta , this_prefix_basename , channel_names
705
- )
721
+ if is_uncombined :
722
+ this_prefix_basename = update_uncombined_name (
723
+ bids_meta , this_prefix_basename , channel_names
724
+ )
706
725
707
726
# Fallback option:
708
727
# If we have failed to modify this_prefix_basename, because it didn't fall
0 commit comments