Skip to content

Commit 6034bd4

Browse files
committed
Merge remote-tracking branch 'origin/master' into mbme-reproin
* origin/master: (32 commits) ENH(TST): skip test_dlad.py if no datalad.api ENH: reproin validator config - ignore absence of custom column description [DATALAD RUNCMD] Update versions to the next version (as in changelog) helper makefile ENH: a helper to prepare release CHANGELOG for 0.7.0 BF: #427 Sort of None echotime was not working. Replaced with nan DOC: basic doc about "-g custom" BF(PY<3.7): just sample the class of a compiled regex RF+ENH: allow matching study using regexp on study_description ENH: reproin - log applied substitutions ENH(TST): test application of "catch all" rule RF: reproin - remove binding of fixup data structures in function signatures RF+ENH: reproin - allow for an empty key in protocols2fix to provide fixups for any study fix: remove filtered DICOMs from file list enh: improve regression test fix: changes from code review RF: return back indexes in comments for seqinfo_fields Minor DOC (explicit list of values in numpy doc style) and remove ambiguity in reading comparison ci: remove 34 testing, add 37 ... Conflicts: heudiconv/convert.py - conflicted with using nan instead of None for EchoTime
2 parents 6046dc0 + 09f7501 commit 6034bd4

File tree

19 files changed

+480
-267
lines changed

19 files changed

+480
-267
lines changed

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,36 @@ All notable changes to this project will be documented (for humans) in this file
44
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

7+
## [0.7.0] - 2020-03-20
8+
9+
### Removed
10+
11+
- Python 2 support/testing
12+
13+
### Enhancement
14+
15+
- `-g` option obtained two new modes: `all` and `custom`. In case of `all`,
16+
all provided DICOMs will be treated as coming from a single scanning session.
17+
`custom` instructs to use `.grouping` value (could be a DICOM attribute or
18+
a callable)provided by the heuristic ([#359][]).
19+
- Stop before reading pixels data while gathering metadata from DICOMs ([#404][])
20+
- reproin heuristic:
21+
- In addition to original "md5sum of the study_description" `protocols2fix`
22+
could now have (and applied after md5sum matching ones)
23+
1). a regular expression searched in study_description,
24+
2). an empty string as "catch all".
25+
This features could be used to easily provide remapping into reproin
26+
naming (documentation is to come to http://github.com/ReproNim/reproin)
27+
([#425][])
28+
29+
### Fixed
30+
31+
- Use nan, not None for absent echo value in sorting
32+
- reproin heuristic: case seqinfos into a list to be able to modify from
33+
overloaded heuristic ([#419][])
34+
- No spurious errors from the logger upon a warning about `etelemetry`
35+
absence ([#407][])
36+
737
## [0.6.0] - 2019-12-16
838

939
This is largely a bug fix. Metadata and order of `_key-value` fields in BIDS
@@ -271,6 +301,7 @@ TODO Summary
271301
[#348]: https://github.com/nipy/heudiconv/issues/348
272302
[#351]: https://github.com/nipy/heudiconv/issues/351
273303
[#352]: https://github.com/nipy/heudiconv/issues/352
304+
[#359]: https://github.com/nipy/heudiconv/issues/359
274305
[#360]: https://github.com/nipy/heudiconv/issues/360
275306
[#364]: https://github.com/nipy/heudiconv/issues/364
276307
[#369]: https://github.com/nipy/heudiconv/issues/369
@@ -280,3 +311,7 @@ TODO Summary
280311
[#379]: https://github.com/nipy/heudiconv/issues/379
281312
[#380]: https://github.com/nipy/heudiconv/issues/380
282313
[#390]: https://github.com/nipy/heudiconv/issues/390
314+
[#404]: https://github.com/nipy/heudiconv/issues/404
315+
[#407]: https://github.com/nipy/heudiconv/issues/407
316+
[#419]: https://github.com/nipy/heudiconv/issues/419
317+
[#425]: https://github.com/nipy/heudiconv/issues/425

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
all:
2+
echo 'nothing by default'
3+
4+
prep_release:
5+
# take previous one, and replace with the next one
6+
utils/prep_release

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
# The short X.Y version
2727
version = ''
2828
# The full version, including alpha/beta/rc tags
29-
release = '0.6.0'
29+
release = '0.7.0'
3030

3131

3232
# -- General configuration ---------------------------------------------------

docs/heuristics.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,20 @@ DICOMs where this function returns ``True`` will be filtered out.
6868
Further processing on ``seqinfos`` to deduce/customize subject, session, and locator.
6969

7070
A dictionary of {"locator": locator, "session": session, "subject": subject} is returned.
71+
72+
---------------------------------------------------------------
73+
``grouping`` string or ``grouping(files, dcmfilter, seqinfo)``
74+
---------------------------------------------------------------
75+
76+
Whenever ``--grouping custom`` (``-g custom``) is used, this attribute or callable
77+
will be used to inform how to group the DICOMs into separate groups. From
78+
`original PR#359 <https://github.com/nipy/heudiconv/pull/359>`_::
79+
80+
grouping = 'AcquisitionDate'
81+
82+
or::
83+
84+
def grouping(files, dcmfilter, seqinfo):
85+
seqinfos = collections.OrderedDict()
86+
...
87+
return seqinfos # ordered dict containing seqinfo objects: list of DICOMs

docs/installation.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ If `Docker <https://docs.docker.com/install/>`_ is available on your system, you
2626
can visit `our page on Docker Hub <https://hub.docker.com/r/nipy/heudiconv/tags>`_
2727
to view available releases. To pull the latest release, run::
2828

29-
$ docker pull nipy/heudiconv:0.6.0
29+
$ docker pull nipy/heudiconv:0.7.0
3030

3131

3232
Singularity
@@ -35,4 +35,4 @@ If `Singularity <https://www.sylabs.io/singularity/>`_ is available on your syst
3535
you can use it to pull and convert our Docker images! For example, to pull and
3636
build the latest release, you can run::
3737

38-
$ singularity pull docker://nipy/heudiconv:0.6.0
38+
$ singularity pull docker://nipy/heudiconv:0.7.0

docs/usage.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ The second script processes a DICOM directory with ``heudiconv`` using the built
8282
DCMDIR=${DCMDIRS[${SLURM_ARRAY_TASK_ID}]}
8383
echo Submitted directory: ${DCMDIR}
8484
85-
IMG="/singularity-images/heudiconv-0.6.0-dev.sif"
85+
IMG="/singularity-images/heudiconv-0.7.0-dev.sif"
8686
CMD="singularity run -B ${DCMDIR}:/dicoms:ro -B ${OUTDIR}:/output -e ${IMG} --files /dicoms/ -o /output -f reproin -c dcm2niix -b notop --minmeta -l ."
8787
8888
printf "Command:\n${CMD}\n"
@@ -97,7 +97,7 @@ This script creates the top-level bids files (e.g.,
9797
set -eu
9898

9999
OUTDIR=${1}
100-
IMG="/singularity-images/heudiconv-0.6.0-dev.sif"
100+
IMG="/singularity-images/heudiconv-0.7.0-dev.sif"
101101
CMD="singularity run -B ${OUTDIR}:/output -e ${IMG} --files /output -f reproin --command populate-templates"
102102

103103
printf "Command:\n${CMD}\n"

heudiconv/cli/run.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ def main(argv=None):
124124

125125
if args.debug:
126126
setup_exceptionhook()
127-
128127
process_args(args)
129128

130129

@@ -154,8 +153,7 @@ def get_parser():
154153
'If not provided, DICOMS would first be "sorted" and '
155154
'subject IDs deduced by the heuristic')
156155
parser.add_argument('-c', '--converter',
157-
default='dcm2niix',
158-
choices=('dcm2niix', 'none'),
156+
choices=('dcm2niix', 'none'), default='dcm2niix',
159157
help='tool to use for DICOM conversion. Setting to '
160158
'"none" disables the actual conversion step -- useful'
161159
'for testing heuristics.')
@@ -219,7 +217,7 @@ def get_parser():
219217
help='custom actions to be performed on provided '
220218
'files instead of regular operation.')
221219
parser.add_argument('-g', '--grouping', default='studyUID',
222-
choices=('studyUID', 'accession_number'),
220+
choices=('studyUID', 'accession_number', 'all', 'custom'),
223221
help='How to group dicoms (default: by studyUID)')
224222
parser.add_argument('--minmeta', action='store_true',
225223
help='Exclude dcmstack meta information in sidecar '
@@ -343,7 +341,8 @@ def process_args(args):
343341
seqinfo=seqinfo,
344342
min_meta=args.minmeta,
345343
overwrite=args.overwrite,
346-
dcmconfig=args.dcmconfig,)
344+
dcmconfig=args.dcmconfig,
345+
grouping=args.grouping,)
347346

348347
lgr.info("PROCESSING DONE: {0}".format(
349348
str(dict(subject=sid, outdir=study_outdir, session=session))))

heudiconv/convert.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import os
33
import os.path as op
44
import logging
5+
from math import nan
56
import shutil
67
import sys
78

@@ -80,8 +81,8 @@ def conversion_info(subject, outdir, info, filegroup, ses):
8081

8182

8283
def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
83-
anon_outdir, with_prov, ses, bids_options, seqinfo, min_meta,
84-
overwrite, dcmconfig):
84+
anon_outdir, with_prov, ses, bids_options, seqinfo,
85+
min_meta, overwrite, dcmconfig, grouping):
8586
if dicoms:
8687
lgr.info("Processing %d dicoms", len(dicoms))
8788
elif seqinfo:
@@ -157,16 +158,17 @@ def prep_conversion(sid, dicoms, outdir, heuristic, converter, anon_sid,
157158
# So either it would need to be brought back or reconsidered altogether
158159
# (since no sample data to test on etc)
159160
else:
160-
# TODO -- might have been done outside already!
161-
# MG -- will have to try with both dicom template, files
162161
assure_no_file_exists(target_heuristic_filename)
163162
safe_copyfile(heuristic.filename, target_heuristic_filename)
164163
if dicoms:
165164
seqinfo = group_dicoms_into_seqinfos(
166165
dicoms,
166+
grouping,
167167
file_filter=getattr(heuristic, 'filter_files', None),
168168
dcmfilter=getattr(heuristic, 'filter_dicom', None),
169-
grouping=None)
169+
flatten=True,
170+
custom_grouping=getattr(heuristic, 'grouping', None))
171+
170172
seqinfo_list = list(seqinfo.keys())
171173
filegroup = {si.series_id: x for si, x in seqinfo.items()}
172174
dicominfo_file = op.join(idir, 'dicominfo%s.tsv' % ses_suffix)
@@ -531,7 +533,7 @@ def save_converted_files(res, item_dicoms, bids_options, outtype, prefix, outnam
531533

532534
# Check for varying echo times
533535
echo_times = sorted(list(set(
534-
b.get('EchoTime', None)
536+
b.get('EchoTime', nan)
535537
for b in bids_metas
536538
if b
537539
)))

0 commit comments

Comments
 (0)