def execute(self, field): if any(field.shape != self.tile.shape): raise AttributeError("Field passed to PSF incorrect shape") if not np.iscomplex(field.ravel()[0]): infield = fft.fftn(field, **fftkwargs) else: infield = field return np.real(fft.ifftn(infield * self.kpsf, **fftkwargs))
def calculate_kpsf(self, shape): d = ((shape - self.min_support)) # fix off-by-one issues when going odd to even tile sizes o = d % 2 d = d // 2 pad = tuple((d[i], d[i] + o[i]) for i in [0, 1, 2]) self.rpsf = np.pad(self.min_rpsf, pad, mode='constant', constant_values=0) self.rpsf = fft.ifftshift(self.rpsf) self.kpsf = fft.fftn(self.rpsf, **fftkwargs) self.kpsf /= (np.real(self.kpsf[0, 0, 0]) + 1e-15) return self.kpsf
def _pad(self, field): if any(self.tile.shape < self.get_padding_size().shape): raise IndexError("PSF tile size is less than minimum support size") d = self.tile.shape - self.get_padding_size().shape # fix off-by-one issues when going odd to even tile sizes o = d % 2 d = np.floor_divide(d, 2) pad = tuple((d[i], d[i] + o[i]) for i in [0, 1, 2]) rpsf = np.pad(field, pad, mode='constant', constant_values=0) rpsf = fft.ifftshift(rpsf) kpsf = fft.fftn(rpsf, **fftkwargs) kpsf /= (np.real(kpsf[0, 0, 0]) + 1e-15) return kpsf
def execute(self, field): if any(field.shape != self.tile.shape): raise AttributeError("Field passed to PSF incorrect shape") if not np.iscomplex(field.ravel()[0]): infield = fft.fftn(field, **fftkwargs) else: infield = field outfield = np.zeros_like(infield, dtype='float') for i in range(field.shape[0]): z = int(self.tile.l[0] + i) kpsf = self._pad(self.array[z]) outfield[i] = np.real(fft.ifftn(infield * kpsf, **fftkwargs))[i] return outfield
def __call__(self, field): """ Accept a field, apply the point-spread-function, and return the resulting image of a blurred field """ # in order to avoid translations from the psf, we must create # real-space vectors that are zero in the corner and go positive # in one direction and negative on the other side of the image tile = peri.util.Tile(field.shape) rx, ry = tile.kvectors(norm=1.0 / tile.shape) # get the sigmas from ourselves sx, sy = self.values # calculate the real-space psf from the r-vectors and sigmas # normalize based on the calculated values, no the usual normalization psf = np.exp(-((rx / sx)**2 + (ry / sy)**2) / 2) psf = psf / psf.sum() self.psf = psf # perform the convolution with ffts and return the result out = fft.fftn(fft.ifftn(field) * fft.ifftn(psf)) return fftnorm(np.real(out))