Exemplo n.º 1
0
    def compute_estimate(self):
        """
            Calculates a single RL fusion estimate. There is no reason to call this
            function -- it is used internally by the class during fusion process.
        """
        self.estimate_new[:] = np.zeros(self.image_size, dtype=np.float32)

        # Iterate over blocks
        iterables = (range(0, m, n) for m, n in zip(self.image_size, self.block_size))
        pad = self.options.block_pad
        block_idx = tuple(slice(pad, pad + block) for block in self.block_size)

        for pos in itertools.product(*iterables):

            estimate_idx = tuple(slice(j, j + k) for j, k in zip(pos, self.block_size))
            index = np.array(pos, dtype=int)

            if self.options.block_pad > 0:
                h_estimate_block = self.get_padded_block(self.estimate, index.copy()).astype(np.complex64)
            else:
                h_estimate_block = self.estimate[estimate_idx].astype(np.complex64)

            # # Execute: cache = convolve(PSF, estimate), non-normalized
            h_estimate_block_new = self._fft_convolve(h_estimate_block, self.psf_fft)

            # Execute: cache = data/cache. Add background bias if requested.
            h_image_block = self.get_padded_block(self.image, index.copy()).astype(np.float32)
            if self.options.rl_background != 0:
                h_image_block += self.options.rl_background
            ops_ext.inverse_division_inplace(h_estimate_block_new, h_image_block)

            # Execute correlation with PSF
            h_estimate_block_new = self._fft_convolve(h_estimate_block_new, self.adj_psf_fft).real

            # Get new weights
            self.estimate_new[estimate_idx] = h_estimate_block_new[block_idx]

        # TV Regularization (doesn't seem to do anything miraculous).
        if self.options.tv_lambda > 0 and self.iteration_count > 0:
            dv_est = ops_ext.div_unit_grad(self.estimate, self.image_spacing)
            self.estimate_new = ops_array.safe_divide(self.estimate_new,
                                                      (1.0 - self.options.rltv_lambda * dv_est))

        # Update estimate inplace. Get convergence statistics.
        return ops_ext.update_estimate_poisson(self.estimate,
                                               self.estimate_new,
                                               self.options.convergence_epsilon)
Exemplo n.º 2
0
    def compute_estimate(self):
        """
            Calculates a single RL fusion estimate. There is no reason to call this
            function -- it is used internally by the class during fusion process.
        """
        print('Beginning the computation of the %i. estimate' % \
              (self.iteration_count + 1))

        self.estimate_new[:] = numpy.zeros(self.image_size, dtype=numpy.float32)

        # Iterate over blocks
        stream1 = cuda.stream()
        stream2 = cuda.stream()

        iterables = (range(0, m, n) for m, n in zip(self.image_size, self.block_size))
        pad = self.options.block_pad
        block_idx = tuple(slice(pad, pad + block) for block in self.block_size)

        if self.imdims == 2:
            for pos in itertools.product(*iterables):

                estimate_idx = tuple(slice(j, j + k) for j, k in zip(idx, self.block_size))
                index = numpy.array(pos, dtype=int)

                if self.options.block_pad > 0:
                    h_estimate_block = self.get_padded_block(self.estimate, index.copy()).astype(numpy.complex64)
                else:
                    h_estimate_block = self.estimate[estimate_idx].astype(numpy.complex64)

                d_estimate_block = cuda.to_device(h_estimate_block, stream=stream1)
                d_psf = cuda.to_device(self.psf_fft, stream=stream2)

                # Execute: cache = convolve(PSF, estimate), non-normalized
                fft_inplace(d_estimate_block, stream=stream1)
                stream2.synchronize()

                self.vmult(d_estimate_block, d_psf, out=d_estimate_block)
                ifft_inplace(d_estimate_block)

                h_estimate_block_new = d_estimate_block.copy_to_host()

                # Execute: cache = data/cache
                h_image_block = self.get_padded_block(self.image, index.copy()).astype(numpy.float32)
                ops_ext.inverse_division_inplace(h_estimate_block_new, h_image_block)

                d_estimate_block = cuda.to_device(h_estimate_block_new,
                                                  stream=stream1)
                d_adj_psf = cuda.to_device(self.adj_psf_fft, stream=stream2)

                fft_inplace(d_estimate_block, stream=stream1)
                stream2.synchronize()
                self.vmult(d_estimate_block, d_adj_psf, out=d_estimate_block)
                ifft_inplace(d_estimate_block)
                h_estimate_block_new = d_estimate_block.copy_to_host().real

                self.estimate_new[estimate_idx] = h_estimate_block_new[block_idx]

        # TV Regularization (doesn't seem to do anything miraculous).
        if self.options.rltv_lambda > 0 and self.iteration_count > 0:
            dv_est = ops_ext.div_unit_grad(self.estimate, self.image_spacing)
            with numpy.errstate(divide="ignore"):
                self.estimate_new /= (1.0 - self.options.rltv_lambda * dv_est)
                self.estimate_new[self.estimate_new == numpy.inf] = 0.0
                self.estimate_new[:] = numpy.nan_to_num(self.estimate_new)

        # Update estimate inplace. Get convergence statistics.
        return ops_ext.update_estimate_poisson(self.estimate,
                                               self.estimate_new,
                                               self.options.convergence_epsilon)
Exemplo n.º 3
0
    def compute_estimate(self):
        """
        Calculates a single RL deconvolution estimate. There is no reason to call this
        function -- it is used internally by the class during fusion process.
        """

        if self.options.verbose:
            print('Beginning the computation of the %i. estimate' %
                  self.iteration_count)

        self.estimate_new[:] = numpy.float32(0)

        # Iterate over blocks
        block_nr = 1
        iterables = (range(0, m, n)
                     for m, n in zip(self.image_size, self.block_size))
        pad = self.options.block_pad
        cache_idx = tuple(slice(pad, pad + block) for block in self.block_size)

        for idx in itertools.product(*iterables):

            estimate_idx = tuple(
                slice(j, j + k) for j, k in zip(idx, self.block_size))

            index = numpy.array(idx, dtype=int)

            if self.options.block_pad > 0:
                estimate_block = self.get_padded_block(self.estimate,
                                                       index.copy())
                image_block = self.get_padded_block(self.image, index.copy())
            else:
                estimate_block = self.estimate[estimate_idx]
                image_block = self.image[estimate_idx]

            # print "The current block is %i" % block_nr
            block_nr += 1

            # Execute: cache = convolve(PSF, estimate), non-normalized
            cache = fftconvolve(estimate_block, self.psf, mode='same')

            if self.options.rl_background != 0:
                cache += self.options.rl_background

                # ops_ext.inverse_division_inplace(cache, image_block)
            with numpy.errstate(divide="ignore"):
                cache = image_block.astype(numpy.float32) / cache
                cache[cache == numpy.inf] = 0.0
                cache = numpy.nan_to_num(cache)

            # Execute: cache = convolve(PSF(-), cache), inverse of non-normalized
            # Convolution with virtual PSFs is performed here as well, if
            # necessary
            cache = fftconvolve(cache, self.adj_psf, mode='same')

            self.estimate_new[estimate_idx] = cache[cache_idx]

        if self.options.tv_lambda > 0 and self.iteration_count > 0:
            if self.estimate.ndim == 2:
                spacing = list(self.image_spacing)
                spacing.insert(0, 1)
                dv_est = ops_ext.div_unit_grad(
                    numpy.expand_dims(self.estimate, 0), spacing)[0]
            else:
                dv_est = ops_ext.div_unit_grad(self.estimate,
                                               self.image_spacing)
            with numpy.errstate(divide="ignore"):
                self.estimate_new /= (1.0 - self.options.tv_lambda * dv_est)
                self.estimate_new[self.estimate_new == numpy.inf] = 0.0
                self.estimate_new[:] = numpy.nan_to_num(self.estimate_new)

        return ops_ext.update_estimate_poisson(
            self.estimate, self.estimate_new, self.options.convergence_epsilon)
Exemplo n.º 4
0
    def compute_estimate(self):
        """
            Calculates a single RL fusion estimate. There is no reason to call this
            function -- it is used internally by the class during fusion process.
        """
        print(
            f'Beginning the computation of the {self.iteration_count + 1}. estimate'
        )

        if "multiplicative" in self.options.fusion_method:
            self.estimate_new[:] = numpy.ones(self.image_size,
                                              dtype=numpy.float32)
        else:
            self.estimate_new[:] = numpy.zeros(self.image_size,
                                               dtype=numpy.float32)

        # Iterate over views
        for idx, view in enumerate(self.views):

            psf_fft = self.psfs_fft[idx]
            adj_psf_fft = self.adj_psfs_fft[idx]

            self.data.set_active_image(view, self.options.channel,
                                       self.options.scale, "registered")

            weighting = self.weights[idx]
            background = self.background[idx]

            iterables = (range(0, m, n)
                         for m, n in zip(self.image_size, self.block_size))
            pad = self.options.block_pad
            block_idx = tuple(
                slice(pad, pad + block) for block in self.block_size)

            for pos in itertools.product(*iterables):

                estimate_idx = tuple(
                    slice(j, j + k) for j, k in zip(pos, self.block_size))
                index = numpy.array(pos, dtype=int)

                if self.options.block_pad > 0:
                    h_estimate_block = self.get_padded_block(
                        self.estimate, index.copy()).astype(numpy.complex64)
                else:
                    h_estimate_block = self.estimate[estimate_idx].astype(
                        numpy.complex64)

                # Convolve estimate block with the PSF
                h_estimate_block_new = self._fft_convolve(
                    h_estimate_block, psf_fft)

                # Apply weighting
                h_estimate_block_new *= weighting

                # Apply background
                h_estimate_block_new += background

                # Divide image block with the convolution result
                h_image_block = self.data.get_registered_block(
                    self.block_size, self.options.block_pad,
                    index.copy()).astype(numpy.float32)

                #h_estimate_block_new = ops_array.safe_divide(h_image_block, h_estimate_block_new)
                ops_ext.inverse_division_inplace(h_estimate_block_new,
                                                 h_image_block)

                # Correlate with adj PSF
                h_estimate_block_new = self._fft_convolve(
                    h_estimate_block_new, adj_psf_fft).real

                # Update the contribution from a single view to the new estimate
                self._write_estimate_block(h_estimate_block_new, estimate_idx,
                                           block_idx)

        # Divide with the number of projections
        if "summative" in self.options.fusion_method:
            # self.estimate_new[:] = self.float_vmult(self.estimate_new,
            #                                         self.scaler)
            self.estimate_new *= (1.0 / self.n_views)
        else:
            self.estimate_new[self.estimate_new < 0] = 0
            self.estimate_new[:] = ops_array.nroot(self.estimate_new,
                                                   self.n_views)

        # TV Regularization (doesn't seem to do anything miraculous).
        if self.options.tv_lambda > 0 and self.iteration_count > 0:
            dv_est = ops_ext.div_unit_grad(self.estimate, self.voxel_size)
            self.estimate_new = ops_array.safe_divide(
                self.estimate, (1.0 - self.options.rltv_lambda * dv_est))

        # Update estimate inplace. Get convergence statistics.
        return ops_ext.update_estimate_poisson(
            self.estimate, self.estimate_new, self.options.convergence_epsilon)
Exemplo n.º 5
0
    def compute_estimate(self):
        """
            Calculates a single RL fusion estimate. There is no reason to call this
            function -- it is used internally by the class during fusion process.
        """
        print('Beginning the computation of the %i. estimate' % \
              (self.iteration_count + 1))

        if "multiplicative" in self.options.fusion_method:
            self.estimate_new[:] = numpy.ones(self.image_size,
                                              dtype=numpy.float32)
        else:
            self.estimate_new[:] = numpy.zeros(self.image_size,
                                               dtype=numpy.float32)

        stream1 = cuda.stream()
        stream2 = cuda.stream()

        # Iterate over views
        for idx, view in enumerate(self.views):

            psf_fft = self.psfs_fft[idx]
            adj_psf_fft = self.adj_psfs_fft[idx]

            self.data.set_active_image(view, self.options.channel,
                                       self.options.scale, "registered")

            weighting = self.weights[idx]
            iterables = (range(0, m, n)
                         for m, n in zip(self.image_size, self.block_size))
            pad = self.options.block_pad
            block_idx = tuple(
                slice(pad, pad + block) for block in self.block_size)

            for pos in itertools.product(*iterables):

                estimate_idx = tuple(
                    slice(j, j + k) for j, k in zip(pos, self.block_size))
                index = numpy.array(pos, dtype=int)

                if self.options.block_pad > 0:
                    h_estimate_block = self.get_padded_block(
                        index.copy()).astype(numpy.complex64)
                else:
                    h_estimate_block = self.estimate[estimate_idx].astype(
                        numpy.complex64)

                d_estimate_block = cuda.to_device(h_estimate_block,
                                                  stream=stream1)
                d_psf = cuda.to_device(psf_fft, stream=stream2)

                # Execute: cache = convolve(PSF, estimate), non-normalized
                fft_inplace(d_estimate_block, stream=stream1)
                stream2.synchronize()

                self.vmult(d_estimate_block, d_psf, out=d_estimate_block)
                ifft_inplace(d_estimate_block)

                h_estimate_block_new = d_estimate_block.copy_to_host()

                # Execute: cache = data/cache
                h_image_block = self.data.get_registered_block(
                    self.block_size, self.options.block_pad,
                    index.copy()).astype(numpy.float32)
                h_estimate_block_new *= weighting
                ops_ext.inverse_division_inplace(h_estimate_block_new,
                                                 h_image_block)

                d_estimate_block = cuda.to_device(h_estimate_block_new,
                                                  stream=stream1)
                d_adj_psf = cuda.to_device(adj_psf_fft, stream=stream2)

                fft_inplace(d_estimate_block, stream=stream1)
                stream2.synchronize()
                self.vmult(d_estimate_block, d_adj_psf, out=d_estimate_block)
                ifft_inplace(d_estimate_block)
                h_estimate_block_new = d_estimate_block.copy_to_host().real

                # Update the contribution from a single view to the new estimate
                if self.options.block_pad == 0:
                    if "multiplicative" in self.options.fusion_method:
                        self.estimate_new[estimate_idx] *= h_estimate_block_new
                    else:

                        self.estimate_new[estimate_idx] += h_estimate_block_new
                else:

                    if "multiplicative" in self.options.fusion_method:
                        self.estimate_new[
                            estimate_idx] *= h_estimate_block_new[block_idx]

                    else:
                        # print "The block size is ", self.block_size
                        self.estimate_new[
                            estimate_idx] += h_estimate_block_new[block_idx]

        # # Divide with the number of projections
        # if "summative" in self.options.fusion_method:
        #     # self.estimate_new[:] = self.float_vmult(self.estimate_new,
        #     #                                         self.scaler)
        #     self.estimate_new *= (1.0 / self.n_views)
        # else:
        #     self.estimate_new[self.estimate_new < 0] = 0
        #     self.estimate_new[:] = ops_array.nroot(self.estimate_new,
        #                                            self.n_views)

        # TV Regularization (doesn't seem to do anything miraculous).
        if self.options.rltv_lambda > 0 and self.iteration_count > 0:
            dv_est = ops_ext.div_unit_grad(self.estimate, self.voxel_size)
            with numpy.errstate(divide="ignore"):
                self.estimate_new /= (1.0 - self.options.rltv_lambda * dv_est)
                self.estimate_new[self.estimate_new == numpy.inf] = 0.0
                self.estimate_new[:] = numpy.nan_to_num(self.estimate_new)

        # Update estimate inplace. Get convergence statistics.
        return ops_ext.update_estimate_poisson(
            self.estimate, self.estimate_new, self.options.convergence_epsilon)