Source code for shamo.core.problems.single.components.grid_sampler

"""Implement the `ComGridSampler` class."""
import logging

import nibabel as nib
import numpy as np
import re

from .abc import CompABC
from shamo.utils.onelab import read_vector_file, pos_to_nii

logger = logging.getLogger(__name__)


[docs]class CompGridSampler(CompABC): """Store information about a space grid sampler. A grid sampler is used to convert outputs from GetDP into a NII file more suitable for neuroimaging studies. Other Parameters ---------------- affine : numpy.ndarray The affine matrix of the grid. shape : tuple [int] The shape of the grid. mask : numpy.ndarray The mask of the grid. """ def __init__(self, **kwargs): super().__init__( affine=kwargs.get("affine", []), shape=kwargs.get("shape", []), mask=kwargs.get("mask", None), ) @property def use_grid(self): """Return wether or not the grid can be used. Returns ------- bool Return ``True`` if the grid can be used, ``False`` otherwise. """ return True if self["affine"] != [] and self["shape"] != [] else False @property def affine(self): """Return the affine matrix of the grid. Returns ------- numpy.ndarray The affine matrix of the grid. """ return self["affine"] @property def shape(self): """Return the shape of the grid. Returns ------- tuple [int] The shape of the grid. """ return self["shape"] @property def mask(self): """Return the mask of the grid. Returns ------- numpy.ndarray The mask of the grid. """ return self["mask"]
[docs] def set(self, affine, shape, mask=None, resize=False): """Set the grid component. Parameters ---------- affine : numpy.ndarray The affine matrix of the grid. shame : tuple [int] The shape of the grid. mask : numpy.ndarray, optional The mask of the grid. If set to ``None``, no mask is applied to the resulting data. (The default is ``None``) resize : bool, optional If set to ``True``, the affine matrix is rescaled from meters to millimeters. (the default is ``False``) """ self["affine"] = np.vstack((affine[:3, :], np.array([0, 0, 0, 1]))) if resize: self["affine"] = np.diag([1e-3] * 3 + [1]) @ self["affine"] self["shape"] = shape self["mask"] = mask
[docs] def check(self, name, **kwargs): """Check is the grid is properly set. Parameters ---------- name : str The name of the grid. Raises ------ TypeError If argument `affine` is not a `numpy.ndarray`. ValueError If argument `affine` is not (3, 4) or (4, 4) `numpy.ndarray`. If argument `shape` is not a 3D shape. """ if self.use_grid: logger.info(f"Checking grid sampler '{name}'.") if not isinstance(self["affine"], np.ndarray): raise TypeError("Argument 'affine' expects type numpy.ndarray.") if self["affine"].shape not in ((3, 4), (4, 4)): raise ValueError("Argument 'affine' expects shape (3,4) or (4,4).") if len(self["shape"]) != 3: raise ValueError("Argument 'shape' expects 3 values.")
[docs] def to_pro_param(self, **kwargs): """Return if the grid can be used. Returns ------- bool Return ``True`` if the grid is set. """ return self.use_grid
[docs] def to_py_param(self, **kwargs): """Return the parameters required to render python template. Returns ------- dict [str, str] The parameters required to render python template. """ if self.use_grid: return { "affine": str(self.affine.tolist()), "shape": str(self.shape), "mask": str(self.mask.astype(int).tolist()) if self.mask is not None else None, } else: return None
[docs] def nii_from_pos(self, src, dst): """Convert a POS file into a NII file. Parameters ---------- src : str, byte or os.PathLike The path to the POS file to convert. dst : str, byte or os.PathLike The path where the generated NII image must be saved. Returns ------- nibabel.Nifti1Image The generated NII image. """ return pos_to_nii(src, dst, self.affine, self.shape, mask=self.mask)