def _generate_report(self): ''' Construct a parcellation overlay image ''' import niworkflows.viz.utils as nwviz from ..patches.niworkflows import _3d_in_file, _plot_anat_with_contours ''' MONKEY PATCH: _3d_in_file in niworkflows.viz.utils cannot accept Nifti1Images as inputs. This is a small patch that will stop it from failing when this is the case ''' # _3d_in_file more robust to accepting a Nifti1Image nwviz._3d_in_file = _3d_in_file # plot_anat_with_contours accepts filled nwviz._plot_anat_with_contours = _plot_anat_with_contours segs = _parcel2segs(self._parcellation) nwviz.compose_view( nwviz.plot_segs( image_nii=self._bg_nii, seg_niis=segs, bbox_nii=self._mask_nii, out_file=None, # this arg doesn't matter colors=self._colors, filled=True, alpha=0.3), fg_svgs=None, out_file=self._out_report)
def _run_interface(self, runtime): from niworkflows.viz.utils import plot_registration, cuts_from_bbox, compose_view from nilearn.image import load_img rootdir = Path(self.inputs.subjects_dir) / self.inputs.subject_id _anat_file = str(rootdir / 'mri' / 'brain.mgz') _contour_file = str(rootdir / 'mri' / 'ribbon.mgz') anat = load_img(_anat_file) contour_nii = load_img(_contour_file) n_cuts = 7 cuts = cuts_from_bbox(contour_nii, cuts=n_cuts) self._results['out_report'] = str( Path(runtime.cwd) / self.inputs.out_report) # Call composer compose_view(plot_registration(anat, 'fixed-image', estimate_brightness=True, cuts=cuts, contour=contour_nii, compress=self.inputs.compress_report), [], out_file=self._results['out_report']) return runtime
def _generate_report(self): """ Generates the visual report """ from niworkflows.viz.utils import compose_view, plot_registration NIWORKFLOWS_LOG.info('Generating visual report') anat = load_img(self._anat_file) contour_nii = load_img( self._contour) if self._contour is not None else None if self._mask_file: anat = unmask(apply_mask(anat, self._mask_file), self._mask_file) mask_nii = load_img(self._mask_file) else: mask_nii = threshold_img(anat, 1e-3) n_cuts = 7 if not self._mask_file and contour_nii: cuts = cuts_from_bbox(contour_nii, cuts=n_cuts) else: cuts = cuts_from_bbox(mask_nii, cuts=n_cuts) # Call composer compose_view(plot_registration(anat, 'fixed-image', estimate_brightness=True, cuts=cuts, contour=contour_nii, compress=self.inputs.compress_report), [], out_file=self._out_report)
def _generate_report(self): """Generate a reportlet.""" NIWORKFLOWS_LOG.info('Generating visual report') refnii = load_img(self.inputs.reference) fmapnii = load_img(self.inputs.fieldmap) contour_nii = load_img(self.inputs.mask) if isdefined( self.inputs.mask) else None mask_nii = threshold_img(refnii, 1e-3) cuts = cuts_from_bbox(contour_nii or mask_nii, cuts=self._n_cuts) fmapdata = fmapnii.get_fdata() vmax = max(fmapdata.max(), abs(fmapdata.min())) # Call composer compose_view(plot_registration(refnii, 'fixed-image', estimate_brightness=True, cuts=cuts, label='reference', contour=contour_nii, compress=False), plot_registration(fmapnii, 'moving-image', estimate_brightness=True, cuts=cuts, label='fieldmap (Hz)', contour=contour_nii, compress=False, plot_params={ 'cmap': coolwarm_transparent(), 'vmax': vmax, 'vmin': -vmax }), out_file=self._out_report)
def _run_interface(self, runtime): from niworkflows.viz.utils import ( plot_registration, cuts_from_bbox, compose_view, ) from nibabel import load rootdir = Path(self.inputs.subjects_dir) / self.inputs.subject_id _anat_file = str(rootdir / "mri" / "brain.mgz") _contour_file = str(rootdir / "mri" / "ribbon.mgz") anat = load(_anat_file) contour_nii = load(_contour_file) n_cuts = 7 cuts = cuts_from_bbox(contour_nii, cuts=n_cuts) self._results["out_report"] = str(Path(runtime.cwd) / self.inputs.out_report) # Call composer compose_view( plot_registration( anat, "fixed-image", estimate_brightness=True, cuts=cuts, contour=contour_nii, compress=self.inputs.compress_report, ), [], out_file=self._results["out_report"], ) return runtime
def make_brain(*, anatomical, mask, out_file): """ Creates `out_file`.svg of brain `mask` on input `anatomical` Parameters ---------- anatomical : str Path to anatomical T1w image (*with skull*) mask : str Path to brain mask file out_file : str Path to where svg will be saved Returns ------- out_file : str Where svg was saved """ if not out_file.endswith('.svg'): out_file += '.svg' compose_view( plot_segs(image_nii=anatomical, seg_niis=[mask], bbox_nii=mask, out_file='reports.svg', masked=False, compress='auto'), fg_svgs=None, out_file=out_file ) return out_file
def _generate_report(self): anat_img = nib.load(self.inputs.in_file) mask_img = nib.load(self.inputs.mask_file) assert nvol(anat_img) == 1 assert nvol(mask_img) == 1 plot_params = robust_set_limits_in_mask(anat_img, mask_img) template = self.inputs.template parc_file = getresource( f"tpl-{template}_RegistrationCheckOverlay.nii.gz") assert parc_file is not None parc_img = nib.load(parc_file) levels = np.unique(np.asanyarray(parc_img.dataobj).astype(np.int32)) levels = (levels[levels > 0] - 0.5).tolist() colors = color_palette("husl", len(levels)) label = None if isdefined(self.inputs.label): label = self.inputs.label compress = self.inputs.compress_report n_cuts = 7 cuts = cuts_from_bbox(mask_img, cuts=n_cuts) outfiles = [] for dimension in ["z", "y", "x"]: display = plot_anat( anat_img, draw_cross=False, display_mode=dimension, cut_coords=cuts[dimension], title=label, **plot_params, ) display.add_contours(parc_img, levels=levels, colors=colors, linewidths=0.25) display.add_contours(mask_img, levels=[0.5], colors="r", linewidths=0.5) label = None # only on first svg = extract_svg(display, compress=compress) svg = svg.replace("figure_1", str(uuid4()), 1) outfiles.append(fromstring(svg)) self._out_report = op.abspath(self.inputs.out_report) compose_view(bg_svgs=outfiles, fg_svgs=None, out_file=self._out_report)
def _generate_report(self): from seaborn import color_palette from niworkflows.viz.utils import plot_segs, compose_view seg_files = self.inputs.in_rois mask_file = None if not isdefined(self.inputs.in_mask) else self.inputs.in_mask # Remove trait decoration and replace None with [] levels = [level for level in self.inputs.levels or []] colors = [c for c in self.inputs.colors or []] if len(seg_files) == 1: # in_rois is a segmentation nsegs = len(levels) if nsegs == 0: levels = np.unique( np.round(nb.load(seg_files[0]).get_fdata(dtype="float32")) ) levels = (levels[levels > 0] - 0.5).tolist() nsegs = len(levels) levels = [levels] missing = nsegs - len(colors) if missing > 0: colors = colors + color_palette("husl", missing) colors = [colors] else: # in_rois is a list of masks nsegs = len(seg_files) levels = [[0.5]] * nsegs missing = nsegs - len(colors) if missing > 0: colors = [[c] for c in colors + color_palette("husl", missing)] if mask_file: seg_files.insert(0, mask_file) if levels: levels.insert(0, [0.5]) colors.insert(0, [self.inputs.mask_color]) nsegs += 1 self._out_report = os.path.abspath(self.inputs.out_report) compose_view( plot_segs( image_nii=self.inputs.in_file, seg_niis=seg_files, bbox_nii=mask_file, levels=levels, colors=colors, out_file=self.inputs.out_report, masked=self.inputs.masked, compress=self.inputs.compress_report, ), fg_svgs=None, out_file=self._out_report, )
def _generate_report(self): """Generate a reportlet.""" NIWORKFLOWS_LOG.info('Generating visual report') movnii = refnii = load_img(self.inputs.reference) fmapnii = load_img(self.inputs.fieldmap) if isdefined(self.inputs.moving): movnii = load_img(self.inputs.moving) contour_nii = mask_nii = None if isdefined(self.inputs.mask): contour_nii = load_img(self.inputs.mask) maskdata = contour_nii.get_fdata() > 0 else: mask_nii = threshold_img(refnii, 1e-3) maskdata = mask_nii.get_fdata() > 0 cuts = cuts_from_bbox(contour_nii or mask_nii, cuts=self._n_cuts) fmapdata = fmapnii.get_fdata() vmax = max(abs(np.percentile(fmapdata[maskdata], 99.8)), abs(np.percentile(fmapdata[maskdata], 0.2))) fmap_overlay = [{ 'overlay': fmapnii, 'overlay_params': { 'cmap': coolwarm_transparent(max_alpha=self.inputs.max_alpha), 'vmax': vmax, 'vmin': -vmax, } }] * 2 if self.inputs.show != 'both': fmap_overlay[not self.inputs.show] = {} # Call composer compose_view(plot_registration(movnii, 'moving-image', estimate_brightness=True, cuts=cuts, label=self.inputs.moving_label, contour=contour_nii, compress=False, **fmap_overlay[1]), plot_registration(refnii, 'fixed-image', estimate_brightness=True, cuts=cuts, label=self.inputs.reference_label, contour=contour_nii, compress=False, **fmap_overlay[0]), out_file=self._out_report)
def _generate_report(self): from niworkflows.viz.utils import plot_segs, compose_view seg_files = self.inputs.in_rois mask_file = None if not isdefined(self.inputs.in_mask) \ else self.inputs.in_mask # Remove trait decoration and replace None with [] levels = [l for l in self.inputs.levels or []] colors = [c for c in self.inputs.colors or []] if len(seg_files) == 1: # in_rois is a segmentation nsegs = len(levels) if nsegs == 0: levels = np.unique(np.round( nb.load(seg_files[0]).get_data()).astype(int)) levels = (levels[levels > 0] - 0.5).tolist() nsegs = len(levels) levels = [levels] missing = nsegs - len(colors) if missing > 0: colors = colors + color_palette("husl", missing) colors = [colors] else: # in_rois is a list of masks nsegs = len(seg_files) levels = [[0.5]] * nsegs missing = nsegs - len(colors) if missing > 0: colors = [[c] for c in colors + color_palette("husl", missing)] if mask_file: seg_files.insert(0, mask_file) if levels: levels.insert(0, [0.5]) colors.insert(0, [self.inputs.mask_color]) nsegs += 1 self._out_report = os.path.abspath(self.inputs.out_report) compose_view( plot_segs( image_nii=self.inputs.in_file, seg_niis=seg_files, bbox_nii=mask_file, levels=levels, colors=colors, out_file=self.inputs.out_report, masked=self.inputs.masked, compress=self.inputs.compress_report, ), fg_svgs=None, out_file=self._out_report )
def _generate_report(self): data = nimg.load_img(self.inputs.nii) if len(data.shape) == 4: data = _make_3d_from_4d(data) compose_view(nvzplot.plot_montage(data, self.inputs.orientation, n_cuts=self.inputs.n_cuts, n_cols=self.inputs.n_cols, auto_brightness=True, figure_title="anatomical"), fg_svgs=None, out_file=self._out_report)
def _generate_report(self): data = nimg.load_img(self.inputs.nii) if len(data.shape) == 4: data = _make_3d_from_4d(data) compose_view(nvzplot.plot_orthogonal_views( data, auto_brightness=True, display_modes=self.inputs.display_modes, n_cuts=self.inputs.n_cuts, figure_title="anatomical"), fg_svgs=None, out_file=self._out_report)
def _generate_report(self): """ Generates the visual report """ from niworkflows.viz.utils import compose_view, plot_registration NIWORKFLOWS_LOG.info('Generating visual report') fixed_image_nii = load_img(self._fixed_image) moving_image_nii = load_img(self._moving_image) contour_nii = load_img( self._contour) if self._contour is not None else None if self._fixed_image_mask: fixed_image_nii = unmask( apply_mask(fixed_image_nii, self._fixed_image_mask), self._fixed_image_mask) # since the moving image is already in the fixed image space we # should apply the same mask moving_image_nii = unmask( apply_mask(moving_image_nii, self._fixed_image_mask), self._fixed_image_mask) mask_nii = load_img(self._fixed_image_mask) else: mask_nii = threshold_img(fixed_image_nii, 1e-3) n_cuts = 7 if not self._fixed_image_mask and contour_nii: cuts = cuts_from_bbox(contour_nii, cuts=n_cuts) else: cuts = cuts_from_bbox(mask_nii, cuts=n_cuts) # Call composer compose_view(plot_registration(fixed_image_nii, 'fixed-image', estimate_brightness=True, cuts=cuts, label=self._fixed_image_label, contour=contour_nii, compress=self.inputs.compress_report), plot_registration(moving_image_nii, 'moving-image', estimate_brightness=True, cuts=cuts, label=self._moving_image_label, contour=contour_nii, compress=self.inputs.compress_report), out_file=self._out_report)
def _generate_report(self): from niworkflows.viz.utils import plot_segs, compose_view seg_files = self.inputs.in_rois mask_file = None if isdefined(self.inputs.in_mask): mask_file = self.inputs.in_mask seg_files.insert(0, self.inputs.in_mask) self._out_report = os.path.abspath(self.inputs.out_report) compose_view(plot_segs(image_nii=self.inputs.in_file, seg_niis=seg_files, bbox_nii=mask_file, out_file=self.inputs.out_report, masked=self.inputs.masked, colors=self.inputs.colors, compress=self.inputs.compress_report), fg_svgs=None, out_file=self._out_report)
def _generate_report(self): in_img = nib.load(self.inputs.in_file) assert nvol(in_img) == 1 mask_img = nib.load(self.inputs.mask_file) assert nvol(mask_img) == 1 label = None if isdefined(self.inputs.label): label = self.inputs.label compress = self.inputs.compress_report n_cuts = 7 cuts = cuts_from_bbox(mask_img, cuts=n_cuts) img_vals = in_img.get_fdata()[np.asanyarray(mask_img.dataobj).astype( np.bool)] vmin = img_vals.min() vmax = img_vals.max() outfiles = [] for dimension in ["z", "y", "x"]: display = plot_epi( in_img, draw_cross=False, display_mode=dimension, cut_coords=cuts[dimension], title=label, vmin=vmin, vmax=vmax, colorbar=(dimension == "z"), cmap=plt.cm.gray, ) display.add_contours(mask_img, levels=[0.5], colors="r") label = None # only on first svg = extract_svg(display, compress=compress) svg = svg.replace("figure_1", str(uuid4()), 1) outfiles.append(fromstring(svg)) self._out_report = op.abspath(self.inputs.out_report) compose_view(bg_svgs=outfiles, fg_svgs=None, out_file=self._out_report)
def _run_interface(self, runtime): """ there is not inner interface to run """ from niworkflows.viz.utils import plot_segs, compose_view seg_files = self.inputs.in_rois mask_file = None if isdefined(self.inputs.in_mask): mask_file = self.inputs.in_mask seg_files.insert(0, self.inputs.in_mask) self._out_report = os.path.abspath(self.inputs.out_report) compose_view(plot_segs(image_nii=self.inputs.in_file, seg_niis=seg_files, bbox_nii=mask_file, out_file=self.inputs.out_report, masked=self.inputs.masked, colors=self.inputs.colors, compress=self.inputs.compress_report), fg_svgs=None, out_file=self._out_report) return runtime
def _generate_report(self): epi_img = nib.load(self.inputs.in_file) mask_img = nib.load(self.inputs.mask_file) assert nvol(epi_img) == 1 assert nvol(mask_img) == 1 label = None if isdefined(self.inputs.label): label = self.inputs.label compress = self.inputs.compress_report n_cuts = 7 cuts = cuts_from_bbox(mask_img, cuts=n_cuts) plot_params = robust_set_limits_in_mask(epi_img, mask_img) outfiles = [] for dimension in ["z", "y", "x"]: display = plot_epi( epi_img, draw_cross=False, display_mode=dimension, cut_coords=cuts[dimension], title=label, colorbar=(dimension == "z"), cmap=plt.get_cmap("gray"), **plot_params, ) display.add_contours(mask_img, levels=[0.5], colors="r") label = None # only on first svg = extract_svg(display, compress=compress) svg = svg.replace("figure_1", str(uuid4()), 1) outfiles.append(fromstring(svg)) self._out_report = op.abspath(self.inputs.out_report) compose_view(bg_svgs=outfiles, fg_svgs=None, out_file=self._out_report)
def make_registration(*, moving, fixed, mask, out_file): """ Creates `out_file`.svg of registration between `moving` and `fixed` Parameters ---------- moving : str Path to file that was registered to `fixed` fixed : str Path to file that `moving` was registered to mask : str Path to brain mask file out_file : str Path to where svg will be saved Returns ------- out_file : str Where svg was saved """ if not out_file.endswith('.svg'): out_file += '.svg' cuts = cuts_from_bbox(nib.load(mask), cuts=7) compose_view( plot_registration(nib.load(fixed), 'fixed-image', estimate_brightness=True, cuts=cuts, label='fixed'), plot_registration(nib.load(moving), 'moving-image', estimate_brightness=True, cuts=cuts, label='moving'), out_file=out_file ) return out_file
def _run_interface(self, runtime): fixed_img = load_img(self.inputs.fixed_img) moving_img = load_img(self.inputs.moving_img) mask = load_img(self.inputs.mask_img) out_dir = os.path.realpath(self.inputs.out_dir) cuts = cuts_from_bbox(mask, self.inputs.cuts) _, fname, _ = split_filename(self.inputs.moving_img) compose_view(plot_registration(fixed_img, 'fixed-image', estimate_brightness=True, cuts=cuts, label='fixed'), plot_registration(moving_img, 'moving-image', estimate_brightness=True, cuts=cuts, label='moving'), out_file=os.path.join(out_dir, (fname + '_vizQC.svg'))) return runtime
def make_segmentation(*, anatomical, segmentation, mask, out_file): """ Creates `out_file`.svg of `segmentation` countours on input `anatomical` Parameters ---------- anatomical : str Path to anatomical T1w image (*without skull*) segmentation : str Path to segmentation file with tissue types (1-6) mask : str Path to brain mask file out_file : str Path to where svg will be saved Returns ------- out_file : str Where svg was saved """ if not out_file.endswith('.svg'): out_file += '.svg' segs = segmentation_to_files(segmentation) compose_view( plot_segs(image_nii=anatomical, seg_niis=[mask] + segs, bbox_nii=mask, out_file='reports.svg', masked=False, compress='auto'), fg_svgs=None, out_file=out_file ) for fname in segs: os.remove(fname) return out_file
def _generate_report(self): """Generate a reportlet.""" NIWORKFLOWS_LOG.info("Generating visual report") movnii = load_img(self.inputs.reference) canonical_r = rotation2canonical(movnii) movnii = refnii = rotate_affine(movnii, rot=canonical_r) fmapnii = nb.squeeze_image( rotate_affine(load_img(self.inputs.fieldmap), rot=canonical_r)) if fmapnii.dataobj.ndim == 4: for i, tstep in enumerate(nb.four_to_three(fmapnii)): if np.any(np.asanyarray(tstep.dataobj) != 0): fmapnii = tstep break if isdefined(self.inputs.moving): movnii = rotate_affine(load_img(self.inputs.moving), rot=canonical_r) contour_nii = mask_nii = None if isdefined(self.inputs.mask): contour_nii = rotate_affine(load_img(self.inputs.mask), rot=canonical_r) maskdata = contour_nii.get_fdata() > 0 else: mask_nii = threshold_img(refnii, 1e-3) maskdata = mask_nii.get_fdata() > 0 cuts = cuts_from_bbox(contour_nii or mask_nii, cuts=self._n_cuts) fmapdata = fmapnii.get_fdata() vmax = max( abs(np.percentile(fmapdata[maskdata], 99.8)), abs(np.percentile(fmapdata[maskdata], 0.2)), ) if self.inputs.apply_mask: fmapdata[~maskdata] = 0 fmapnii = fmapnii.__class__(fmapdata, fmapnii.affine, fmapnii.header) fmap_overlay = [{ "overlay": fmapnii, "overlay_params": { "cmap": coolwarm_transparent(max_alpha=self.inputs.max_alpha), "vmax": vmax, "vmin": -vmax, }, }] * 2 if self.inputs.show != "both": fmap_overlay[not self.inputs.show] = {} # Call composer compose_view( plot_registration(movnii, "moving-image", estimate_brightness=True, cuts=cuts, label=self.inputs.moving_label, contour=contour_nii, compress=False, **fmap_overlay[1]), plot_registration(refnii, "fixed-image", estimate_brightness=True, cuts=cuts, label=self.inputs.reference_label, contour=contour_nii, compress=False, **fmap_overlay[0]), out_file=self._out_report, )