Example #1
0
    def psf_calc(self, psf, data_size):
        """Precalculate the OTF etc..."""
        g = resizePSF(psf, data_size)

        #keep track of our data shape
        self.height = data_size[0]
        self.width = data_size[1]
        self.depth = data_size[2]

        self.shape = data_size

        self.FTshape = [self.shape[0], self.shape[1], self.shape[2] / 2 + 1]

        self.g = g.astype('f4')
        self.g2 = 1.0 * self.g[::-1, ::-1, ::-1]

        #allocate memory
        self.H = fftw3f.create_aligned_array(self.FTshape, 'complex64')
        self.Ht = fftw3f.create_aligned_array(self.FTshape, 'complex64')
        #self.f = np.zeros(self.shape, 'f4')
        #self.res = np.zeros(self.shape, 'f4')
        #self.S = np.zeros((np.size(self.f), 3), 'f4')

        #self._F = fftw3f.create_aligned_array(self.FTshape, 'complex64')
        #self._r = fftw3f.create_aligned_array(self.shape, 'f4')
        #S0 = self.S[:,0]

        #create plans & calculate OTF and conjugate transformed OTF
        fftw3f.Plan(self.g, self.H, 'forward')()
        fftw3f.Plan(self.g2, self.Ht, 'forward')()

        self.Ht /= g.size
        self.H /= g.size
Example #2
0
    def prep(self):
        #allocate memory

        self._F = fftw3f.create_aligned_array(self.FTshape, 'complex64')
        self._r = fftw3f.create_aligned_array(self.shape[:-1], 'f4')

        #calculate plans for other ffts
        self._plan_r_F = fftw3f.Plan(self._r, self._F, 'forward')
        self._plan_F_r = fftw3f.Plan(self._F, self._r, 'backward')
    def __init__(self, u, v, k=None, lamb=488, n=1.51):
        """A FourierPropagator object allows us evaluate the electric field at a given defocus by propagating a complex
        pupil distribution a given distance from the nominal focus by adding the relevant phase term to the pupil and
        then taking the Fourier amplitude.
        
        Parameters
        ==========
        
        u, v : 2d arrays of float
            the co-ordinates in spatial frequencies within the pupil plane
            
        lamb : float
            the wavelength in nm
            
        n : float
            the refractive index of the media
            
            
        Notes
        =====
        
        u, v must be the same size as the eventual pupil distribution to be used. On creation, the FourierPropagator
        pre-calculates the phase factor to add for each u, v, co-ordinate and also pre-computes FFTW3 plans for the
        necessary Fourier transforms.
        
        """
        if not k is None:
            raise DeprecationWarning('k is no longer used')

        #R = np.sqrt(u**2 + v**2)
        self.propFac = ((2 * np.pi * n / lamb) *
                        np.sqrt(1 - np.minimum(u**2 + v**2, 1))).astype('f')

        #self.pfm =(self.propFac > 0).astype('f')
        self.pfm = (np.sqrt(u**2 + v**2) < 1).astype('f')

        self._F = fftw3f.create_aligned_array(u.shape, 'complex64')
        self._f = fftw3f.create_aligned_array(u.shape, 'complex64')

        #print('Creating plans for FFTs - this might take a while')

        #calculate plans for other ffts
        self._plan_f_F = fftw3f.Plan(self._f,
                                     self._F,
                                     'forward',
                                     flags=FFTWFLAGS,
                                     nthreads=NTHREADS)
        self._plan_F_f = fftw3f.Plan(self._F,
                                     self._f,
                                     'backward',
                                     flags=FFTWFLAGS,
                                     nthreads=NTHREADS)
        #self._plan_F_f = fftw3f.Plan(self._F, self._f, 'backward', flags = FFTWFLAGS, nthreads=NTHREADS)

        fftwWisdom.save_wisdom()
Example #4
0
    def prep(self):
        #allocate memory
        self._F = fftw3f.create_aligned_array(self.FTshape, 'complex64')
        self._r = fftw3f.create_aligned_array(self.shape, 'f4')

        print('Creating plans for FFTs - this might take a while')
        #calculate plans for other ffts
        self._plan_r_F = fftw3f.Plan(self._r, self._F, 'forward', flags = FFTWFLAGS, nthreads=NTHREADS)
        self._plan_F_r = fftw3f.Plan(self._F, self._r, 'backward', flags = FFTWFLAGS, nthreads=NTHREADS)
        
        fftwWisdom.save_wisdom()

        print('Done planning')
Example #5
0
    def psf_calc(self, psf, data_size):
        """Precalculate the OTF etc..."""

        g = resizePSF(psf, data_size)

        #keep track of our data shape
        self.height = data_size[0]
        self.width = data_size[1]
        self.depth = data_size[2]

        self.shape = data_size

        FTshape = [self.shape[0], self.shape[1], self.shape[2] / 2 + 1]

        #allocate memory

        self.H = fftw3f.create_aligned_array(FTshape, 'complex64')
        self.Ht = fftw3f.create_aligned_array(FTshape, 'complex64')

        self._F = fftw3f.create_aligned_array(FTshape, 'complex64')
        self._r = fftw3f.create_aligned_array(self.shape, 'f4')

        self.g = g.astype('f4')
        self.g2 = 1.0 * self.g[::-1, ::-1, ::-1]

        #S0 = self.S[:,0]

        #create plans & calculate OTF and conjugate transformed OTF
        fftw3f.Plan(self.g, self.H, 'forward')()
        fftw3f.Plan(self.g2, self.Ht, 'forward')()

        self.Ht /= g.size
        self.H /= g.size

        self.H2 = self.Ht * self.H

        #calculate plans for other ffts
        self._plan_r_F = fftw3f.Plan(self._r,
                                     self._F,
                                     'forward',
                                     flags=FFTWFLAGS,
                                     nthreads=NTHREADS)
        self._plan_F_r = fftw3f.Plan(self._F,
                                     self._r,
                                     'backward',
                                     flags=FFTWFLAGS,
                                     nthreads=NTHREADS)

        fftwWisdom.save_wisdom()

        self.lamb = None
Example #6
0
    def psf_calc(self, psf, data_size):
        """Precalculate the OTF etc..."""
        g = resizePSF(psf, data_size)
        #normalise
        g /= g[:, :, g.shape[2] / 2].sum()

        #keep track of our data shape
        self.height = data_size[0]
        self.width = data_size[1]
        self.depth = data_size[2]

        self.shape = data_size

        self.FTshape = list(
            self.shape[:-1]
        )  #[self.shape[0], self.shape[1], self.shape[2]/2 + 1]
        self.FTshape[-1] = self.FTshape[-1] / 2 + 1

        self.g = g.astype('f4')

        self.g2 = 1.0 * self.g[::-1, ::-1, :]

        self.H = []
        self.Ht = []

        for i in range(self.shape[-1]):

            #allocate memory
            self.H.append(
                fftw3f.create_aligned_array(self.FTshape, 'complex64'))
            self.Ht.append(
                fftw3f.create_aligned_array(self.FTshape, 'complex64'))

            #create plans & calculate OTF and conjugate transformed OTF
            fftw3f.Plan(1.0 * self.g[:, :, i], self.H[i], 'forward')()
            fftw3f.Plan(1.0 * self.g2[:, :, i], self.Ht[i], 'forward')()

            self.Ht[i] /= g[:, :, i].size
            self.H[i] /= g[:, :, i].size
Example #7
0
def resizePSF(psf, data_size):
    if not psf.shape == data_size:
        #Expand PSF to data size by fourier domain interpolation
        print('Resizing PSF to match data size')
        g_ = fftw3f.create_aligned_array(data_size, 'complex64')
        H_ = fftw3f.create_aligned_array(data_size, 'complex64')

        sx, sy, sz = numpy.array(data_size).astype('f') / psf.shape

        #print sx, sy, sz

        OT = fftshift(fftn(
            fftshift(psf)))  #don't bother with FFTW here as raw PSF is small

        if data_size[2] > 1:
            pr = ndimage.zoom(OT.real, [sx, sy, sz], order=1)
            pi = ndimage.zoom(OT.imag, [sx, sy, sz], order=1)
        else:  #special case for 2D
            pr = ndimage.zoom(OT.real.squeeze(), [sx, sy],
                              order=1).reshape(data_size)
            pi = ndimage.zoom(OT.imag.squeeze(), [sx, sy],
                              order=1).reshape(data_size)

        H_[:] = ifftshift(pr + 1j * pi)
        fftw3f.Plan(H_, g_, 'backward')()
        #View3D(psf)
        #View3D(H_)
        #View3D(OT)
        #View3D(pr)

        g = ifftshift(g_.real).clip(
            min=0)  # negative values may cause instability

        print('PSF resizing complete')
    else:
        g = psf
    #View3D(psf)
    #View3D(fftshift(numpy.abs(H_)))
    #View3D(fftshift(numpy.angle(H_)))
    #View3D(g)

    return g / g.sum()