Example #1
0
    def set_data(self, dat, casting='unsafe'):

        if '+' not in self.mode:
            raise RuntimeError('Cannot write into read-only volume. '
                               'Re-map in mode "r+" to allow in-place '
                               'writing.')

        # --- convert to numpy ---
        if torch.is_tensor(dat):
            dat = dat.detach().cpu()
        dat = np.asanyarray(dat)

        # --- sanity check ---
        if dat.shape != self.shape:
            raise ValueError(
                'Expected an array of shape {} but got {}.'.format(
                    self.shape, dat.shape))

        # --- special case if empty view ---
        if dat.size == 0:
            # nothing to write
            return self

        # --- cast ---
        dat = volutils.cast(dat, self.dtype, casting)

        # --- unpermute ---
        drop, perm, slicer = split_operation(self.permutation, self.slicer,
                                             'w')
        dat = dat[drop].transpose(perm)

        # --- dispatch ---
        if self.is_compressed('image'):
            if not all(is_fullslice(slicer, self._shape)):
                # read-and-write
                slice = dat
                with self.fileobj('image', 'r') as f:
                    dat = self._read_data_raw(fileobj=f, mmap=False)
                dat[slicer] = slice
            with self.fileobj('image', 'w', seek=0) as f:
                if self.same_file('image', 'header'):
                    self._set_header_raw(fileobj=f)
                self._write_data_raw_full(dat, fileobj=f)
                if self.same_file('image', 'footer'):
                    self._set_footer_raw(fileobj=f)

        elif all(is_fullslice(slicer, self._shape)):
            with self.fileobj('image', 'r+') as f:
                self._write_data_raw_full(dat, fileobj=f)

        else:
            with self.fileobj('image', 'r+') as f:
                self._write_data_raw_partial(dat, slicer, fileobj=f)
        return self
Example #2
0
    def _read_data_raw(self, slicer=None, tiffobj=None):
        """Read native data

        Dispatch to `_read_data_raw_full` or `_read_data_raw_partial`.

        Parameters
        ----------
        slicer : tuple[index_like], optional
            A tuple of indices that describe the chunk of data to read.
            If None, read everything.
        tiffobj : file object, default=`self.fileobj('image', 'r')`
            A file object (with `seek`, `read`) from which to read

        Returns
        -------
        dat : np.ndarray

        """
        if tiffobj is None:
            with self.tiffobj() as tiffobj:
                return self._read_data_raw(slicer, tiffobj)

        # load sub-array
        if slicer is None or all(is_fullslice(slicer, self._shape)):
            dat = self._read_data_raw_full(tiffobj)
        else:
            dat = self._read_data_raw_partial(slicer, tiffobj)

        return dat
Example #3
0
    def _read_data_raw(self, slicer=None, fileobj=None, mmap=None):
        """Read native data

        Dispatch to `_read_data_raw_full` or `_read_data_raw_partial`.

        Parameters
        ----------
        slicer : tuple[index_like], optional
            A tuple of indices that describe the chunk of data to read.
            If None, read everything.
        fileobj : file object, default=`self.fileobj('image', 'r')`
            A file object (with `seek`, `read`) from which to read
        mmap : bool, default=`self._image.dataobj.mmap`
            If True, try to memory map the data.

        Returns
        -------
        dat : np.ndarray

        """

        # load sub-array
        if slicer is None or all(is_fullslice(slicer, self._shape)):
            dat = self._read_data_raw_full(fileobj, mmap=mmap)
            if slicer is not None:
                dat = dat[slicer]
        else:
            dat = self._read_data_raw_partial(slicer, fileobj)

        return dat
Example #4
0
    def _write_data_raw_partial(self, dat, slicer, fileobj=None):
        """Write native data

        Parameters
        ----------
        dat : np.ndarray
            Should already have the on-disk data type, including byte-order
        slicer : tuple[index_like]
            Unpermuted slicer, without new axes.
        fileobj : nibabel.Opener, optional
            File object

        """

        if fileobj is None:
            # Create our own context
            with self.fileobj('image', 'r+') as fileobj:
                return self._write_data_raw_partial(dat, slicer, fileobj)

        # sanity checks for developers
        # (asserts because proper conversion/dispatch should happen before)
        assert isinstance(dat, np.ndarray), "Data should already be numpy"
        assert dat.dtype == self.dtype, "Data should already have correct type"
        assert not self.is_compressed('image'), "Data cannot be compressed"
        assert not all(is_fullslice(
            slicer, self._shape)), "No need for partial writing"

        if not fileobj.readable():
            raise RuntimeError('File object not readable')
        if not fileobj.writable():
            raise RuntimeError('File object not writable')

        # write data chunk
        writeslice(dat,
                   fileobj,
                   tuple(slicer),
                   self._shape,
                   self.dtype,
                   offset=self._image.dataobj.offset,
                   order=self._image.dataobj.order,
                   lock=self._lock['image'])
Example #5
0
 def level(self, val):
     if val != self.level and not all(is_fullslice(self.slicer)):
         raise RuntimeError("Cannot change resolution level in a view")
     self._level = val
     self._cache = {}
Example #6
0
 def series(self, val):
     if val != self.series and not all(is_fullslice(self.slicer)):
         raise RuntimeError("Cannot change series in a view")
     self._series = val
     self._cache = {}