Skip to content

Commit 599cb83

Browse files
authored
Merge pull request #489 from cbinyu/handles_phoenix_file
ENH: Allows the user to save the Phoenix Report in the sourcedata folder
2 parents d8e5c5f + fe3fc34 commit 599cb83

File tree

6 files changed

+84
-3
lines changed

6 files changed

+84
-3
lines changed

heudiconv/dicoms.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,13 @@ def group_dicoms_into_seqinfos(files, grouping, file_filter=None,
265265
series_id = '-'.join(map(str, series_id))
266266
if mw.image_shape is None:
267267
# this whole thing has no image data (maybe just PSg DICOMs)
268-
# nothing to see here, just move on
269-
continue
268+
# If this is a Siemens PhoenixZipReport or PhysioLog, keep it:
269+
if mw.dcm_data.SeriesDescription == 'PhoenixZIPReport':
270+
# give it a dummy shape, so that we can continue:
271+
mw.image_shape = (0, 0, 0)
272+
else:
273+
# nothing to see here, just move on
274+
continue
270275
seqinfo = create_seqinfo(mw, series_files, series_id)
271276

272277
if per_studyUID:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Heuristic demonstrating conversion of the PhoenixZIPReport from Siemens.
2+
3+
It only cares about converting a series with have PhoenixZIPReport in their
4+
series_description and outputs **only to sourcedata**.
5+
"""
6+
7+
8+
def create_key(template, outtype=('nii.gz',), annotation_classes=None):
9+
if template is None or not template:
10+
raise ValueError('Template must be a valid format string')
11+
return template, outtype, annotation_classes
12+
13+
14+
def infotodict(seqinfo):
15+
"""Heuristic evaluator for determining which runs belong where
16+
17+
allowed template fields - follow python string module:
18+
19+
item: index within category
20+
subject: participant id
21+
seqitem: run number during scanning
22+
subindex: sub index within group
23+
"""
24+
sbref = create_key('sub-{subject}/func/sub-{subject}_task-QA_sbref', outtype=('nii.gz', 'dicom',))
25+
scout = create_key('sub-{subject}/anat/sub-{subject}_T1w', outtype=('nii.gz', 'dicom',))
26+
phoenix_doc = create_key('sub-{subject}/misc/sub-{subject}_phoenix', outtype=('dicom',))
27+
28+
info = {sbref: [], scout: [], phoenix_doc: []}
29+
for s in seqinfo:
30+
if (
31+
'PhoenixZIPReport' in s.series_description
32+
and s.image_type[3] == 'CSA REPORT'
33+
):
34+
info[phoenix_doc].append({'item': s.series_id})
35+
if 'scout' in s.series_description.lower():
36+
info[scout].append({'item': s.series_id})
37+
38+
return info
Binary file not shown.
Binary file not shown.

heudiconv/tests/test_dicoms.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
import os.path as op
22
import json
3+
from glob import glob
34

45
import pytest
56

67
from heudiconv.external.pydicom import dcm
78
from heudiconv.cli.run import main as runner
89
from heudiconv.convert import nipype_convert
9-
from heudiconv.dicoms import parse_private_csa_header, embed_dicom_and_nifti_metadata
10+
from heudiconv.dicoms import (
11+
OrderedDict,
12+
embed_dicom_and_nifti_metadata,
13+
group_dicoms_into_seqinfos,
14+
parse_private_csa_header,
15+
)
1016
from .utils import (
1117
assert_cwd_unchanged,
1218
TESTS_DATA_PATH,
@@ -64,3 +70,18 @@ def test_embed_dicom_and_nifti_metadata(tmpdir):
6470

6571
assert out3.pop("existing") == "data"
6672
assert out3 == out2
73+
74+
75+
def test_group_dicoms_into_seqinfos(tmpdir):
76+
"""Tests for group_dicoms_into_seqinfos"""
77+
78+
# 1) Check that it works for PhoenixDocuments:
79+
# set up testing files
80+
dcmfolder = op.join(TESTS_DATA_PATH, 'Phoenix')
81+
dcmfiles = glob(op.join(dcmfolder, '*', '*.dcm'))
82+
83+
seqinfo = group_dicoms_into_seqinfos(dcmfiles, 'studyUID', flatten=True)
84+
85+
assert type(seqinfo) is OrderedDict
86+
assert len(seqinfo) == len(dcmfiles)
87+
assert [s.series_description for s in seqinfo] == ['AAHead_Scout_32ch-head-coil', 'PhoenixZIPReport']

heudiconv/tests/test_heuristics.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,3 +176,20 @@ def test_notop(tmpdir, bidsoptions):
176176
assert not op.exists(pjoin(tmppath, 'Halchenko/Yarik/950_bids_test4', fname))
177177
else:
178178
assert op.exists(pjoin(tmppath, 'Halchenko/Yarik/950_bids_test4', fname))
179+
180+
181+
def test_phoenix_doc_conversion(tmpdir):
182+
tmppath = tmpdir.strpath
183+
subID = 'Phoenix'
184+
args = (
185+
"-c dcm2niix -o %s -b -f bids_PhoenixReport --files %s -s %s"
186+
% (tmpdir, pjoin(TESTS_DATA_PATH, 'Phoenix'), subID)
187+
).split(' ')
188+
runner(args)
189+
190+
# check that the Phoenix document has been extracted (as gzipped dicom) in
191+
# the sourcedata/misc folder:
192+
assert op.exists(pjoin(tmppath, 'sourcedata', 'sub-%s', 'misc', 'sub-%s_phoenix.dicom.tgz') % (subID, subID))
193+
# check that no "sub-<subID>/misc" folder has been created in the BIDS
194+
# structure:
195+
assert not op.exists(pjoin(tmppath, 'sub-%s', 'misc') % subID)

0 commit comments

Comments
 (0)