Skip to content

Commit 65dbc3c

Browse files
committed
Merge remote-tracking branch 'origin/master' into merge-enh-dbic2
* origin/master: fix: update heuristics to new style quick and dirty symlink fix for #120 Minor tune ups to README
2 parents 9780253 + 35e95b6 commit 65dbc3c

File tree

4 files changed

+63
-47
lines changed

4 files changed

+63
-47
lines changed

README.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,37 @@ structured directory layouts.
1212
- it's faster than parsesdicomdir or mri_convert if you use dcm2niix option
1313
- it tracks the provenance of the conversion from DICOM to NIfTI in W3C
1414
PROV format
15-
- the cmrr_heuristic example shows a conversion to [BIDS](http://bids.neuroimaging.io)
16-
layout structure
15+
- it provides assistance in converting to [BIDS]
16+
- it integrates with [DataLad] to place converted and original data
17+
under git/git-annex version control, while automatically annotating files
18+
with sensitive information (e.g., non-defaced anatomicals, etc)
19+
20+
### Heuristics
21+
22+
HeuDiConv operates using a heuristic, which provides information on
23+
how your files should be converted. A number of example heuristics are
24+
provided to address various use-cases
25+
26+
- the [cmrr_heuristic](heuristics/cmrr_heuristic.py) provides an
27+
example for a conversion to [BIDS]
28+
- the [dbic_bids](heuristics/dbic_bids.py) could be used to establish
29+
a complete imaging center wide automation to convert all acquired
30+
data to [BIDS] following a simple naming
31+
[convention](https://goo.gl/o0YASC) for studies and sequences
1732

1833
## Install
1934

35+
### Released versions
36+
37+
Released versions of HeuDiConv are available from PyPI so you could
38+
just `pip install heudiconv` but it would require manual installation
39+
of the [dcm2niix](https://github.com/rordenlab/dcm2niix/). On
40+
Debian-based systems we recommend to use
41+
[NeuroDebian](http://neuro.debian.net) providing
42+
[heudiconv Debian package](http://neuro.debian.net/pkgs/heudiconv.html).
43+
44+
### From source
45+
2046
You can clone this directory and do a `make install`
2147

2248
or `pip install https://github.com/nipy/heudiconv/archive/master.zip`
@@ -159,3 +185,6 @@ info[some_3-tuple] = [{'item': 12, 'acq': 'AP'},
159185
{'item': 14, 'acq': 'AP'},
160186
{'item': 16, 'acq': 'PA'}]
161187
```
188+
189+
[BIDS]: http://bids.neuroimaging.io
190+
[DataLad]: http://datalad.org

heudiconv/convert.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,10 +361,11 @@ def convert_dicom(item_dicoms, bids, prefix,
361361
outfile = op.join(dicomdir, op.basename(filename))
362362
if not op.islink(outfile):
363363
# TODO: add option to enable hardlink?
364-
if symlink:
365-
os.symlink(filename, outfile)
366-
else:
367-
os.link(filename, outfile)
364+
# if symlink:
365+
# os.symlink(filename, outfile)
366+
# else:
367+
# os.link(filename, outfile)
368+
shutil.copyfile(filename, outfile)
368369

369370

370371
def nipype_convert(item_dicoms, prefix, with_prov, bids, tmpdir):

heuristics/banda-bids.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ def infotodict(seqinfo):
1616
seqitem: run number during scanning
1717
subindex: sub index within group
1818
"""
19-
t1 = create_key('anat/sub-{subject}_T1w')
20-
t2 = create_key('anat/sub-{subject}_T2w')
21-
rest = create_key('func/sub-{subject}_task-rest_run-{item:02d}_bold')
22-
rest_sbref = create_key('func/sub-{subject}_task-rest_run-{item:02d}_sbref')
23-
face = create_key('func/sub-{subject}_task-face_run-{item:02d}_bold')
24-
face_sbref = create_key('func/sub-{subject}_task-face_run-{item:02d}_sbref')
25-
gamble = create_key('func/sub-{subject}_task-gambling_run-{item:02d}_bold')
26-
gamble_sbref = create_key('func/sub-{subject}_task-gambling_run-{item:02d}_sbref')
27-
conflict = create_key('func/sub-{subject}_task-conflict_run-{item:02d}_bold')
28-
conflict_sbref = create_key('func/sub-{subject}_task-conflict_run-{item:02d}_sbref')
29-
dwi = create_key('dwi/sub-{subject}_run-{item:02d}_dwi')
30-
dwi_sbref = create_key('dwi/sub-{subject}_run-{item:02d}_sbref')
31-
fmap = create_key('fmap/sub-{subject}_dir-{dir}_run-{item:02d}_epi')
19+
t1 = create_key('sub-{subject}/anat/sub-{subject}_T1w')
20+
t2 = create_key('sub-{subject}/anat/sub-{subject}_T2w')
21+
rest = create_key('sub-{subject}/func/sub-{subject}_task-rest_run-{item:02d}_bold')
22+
rest_sbref = create_key('sub-{subject}/func/sub-{subject}_task-rest_run-{item:02d}_sbref')
23+
face = create_key('sub-{subject}/func/sub-{subject}_task-face_run-{item:02d}_bold')
24+
face_sbref = create_key('sub-{subject}/func/sub-{subject}_task-face_run-{item:02d}_sbref')
25+
gamble = create_key('sub-{subject}/func/sub-{subject}_task-gambling_run-{item:02d}_bold')
26+
gamble_sbref = create_key('sub-{subject}/func/sub-{subject}_task-gambling_run-{item:02d}_sbref')
27+
conflict = create_key('sub-{subject}/func/sub-{subject}_task-conflict_run-{item:02d}_bold')
28+
conflict_sbref = create_key('sub-{subject}/func/sub-{subject}_task-conflict_run-{item:02d}_sbref')
29+
dwi = create_key('sub-{subject}/dwi/sub-{subject}_run-{item:02d}_dwi')
30+
dwi_sbref = create_key('sub-{subject}/dwi/sub-{subject}_run-{item:02d}_sbref')
31+
fmap = create_key('sub-{subject}/fmap/sub-{subject}_dir-{dir}_run-{item:02d}_epi')
3232

3333
info = {t1:[], t2:[],
3434
rest:[], face:[], gamble:[], conflict:[], dwi:[],

heuristics/bids_with_ses.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,21 @@ def infotodict(seqinfo):
1818
subindex: sub index within group
1919
session: scan index for longitudinal acq
2020
"""
21-
and_dicom = ('dicom', 'nii.gz')
21+
# for this example, we want to include copies of the DICOMs just for our T1
22+
# and functional scans
23+
outdicom = ('dicom', 'nii.gz')
2224

23-
t1 = create_key('{session}/anat/sub-{subject}_T1w', outtype=and_dicom)
24-
t2 = create_key('{session}/anat/sub-{subject}_T2w', outtype=and_dicom)
25-
fm_diff = create_key('{session}/fmap/sub-{subject}_fieldmap-dwi')
26-
dwi_ap = create_key('{session}/dwi/sub-{subject}_dir-AP_dwi', outtype=and_dicom)
27-
dwi_pa = create_key('{session}/dwi/sub-{subject}_dir-PA_dwi', outtype=and_dicom)
28-
fm_rest= create_key('{session}/fmap/sub-{subject}_fieldmap-rest')
29-
rs = create_key('{session}/func/sub-{subject}_task-rest_run-{item:02d}_bold', outtype=and_dicom)
30-
boldt1 = create_key('{session}/func/sub-{subject}_task-bird1back_run-{item:02d}_bold', outtype=and_dicom)
31-
boldt2 = create_key('{session}/func/sub-{subject}_task-letter1back_run-{item:02d}_bold', outtype=and_dicom)
32-
boldt3 = create_key('{session}/func/sub-{subject}_task-letter2back_run-{item:02d}_bold', outtype=and_dicom)
33-
nofb_task=create_key('{session}/func/sub-{subject}_task-nofb_run-{item:02d}_bold', outtype=and_dicom)
34-
fb_task=create_key('{session}/func/sub-{subject}_task-fb_run-{item:02d}_bold', outtype=and_dicom)
35-
info = {t1: [], t2:[], fm_diff:[], dwi_ap:[], dwi_pa:[], fm_rest:[], rs:[],
36-
boldt1:[], boldt2:[], boldt3:[], nofb_task:[], fb_task:[]}
25+
t1 = create_key('{bids_subject_session_dir}/anat/{bids_subject_session_prefix}_T1w', outtype=outdicom)
26+
t2 = create_key('{bids_subject_session_dir}/anat/{bids_subject_session_prefix}_T2w')
27+
dwi_ap = create_key('{bids_subject_session_dir}/dwi/{bids_subject_session_prefix}_dir-AP_dwi')
28+
dwi_pa = create_key('{bids_subject_session_dir}/dwi/{bids_subject_session_prefix}_dir-PA_dwi')
29+
rs = create_key('{bids_subject_session_dir}/func/{bids_subject_session_prefix}_task-rest_run-{item:02d}_bold', outtype=outdicom)
30+
boldt1 = create_key('{bids_subject_session_dir}/func/{bids_subject_session_prefix}_task-bird1back_run-{item:02d}_bold', outtype=outdicom)
31+
boldt2 = create_key('{bids_subject_session_dir}/func/{bids_subject_session_prefix}_task-letter1back_run-{item:02d}_bold', outtype=outdicom)
32+
boldt3 = create_key('{bids_subject_session_dir}/func/{bids_subject_session_prefix}_task-letter2back_run-{item:02d}_bold', outtype=outdicom)
33+
34+
info = {t1: [], t2:[], dwi_ap:[], dwi_pa:[], rs:[],
35+
boldt1:[], boldt2:[], boldt3:[],}
3736
last_run = len(seqinfo)
3837
for s in seqinfo:
3938
if (s.dim3 == 176 or s.dim3 == 352) and (s.dim4 == 1) and ('MEMPRAGE' in s.protocol_name):
@@ -42,14 +41,10 @@ def infotodict(seqinfo):
4241
info[t1] = [s.series_id]
4342
elif (s.dim3 == 176 or s.dim3 == 352) and (s.dim4 == 1) and ('T2_SPACE' in s.protocol_name):
4443
info[t2] = [s.series_id]
45-
elif ('field_mapping_diffusion' in s.protocol_name):
46-
info[fm_diff].append([s.series_id])
4744
elif (s.dim4 >= 70) and ('DIFFUSION_HighRes_AP' in s.protocol_name):
4845
info[dwi_ap].append([s.series_id])
4946
elif ('DIFFUSION_HighRes_PA' in s.protocol_name):
5047
info[dwi_pa].append([s.series_id])
51-
elif ('field_mapping_resting' in s.protocol_name):
52-
info[fm_rest].append([s.series_id])
5348
elif (s.dim4 == 144) and ('resting' in s.protocol_name):
5449
if not s.is_motion_corrected:
5550
info[rs].append([(s.series_id)])
@@ -62,13 +57,4 @@ def infotodict(seqinfo):
6257
elif (s.dim4 == 227 or s.dim4 == 454) and ('transfer2' in s.protocol_name):
6358
if not s.is_motion_corrected:
6459
info[boldt3].append([s.series_id])
65-
elif (('run1' in s.protocol_name) or ('run6' in s.protocol_name)) and (s.dim4 == 159):
66-
if not s.is_motion_corrected:
67-
info[nofb_task].append([s.series_id])
68-
elif (('run2' in s.protocol_name) or ('run3' in s.protocol_name) or ('run4' in s.protocol_name)
69-
or ('run5' in s.protocol_name)) and (s.dim4 == 159):
70-
if not s.is_motion_corrected:
71-
info[fb_task].append([s.series_id])
72-
else:
73-
pass
7460
return info

0 commit comments

Comments
 (0)