Skip to content

Commit d011b6c

Browse files
committed
RF: reproin - used datatype and suffix terms in reproin code
Also added few extra comments / pointers. There should be no behavior change, unless someone used parts of reproin heuristic and relied on those returned by helper parse_series_spec data structures
1 parent 364551b commit d011b6c

File tree

1 file changed

+43
-38
lines changed

1 file changed

+43
-38
lines changed

heudiconv/heuristics/reproin.py

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,9 @@ def infotodict(seqinfo):
417417
# 1 - PRIMARY/SECONDARY
418418
# 3 - Image IOD specific specialization (optional)
419419
dcm_image_iod_spec = s.image_type[2]
420-
image_type_seqtype = {
420+
image_type_datatype = {
421421
# Note: P and M are too generic to make a decision here, could be
422-
# for different seqtypes (bold, fmap, etc)
422+
# for different datatypes (bold, fmap, etc)
423423
'FMRI': 'func',
424424
'MPR': 'anat',
425425
'DIFFUSION': 'dwi',
@@ -428,7 +428,7 @@ def infotodict(seqinfo):
428428
'MIP_TRA': 'anat', # angiography
429429
}.get(dcm_image_iod_spec, None)
430430
else:
431-
dcm_image_iod_spec = image_type_seqtype = None
431+
dcm_image_iod_spec = image_type_datatype = None
432432

433433
series_info = {} # For please lintian and its friends
434434
for sfield in series_spec_fields:
@@ -453,19 +453,19 @@ def infotodict(seqinfo):
453453
if dcm_image_iod_spec and dcm_image_iod_spec.startswith('MIP'):
454454
series_info['acq'] = series_info.get('acq', '') + sanitize_str(dcm_image_iod_spec)
455455

456-
seqtype = series_info.pop('seqtype')
457-
seqtype_label = series_info.pop('seqtype_label', None)
456+
datatype = series_info.pop('datatype')
457+
datatype_suffix = series_info.pop('datatype_suffix', None)
458458

459-
if image_type_seqtype and seqtype != image_type_seqtype:
459+
if image_type_datatype and datatype != image_type_datatype:
460460
lgr.warning(
461-
"Deduced seqtype to be %s from DICOM, but got %s out of %s",
462-
image_type_seqtype, seqtype, series_spec)
461+
"Deduced datatype to be %s from DICOM, but got %s out of %s",
462+
image_type_datatype, datatype, series_spec)
463463

464464
# if s.is_derived:
465465
# # Let's for now stash those close to original images
466466
# # TODO: we might want a separate tree for all of this!?
467467
# # so more of a parameter to the create_key
468-
# #seqtype += '/derivative'
468+
# #datatype += '/derivative'
469469
# # just keep it lower case and without special characters
470470
# # XXXX what for???
471471
# #seq.append(s.series_description.lower())
@@ -475,46 +475,46 @@ def infotodict(seqinfo):
475475
prefix = ''
476476

477477
#
478-
# Figure out the seqtype_label (BIDS _suffix)
478+
# Figure out the datatype_suffix (BIDS _suffix)
479479
#
480480
# If none was provided -- let's deduce it from the information we find:
481481
# analyze s.protocol_name (series_id is based on it) for full name mapping etc
482-
if not seqtype_label:
483-
if seqtype == 'func':
482+
if not datatype_suffix:
483+
if datatype == 'func':
484484
if '_pace_' in series_spec:
485-
seqtype_label = 'pace' # or should it be part of seq-
485+
datatype_suffix = 'pace' # or should it be part of seq-
486486
elif 'P' in s.image_type:
487-
seqtype_label = 'phase'
487+
datatype_suffix = 'phase'
488488
elif 'M' in s.image_type:
489-
seqtype_label = 'bold'
489+
datatype_suffix = 'bold'
490490
else:
491491
# assume bold by default
492-
seqtype_label = 'bold'
493-
elif seqtype == 'fmap':
492+
datatype_suffix = 'bold'
493+
elif datatype == 'fmap':
494494
# TODO: support phase1 phase2 like in "Case 2: Two phase images ..."
495495
if not dcm_image_iod_spec:
496496
raise ValueError("Do not know image data type yet to make decision")
497-
seqtype_label = {
497+
datatype_suffix = {
498498
# might want explicit {file_index} ?
499499
# _epi for pepolar fieldmaps, see
500500
# https://bids-specification.readthedocs.io/en/stable/04-modality-specific-files/01-magnetic-resonance-imaging-data.html#case-4-multiple-phase-encoded-directions-pepolar
501501
'M': 'epi' if 'dir' in series_info else 'magnitude',
502502
'P': 'phasediff',
503503
'DIFFUSION': 'epi', # according to KODI those DWI are the EPIs we need
504504
}[dcm_image_iod_spec]
505-
elif seqtype == 'dwi':
505+
elif datatype == 'dwi':
506506
# label for dwi as well
507-
seqtype_label = 'dwi'
507+
datatype_suffix = 'dwi'
508508

509509
#
510-
# Even if seqtype_label was provided, for some data we might need to override,
510+
# Even if datatype_suffix was provided, for some data we might need to override,
511511
# since they are complementary files produced along-side with original
512512
# ones.
513513
#
514514
if s.series_description.endswith('_SBRef'):
515-
seqtype_label = 'sbref'
515+
datatype_suffix = 'sbref'
516516

517-
if not seqtype_label:
517+
if not datatype_suffix:
518518
# Might be provided by the bids ending within series_spec, we would
519519
# just want to check if that the last element is not _key-value pair
520520
bids_ending = series_info.get('bids', None)
@@ -584,7 +584,12 @@ def from_series_info(name):
584584
else:
585585
return None
586586

587-
suffix_parts = [
587+
# TODO: get order from schema, do not hardcode. ATM could be checked at
588+
# https://bids-specification.readthedocs.io/en/stable/99-appendices/04-entity-table.html
589+
# https://github.com/bids-standard/bids-specification/blob/HEAD/src/schema/rules/entities.yaml
590+
# ATM we at large rely on possible (re)ordering according to schema to be done
591+
# by heudiconv, not reproin here.
592+
filename_suffix_parts = [
588593
from_series_info('task'),
589594
from_series_info('acq'),
590595
# But we want to add an indicator in case it was motion corrected
@@ -593,10 +598,10 @@ def from_series_info(name):
593598
from_series_info('dir'),
594599
series_info.get('bids'),
595600
run_label,
596-
seqtype_label,
601+
datatype_suffix,
597602
]
598603
# filter those which are None, and join with _
599-
suffix = '_'.join(filter(bool, suffix_parts))
604+
suffix = '_'.join(filter(bool, filename_suffix_parts))
600605

601606
# # .series_description in case of
602607
# sdesc = s.study_description
@@ -615,12 +620,12 @@ def from_series_info(name):
615620
# For scouts -- we want only dicoms
616621
# https://github.com/nipy/heudiconv/issues/145
617622
if "_Scout" in s.series_description or \
618-
(seqtype == 'anat' and seqtype_label and seqtype_label.startswith('scout')):
623+
(datatype == 'anat' and datatype_suffix and datatype_suffix.startswith('scout')):
619624
outtype = ('dicom',)
620625
else:
621626
outtype = ('nii.gz', 'dicom')
622627

623-
template = create_key(seqtype, suffix, prefix=prefix, outtype=outtype)
628+
template = create_key(datatype, suffix, prefix=prefix, outtype=outtype)
624629
# we wanted ordered dict for consistent demarcation of dups
625630
if template not in info:
626631
info[template] = []
@@ -862,17 +867,17 @@ def split2(s):
862867
return s, None
863868

864869
# Let's analyze first element which should tell us sequence type
865-
seqtype, seqtype_label = split2(split[0])
866-
if seqtype not in KNOWN_DATATYPES:
870+
datatype, datatype_suffix = split2(split[0])
871+
if datatype not in KNOWN_DATATYPES:
867872
# It is not something we don't consume
868873
if bids:
869874
lgr.warning("It was instructed to be BIDS datatype but unknown "
870-
"%s found. Known are: %s", seqtype, ', '.join(KNOWN_DATATYPES))
875+
"%s found. Known are: %s", datatype, ', '.join(KNOWN_DATATYPES))
871876
return {}
872877

873-
regd = dict(seqtype=seqtype)
874-
if seqtype_label:
875-
regd['seqtype_label'] = seqtype_label
878+
regd = dict(datatype=datatype)
879+
if datatype_suffix:
880+
regd['datatype_suffix'] = datatype_suffix
876881
# now go through each to see if one which we care
877882
bids_leftovers = []
878883
for s in split[1:]:
@@ -899,12 +904,12 @@ def split2(s):
899904
# TODO: might want to check for all known "standard" BIDS suffixes here
900905
# among bids_leftovers, thus serve some kind of BIDS validator
901906

902-
# if not regd.get('seqtype_label', None):
903-
# # might need to assign a default label for each seqtype if was not
907+
# if not regd.get('datatype_suffix', None):
908+
# # might need to assign a default label for each datatype if was not
904909
# # given
905-
# regd['seqtype_label'] = {
910+
# regd['datatype_suffix'] = {
906911
# 'func': 'bold'
907-
# }.get(regd['seqtype'], None)
912+
# }.get(regd['datatype'], None)
908913

909914
return regd
910915

0 commit comments

Comments
 (0)