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)
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)
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)
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)
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)