Skip to content

Commit 25729f4

Browse files
committed
ENH: addressing Matthew's comments -- should be no functional changes
1 parent a169e0b commit 25729f4

File tree

1 file changed

+38
-35
lines changed

1 file changed

+38
-35
lines changed

bin/heudiconv

Lines changed: 38 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
"""Convert DICOM dirs based on heuristic info
44
5-
This script uses DicomStack and mri_convert to convert DICOM directories.
5+
This script uses the dcmstack package and dcm2niix tool to convert DICOM
6+
directories or tarballs into collections of NIfTI files following pre-defined
7+
heuristic(s).
68
79
It has multiple modes of operation
810
@@ -18,7 +20,7 @@ It has multiple modes of operation
1820
DICOMs are sorted based on study UID, and layed out using specified heuristic
1921
"""
2022

21-
__version__ = '0.2'
23+
__version__ = '0.3'
2224

2325
import argparse
2426
from glob import glob
@@ -124,6 +126,8 @@ StudySessionInfo = namedtuple(
124126
)
125127

126128

129+
# TODO: RF to avoid package-level global structure, and be more friendly in
130+
# case of refactoring of heudiconv into a proper Python package/module
127131
class TempDirs(object):
128132
"""A helper to centralize handling and cleanup of dirs"""
129133

@@ -296,23 +300,24 @@ def find_files(regex, topdir=curdir, exclude=None, exclude_vcs=True, dirs=False)
296300
find_files.__doc__ %= (_VCS_REGEX,)
297301

298302

299-
def group_dicoms_into_seqinfos(fl, flfilter=None, dcmfilter=None, grouping='studyUID'):
303+
def group_dicoms_into_seqinfos(
304+
files, file_filter=None, dcmfilter=None, grouping='studyUID'
305+
):
300306
"""Process list of dicoms and return seqinfo and file group
301307
302308
`seqinfo` contains per-sequence extract of fields from DICOMs which
303309
will be later provided into heuristics to decide on filenames
304310
305311
Parameters
306312
----------
307-
fl : list of str
313+
files : list of str
308314
List of files to consider
309-
flfilter : callable, optional
310-
Applied to each of fl. Should return True if file needs to be kept,
311-
False otherwise. Used to filter fl
315+
file_filter : callable, optional
316+
Applied to each item of filenames. Should return True if file needs to be
317+
kept, False otherwise.
312318
dcmfilter : callable, optional
313-
If called on dcm_data and returns True, it is used to set
314-
series_id
315-
grouping : str ('studyUID', 'accession_number') or None, optional
319+
If called on dcm_data and returns True, it is used to set series_id
320+
grouping : {'studyUID', 'accession_number', None}, optional
316321
what to group by: studyUID or accession_number
317322
318323
Returns
@@ -328,24 +333,25 @@ def group_dicoms_into_seqinfos(fl, flfilter=None, dcmfilter=None, grouping='stud
328333
raise ValueError('I do not know how to group by {0}'.format(grouping))
329334
per_studyUID = grouping == 'studyUID'
330335
per_accession_number = grouping == 'accession_number'
331-
lgr.info("Analyzing %d dicoms", len(fl))
336+
lgr.info("Analyzing %d dicoms", len(files))
332337
import dcmstack as ds
333338
import dicom as dcm
334339

335340
groups = [[], []]
336341
mwgroup = []
337342

338-
studyUID = None # for sanity check that all DICOMs came from the same
339-
# "study". If not -- what is the use-case? (interrupted acquisition?)
340-
# and how would then we deal with series numbers
341-
# which would differ already
342-
if flfilter:
343-
nfl_before = len(fl)
344-
fl = list(filter(flfilter, fl))
345-
nfl_after = len(fl)
343+
studyUID = None
344+
# for sanity check that all DICOMs came from the same
345+
# "study". If not -- what is the use-case? (interrupted acquisition?)
346+
# and how would then we deal with series numbers
347+
# which would differ already
348+
if file_filter:
349+
nfl_before = len(files)
350+
files = list(filter(file_filter, files))
351+
nfl_after = len(files)
346352
lgr.info('Filtering out {0} dicoms based on their filename'.format(
347353
nfl_before-nfl_after))
348-
for fidx, filename in enumerate(fl):
354+
for fidx, filename in enumerate(files):
349355
# TODO after getting a regression test check if the same behavior
350356
# with stop_before_pixels=True
351357
mw = ds.wrapper_from_data(dcm.read_file(filename, force=True))
@@ -357,30 +363,29 @@ def group_dicoms_into_seqinfos(fl, flfilter=None, dcmfilter=None, grouping='stud
357363
pass
358364

359365
try:
360-
studyUID_ = mw.dcm_data.StudyInstanceUID
366+
file_studyUID = mw.dcm_data.StudyInstanceUID
361367
except AttributeError:
362-
#import pdb; pdb.set_trace()
363368
lgr.info("File %s is missing any StudyInstanceUID" % filename)
364-
studyUID_ = None
369+
file_studyUID = None
365370
#continue
366371

367372
try:
368373
series_id = (int(mw.dcm_data.SeriesNumber),
369374
mw.dcm_data.ProtocolName)
370-
studyUID_ = mw.dcm_data.StudyInstanceUID
375+
file_studyUID = mw.dcm_data.StudyInstanceUID
371376

372377
if not per_studyUID:
373378
# verify that we are working with a single study
374379
if studyUID is None:
375-
studyUID = studyUID_
380+
studyUID = file_studyUID
376381
elif not per_accession_number:
377-
assert studyUID == studyUID_
382+
assert studyUID == file_studyUID
378383
except AttributeError as exc:
379384
lgr.warning('Ignoring %s since not quite a "normal" DICOM: %s',
380385
filename, exc)
381386
# not a normal DICOM -> ignore
382387
series_id = (-1, 'none')
383-
studyUID_ = None
388+
file_studyUID = None
384389

385390
if not series_id[0] < 0:
386391
if dcmfilter is not None and dcmfilter(mw.dcm_data):
@@ -403,7 +408,7 @@ def group_dicoms_into_seqinfos(fl, flfilter=None, dcmfilter=None, grouping='stud
403408
series_id = (-1, mw.dcm_data.ProtocolName)
404409

405410
if per_studyUID:
406-
series_id = series_id + (studyUID_,)
411+
series_id = series_id + (file_studyUID,)
407412

408413

409414
#print fidx, N, filename
@@ -413,13 +418,13 @@ def group_dicoms_into_seqinfos(fl, flfilter=None, dcmfilter=None, grouping='stud
413418
#print idx, same, groups[idx][0]
414419
if same:
415420
# the same series should have the same study uuid
416-
assert mwgroup[idx].dcm_data.get('StudyInstanceUID', None) == studyUID_
421+
assert mwgroup[idx].dcm_data.get('StudyInstanceUID', None) == file_studyUID
417422
ingrp = True
418423
if series_id[0] >= 0:
419424
series_id = (mwgroup[idx].dcm_data.SeriesNumber,
420425
mwgroup[idx].dcm_data.ProtocolName)
421426
if per_studyUID:
422-
series_id = series_id + (studyUID_,)
427+
series_id = series_id + (file_studyUID,)
423428
groups[0].append(series_id)
424429
groups[1].append(idx)
425430

@@ -445,7 +450,7 @@ def group_dicoms_into_seqinfos(fl, flfilter=None, dcmfilter=None, grouping='stud
445450
# nothing to see here, just move on
446451
continue
447452
dcminfo = mw.dcm_data
448-
files = [fl[i] for i, s in enumerate(groups[0]) if s == series_id]
453+
files = [files[i] for i, s in enumerate(groups[0]) if s == series_id]
449454
# turn the series_id into a human-readable string -- string is needed
450455
# for JSON storage later on
451456
if per_studyUID:
@@ -1261,7 +1266,7 @@ def convert_dicoms(sid,
12611266
if dicoms:
12621267
seqinfo = group_dicoms_into_seqinfos(
12631268
dicoms,
1264-
flfilter=getattr(heuristic, 'filter_files', None),
1269+
file_filter=getattr(heuristic, 'filter_files', None),
12651270
dcmfilter=getattr(heuristic, 'filter_dicom', None),
12661271
grouping=None, # no groupping
12671272
)
@@ -1454,10 +1459,9 @@ def get_study_sessions(dicom_dir_template, files_opt, heuristic, outdir,
14541459

14551460
# sort all DICOMS using heuristic
14561461
# TODO: this one is not groupping by StudyUID but may be we should!
1457-
#import pdb; pdb.set_trace()
14581462
seqinfo_dict = group_dicoms_into_seqinfos(
14591463
files_,
1460-
flfilter=getattr(heuristic, 'filter_files', None),
1464+
file_filter=getattr(heuristic, 'filter_files', None),
14611465
dcmfilter=getattr(heuristic, 'filter_dicom', None),
14621466
grouping=grouping)
14631467

@@ -1727,7 +1731,6 @@ def add_to_datalad(topdir, studydir, msg=None, bids=False):
17271731
mark_sensitive(ds, '*/*/anat') # within subj/ses
17281732
if dsh:
17291733
mark_sensitive(dsh) # entire .heudiconv!
1730-
# import pdb; pdb.set_trace()
17311734
dsh.save(message=msg)
17321735
ds.save(message=msg, recursive=True, super_datasets=True)
17331736

0 commit comments

Comments
 (0)