1
1
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
2
2
# vi: set ft=python sts=4 ts=4 sw=4 et:
3
3
"""Interfaces to generate speciality reportlets."""
4
+ import numpy as np
4
5
from nilearn .image import threshold_img , load_img
5
6
from niworkflows import NIWORKFLOWS_LOG
6
7
from niworkflows .viz .utils import cuts_from_bbox , compose_view
7
- from nipype .interfaces .base import File , isdefined
8
+ from nipype .interfaces .base import File , isdefined , traits
8
9
from nipype .interfaces .mixins import reporting
9
10
10
11
from ..viz .utils import plot_registration , coolwarm_transparent
11
12
12
13
13
14
class _FieldmapReportletInputSpec (reporting .ReportCapableInputSpec ):
14
15
reference = File (exists = True , mandatory = True , desc = 'input reference' )
16
+ moving = File (exists = True , desc = 'input moving' )
15
17
fieldmap = File (exists = True , mandatory = True , desc = 'input fieldmap' )
18
+ max_alpha = traits .Float (0.7 , usedefault = True , desc = 'maximum alpha channel' )
16
19
mask = File (exists = True , desc = 'brain mask' )
17
20
out_report = File ('report.svg' , usedefault = True ,
18
21
desc = 'filename for the visual report' )
22
+ show = traits .Enum (1 , 0 , 'both' , usedefault = True ,
23
+ desc = 'where the fieldmap should be shown' )
19
24
20
25
21
26
class FieldmapReportlet (reporting .ReportCapableInterface ):
@@ -39,28 +44,46 @@ def _generate_report(self):
39
44
40
45
refnii = load_img (self .inputs .reference )
41
46
fmapnii = load_img (self .inputs .fieldmap )
42
- contour_nii = load_img (self .inputs .mask ) if isdefined (self .inputs .mask ) else None
43
- mask_nii = threshold_img (refnii , 1e-3 )
47
+
48
+ contour_nii = mask_nii = None
49
+ if isdefined (self .inputs .mask ):
50
+ contour_nii = load_img (self .inputs .mask )
51
+ maskdata = contour_nii .get_fdata () > 0
52
+ else :
53
+ mask_nii = threshold_img (refnii , 1e-3 )
54
+ maskdata = mask_nii .get_fdata () > 0
44
55
cuts = cuts_from_bbox (contour_nii or mask_nii , cuts = self ._n_cuts )
45
56
fmapdata = fmapnii .get_fdata ()
46
- vmax = max (fmapdata .max (), abs (fmapdata .min ()))
57
+ vmax = max (abs (np .percentile (fmapdata [maskdata ], 99.8 )),
58
+ abs (np .percentile (fmapdata [maskdata ], 0.2 )))
59
+
60
+ fmap_overlay = [{
61
+ 'overlay' : fmapnii ,
62
+ 'overlay_params' : {
63
+ 'cmap' : coolwarm_transparent (max_alpha = self .inputs .max_alpha ),
64
+ 'vmax' : vmax ,
65
+ 'vmin' : - vmax ,
66
+ }
67
+ }] * 2
68
+
69
+ if self .inputs .show != 'both' :
70
+ fmap_overlay [not self .inputs .show ] = {}
47
71
48
72
# Call composer
49
73
compose_view (
50
- plot_registration (refnii , 'fixed -image' ,
74
+ plot_registration (refnii , 'moving -image' ,
51
75
estimate_brightness = True ,
52
76
cuts = cuts ,
53
- label = 'reference ' ,
77
+ label = 'fieldmap (Hz) ' ,
54
78
contour = contour_nii ,
55
- compress = False ),
56
- plot_registration (fmapnii , 'moving-image' ,
79
+ compress = False ,
80
+ ** fmap_overlay [1 ]),
81
+ plot_registration (refnii , 'fixed-image' ,
57
82
estimate_brightness = True ,
58
83
cuts = cuts ,
59
- label = 'fieldmap (Hz) ' ,
84
+ label = 'reference ' ,
60
85
contour = contour_nii ,
61
86
compress = False ,
62
- plot_params = {'cmap' : coolwarm_transparent (),
63
- 'vmax' : vmax ,
64
- 'vmin' : - vmax }),
87
+ ** fmap_overlay [0 ]),
65
88
out_file = self ._out_report
66
89
)
0 commit comments