6
6
import tarfile
7
7
8
8
from .external .pydicom import dcm
9
- from .utils import load_json , get_typed_attr , set_readonly , SeqInfo
9
+ from .utils import (
10
+ get_typed_attr ,
11
+ load_json ,
12
+ save_json ,
13
+ SeqInfo ,
14
+ set_readonly ,
15
+ )
10
16
11
17
import warnings
12
18
with warnings .catch_warnings ():
@@ -386,14 +392,10 @@ def _assign_dicom_time(ti):
386
392
return outtar
387
393
388
394
389
- def embed_nifti (dcmfiles , niftifile , infofile , bids_info , min_meta ):
390
- """
391
-
392
- If `niftifile` doesn't exist, it gets created out of the `dcmfiles` stack,
393
- and json representation of its meta_ext is returned (bug since should return
394
- both niftifile and infofile?)
395
+ def embed_dicom_and_nifti_metadata (dcmfiles , niftifile , infofile , bids_info ):
396
+ """Embed metadata from nifti (affine etc) and dicoms into infofile (json)
395
397
396
- if `niftifile` exists, its affine's orientation information is used while
398
+ `niftifile` should exist. Its affine's orientation information is used while
397
399
establishing new `NiftiImage` out of dicom stack and together with `bids_info`
398
400
(if provided) is dumped into json `infofile`
399
401
@@ -402,68 +404,52 @@ def embed_nifti(dcmfiles, niftifile, infofile, bids_info, min_meta):
402
404
dcmfiles
403
405
niftifile
404
406
infofile
405
- bids_info
406
- min_meta
407
-
408
- Returns
409
- -------
410
- niftifile, infofile
407
+ bids_info: dict
408
+ Additional metadata to be embedded. `infofile` is overwritten if exists,
409
+ so here you could pass some metadata which would overload (at the first
410
+ level of the dict structure, no recursive fancy updates) what is obtained
411
+ from nifti and dicoms
411
412
412
413
"""
413
414
# imports for nipype
414
415
import nibabel as nb
415
416
import os .path as op
416
417
import json
417
418
import re
419
+ from heudiconv .utils import save_json
420
+
421
+ from heudiconv .external .dcmstack import ds
422
+ stack = ds .parse_and_stack (dcmfiles , force = True ).values ()
423
+ if len (stack ) > 1 :
424
+ raise ValueError ('Found multiple series' )
425
+ # may be odict now - iter to be safe
426
+ stack = next (iter (stack ))
427
+
428
+ if not op .exists (niftifile ):
429
+ raise NotImplementedError (
430
+ "%s does not exist. "
431
+ "We are not producing new nifti files here any longer. "
432
+ "Use dcm2niix directly or .convert.nipype_convert helper ."
433
+ % niftifile
434
+ )
418
435
419
- if not min_meta :
420
- from heudiconv .external .dcmstack import ds
421
- stack = ds .parse_and_stack (dcmfiles , force = True ).values ()
422
- if len (stack ) > 1 :
423
- raise ValueError ('Found multiple series' )
424
- # may be odict now - iter to be safe
425
- stack = next (iter (stack ))
426
-
427
- # Create the nifti image using the data array
428
- if not op .exists (niftifile ):
429
- nifti_image = stack .to_nifti (embed_meta = True )
430
- nifti_image .to_filename (niftifile )
431
- return ds .NiftiWrapper (nifti_image ).meta_ext .to_json ()
432
-
433
- orig_nii = nb .load (niftifile )
434
- aff = orig_nii .affine
435
- ornt = nb .orientations .io_orientation (aff )
436
- axcodes = nb .orientations .ornt2axcodes (ornt )
437
- new_nii = stack .to_nifti (voxel_order = '' .join (axcodes ), embed_meta = True )
438
- meta = ds .NiftiWrapper (new_nii ).meta_ext .to_json ()
439
-
440
- meta_info = None if min_meta else json .loads (meta )
436
+ orig_nii = nb .load (niftifile )
437
+ aff = orig_nii .affine
438
+ ornt = nb .orientations .io_orientation (aff )
439
+ axcodes = nb .orientations .ornt2axcodes (ornt )
440
+ new_nii = stack .to_nifti (voxel_order = '' .join (axcodes ), embed_meta = True )
441
+ meta_info = ds .NiftiWrapper (new_nii ).meta_ext .to_json ()
442
+ meta_info = json .loads (meta_info )
441
443
442
444
if bids_info :
445
+ meta_info .update (bids_info )
443
446
444
- if min_meta :
445
- meta_info = bids_info
446
- else :
447
- # make nice with python 3 - same behavior?
448
- meta_info = meta_info .copy ()
449
- meta_info .update (bids_info )
450
- # meta_info = dict(meta_info.items() + bids_info.items())
451
- try :
452
- meta_info ['TaskName' ] = re .search (
453
- r'(?<=_task-)\w+' , op .basename (infofile )
454
- ).group (0 ).split ('_' )[0 ]
455
- except AttributeError :
456
- pass
457
447
# write to outfile
458
- with open (infofile , 'wt' ) as fp :
459
- json .dump (meta_info , fp , indent = 3 , sort_keys = True )
460
-
461
- return niftifile , infofile
448
+ save_json (infofile , meta_info )
462
449
463
450
464
451
def embed_metadata_from_dicoms (bids_options , item_dicoms , outname , outname_bids ,
465
- prov_file , scaninfo , tempdirs , with_prov ,
466
- min_meta ):
452
+ prov_file , scaninfo , tempdirs , with_prov ):
467
453
"""
468
454
Enhance sidecar information file with more information from DICOMs
469
455
@@ -477,7 +463,6 @@ def embed_metadata_from_dicoms(bids_options, item_dicoms, outname, outname_bids,
477
463
scaninfo
478
464
tempdirs
479
465
with_prov
480
- min_meta
481
466
482
467
Returns
483
468
-------
@@ -490,14 +475,13 @@ def embed_metadata_from_dicoms(bids_options, item_dicoms, outname, outname_bids,
490
475
item_dicoms = list (map (op .abspath , item_dicoms ))
491
476
492
477
embedfunc = Node (Function (input_names = ['dcmfiles' , 'niftifile' , 'infofile' ,
493
- 'bids_info' , 'min_meta' ],
478
+ 'bids_info' ,],
494
479
output_names = ['outfile' , 'meta' ],
495
- function = embed_nifti ),
480
+ function = embed_dicom_and_nifti_metadata ),
496
481
name = 'embedder' )
497
482
embedfunc .inputs .dcmfiles = item_dicoms
498
483
embedfunc .inputs .niftifile = op .abspath (outname )
499
484
embedfunc .inputs .infofile = op .abspath (scaninfo )
500
- embedfunc .inputs .min_meta = min_meta
501
485
embedfunc .inputs .bids_info = load_json (op .abspath (outname_bids )) if (bids_options is not None ) else None
502
486
embedfunc .base_dir = tmpdir
503
487
cwd = os .getcwd ()
0 commit comments