Example #1
0
    def test_generic_load(self):
        nib_data = os.path.join(nib_testing.data_path, "example4d.nii.gz")
        vol = fio_utils.generic_load(nib_data)
        expected = NiftiReader().load(nib_data)
        assert vol.is_identical(expected)

        dcm_data = os.path.join(pydd.get_testdata_file("MR_small.dcm"))
        vol = fio_utils.generic_load(dcm_data)[0]
        expected = DicomReader().load(dcm_data)[0]
        assert vol.is_identical(expected)
Example #2
0
    def load_data(self, dir_path):
        """Load data from disk.

        Data will be loaded from folder '`dir_path`/`self.NAME`'.

        Currently, additional volumes are not reloaded.

        Args:
            dir_path (str): Directory path.
        """
        file_path = os.path.join(dir_path, self.NAME, "{}.nii.gz".format(self.NAME))
        qv_volume = fio_utils.generic_load(file_path, expected_num_volumes=1)

        self.volumetric_map = qv_volume
Example #3
0
    def generate_t2_star_map(self,
                             tissue: Tissue,
                             mask_path: str = None,
                             num_workers: int = 0):
        """
        Generate 3D :math:`T_2^* map and r-squared fit map using mono-exponential fit
        across subvolumes acquired at different echo times.

        :math:`T_2^* map is also added to the tissue.

        Args:
            tissue (Tissue): Tissue to generate quantitative value for.
            mask_path (:obj:`str`, optional): File path to mask of ROI to analyze.
                If specified, only voxels specified by mask will be fit.
                This can considerably speed up computation.
            num_workers (int, optional): Number of subprocesses to use for fitting.
                If `0`, will execute on the main thread.

        Returns:
            qv.T2Star: :math:`T_2^* fit for tissue.

        Raises:
            ValueError: If ``mask_path`` corresponds to non-binary volume.
        """
        # only calculate for focused region if a mask is available, this speeds up computation
        mask = tissue.get_mask()
        if mask_path is not None:
            mask = (fio_utils.generic_load(mask_path, expected_num_volumes=1)
                    if isinstance(mask_path,
                                  (str, os.PathLike)) else mask_path)

        spin_lock_times = self.echo_times
        subvolumes_list = self.volumes

        mef = MonoExponentialFit(
            bounds=(__T2_STAR_LOWER_BOUND__, __T2_STAR_UPPER_BOUND__),
            tc0="polyfit",
            decimal_precision=__T2_STAR_DECIMAL_PRECISION__,
            num_workers=num_workers,
            verbose=True,
        )

        t2star_map, r2 = mef.fit(spin_lock_times, subvolumes_list, mask=mask)

        quant_val_map = qv.T2Star(t2star_map)
        quant_val_map.add_additional_volume("r2", r2)

        tissue.add_quantitative_value(quant_val_map)

        return quant_val_map
Example #4
0
    def load_volume(self, title="Select volume file(s)"):
        files = filedialog.askopenfilenames(initialdir=self.__base_filepath,
                                            title=title)
        if len(files) == 0:
            return

        filepath = files[0]
        self.__base_filepath = os.path.dirname(filepath)

        if filepath.endswith(".dcm"):
            filepath = os.path.dirname(filepath)

        im = fio_utils.generic_load(filepath, 1)

        return im
Example #5
0
    def __dilate_mask__(
        self,
        mask_path: str,
        temp_path: str,
        dil_rate: float = preferences.mask_dilation_rate,
        dil_threshold: float = preferences.mask_dilation_threshold,
    ):
        """Dilate mask using gaussian blur and write to disk to use with Elastix.

        Args:
            mask_path (str | MedicalVolume): File path for mask or mask to use to use as
                focus points for registration. Mask must be binary.
            temp_path (str): Directory path to store temporary data.
            dil_rate (`float`, optional): Dilation rate (sigma).
                Defaults to ``preferences.mask_dilation_rate``.
            dil_threshold (`float`, optional): Threshold to binarize dilated mask.
                Must be between [0, 1]. Defaults to ``preferences.mask_dilation_threshold``.

        Returns:
            str: File path of dilated mask.

        Raises:
            FileNotFoundError: If `mask_path` not valid file.
            ValueError: If `dil_threshold` not in range [0, 1].
        """

        if dil_threshold < 0 or dil_threshold > 1:
            raise ValueError("'dil_threshold' must be in range [0, 1]")

        if isinstance(mask_path, MedicalVolume):
            mask = mask_path
        elif os.path.isfile(mask_path):
            mask = fio_utils.generic_load(mask_path, expected_num_volumes=1)
        else:
            raise FileNotFoundError("File {} not found".format(mask_path))

        dilated_mask = (sni.gaussian_filter(np.asarray(mask.volume,
                                                       dtype=np.float32),
                                            sigma=dil_rate) > dil_threshold)
        fixed_mask = np.asarray(dilated_mask, dtype=np.int8)
        fixed_mask_filepath = os.path.join(io_utils.mkdirs(temp_path),
                                           "dilated-mask.nii.gz")

        dilated_mask_volume = MedicalVolume(fixed_mask, affine=mask.affine)
        dilated_mask_volume.save_volume(fixed_mask_filepath)

        return fixed_mask_filepath
Example #6
0
    def _load_custom_data_base(cls, data, dtype=None, **kwargs):
        """The base condition for :meth:`load_custom_data`.

        Args:
            data:
            dtype (type): The data type.

        Return:
            The loaded data.
        """
        if dtype is None:
            dtype = type(data)

        # TODO: Add support for loading with num_workers
        num_workers = kwargs.get("num_workers", 0)
        if isinstance(data, str) and issubclass(dtype, MedicalVolume):
            data = fio_utils.generic_load(data, num_workers=num_workers)

        return data
Example #7
0
    def __fitting_helper(
        self,
        qv_type: QuantitativeValueType,
        echo_inds: Sequence[int],
        tissue: Tissue,
        bounds,
        tc0,
        decimal_precision,
        mask_path,
        num_workers,
    ):
        echo_info = [(self.echo_times[i], self.volumes[i]) for i in echo_inds]

        # sort by echo time
        echo_info = sorted(echo_info, key=lambda x: x[0])

        xs = [et for et, _ in echo_info]
        ys = [vol for _, vol in echo_info]

        # only calculate for focused region if a mask is available, this speeds up computation
        mask = tissue.get_mask()
        if mask_path is not None:
            mask = (fio_utils.generic_load(mask_path, expected_num_volumes=1)
                    if isinstance(mask_path,
                                  (str, os.PathLike)) else mask_path)

        mef = MonoExponentialFit(
            bounds=bounds,
            tc0=tc0,
            decimal_precision=decimal_precision,
            num_workers=num_workers,
            verbose=True,
        )
        qv_map, r2 = mef.fit(xs, ys, mask=mask)

        quant_val_map = qv_type(qv_map)
        quant_val_map.add_additional_volume("r2", r2)

        tissue.add_quantitative_value(quant_val_map)

        return quant_val_map
Example #8
0
    def load_data(self, load_dir_path: str):
        """Load data for tissue.

        All tissue information is based on the mask. If mask for tissue doesn't exist,
        there is no information to load.

        Args:
            load_dir_path (str): Directory path where all data is stored.
        """
        load_dir_path = self.__save_dirpath__(load_dir_path)
        mask_file_path = os.path.join(load_dir_path,
                                      "{}.nii.gz".format(self.STR_ID))

        # Try to load mask, if file exists.
        try:
            msk = fio_utils.generic_load(mask_file_path,
                                         expected_num_volumes=1)
            self.set_mask(msk)
        except FileNotFoundError:
            # do nothing
            pass

        self.quantitative_values = QuantitativeValue.load_qvs(load_dir_path)
Example #9
0
    def load_volume(self, title="Select volume file(s)"):
        filepath = self.get_volume_filepath(title)

        im = fio_utils.generic_load(filepath, 1)

        return im