Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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))