Esempio n. 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 = zeros(self.shape, 'f4')
        #self.res = zeros(self.shape, 'f4')
        #self.S = zeros((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;
Esempio n. 2
0
    def __init__(self, ps, vox, PSSize):
        ps = ps.max(2)
        ps = ps - ps.min()

        ps = ps*scipy.signal.hanning(ps.shape[0])[:,None]*scipy.signal.hanning(ps.shape[1])[None,:]
        ps = ps/ps.sum()
        #PSFFileName = PSFFilename

        pw = (numpy.array(PSSize) - ps.shape)/2.
        pw1 = numpy.floor(pw)
        pw2 = numpy.ceil(pw)

        self.cachedPSF = pad.with_constant(ps, ((pw2[0], pw1[0]), (pw2[1], pw1[1])), (0,))
        self.cachedOTFH = (ifftn(self.cachedPSF)*self.cachedPSF.size).astype('complex64')
        self.cachedOTF2 = (self.cachedOTFH*fftn(self.cachedPSF)).astype('complex64')

        self.weinerFT = fftw3.create_aligned_array(self.cachedOTFH.shape, 'complex64')
        self.weinerR = fftw3.create_aligned_array(self.cachedOTFH.shape, 'float32')

        self.planForward = fftw3.Plan(self.weinerR, self.weinerFT, flags = FFTWFLAGS, nthreads=NTHREADS)
        self.planInverse = fftw3.Plan(self.weinerFT, self.weinerR, direction='reverse', flags = FFTWFLAGS, nthreads=NTHREADS)
        
        fftwWisdom.save_wisdom()
        
        self.otf2mean = self.cachedOTF2.mean()
Esempio n. 3
0
    def __init__(self, u,v,k, lamb = 488, n=1.51, field_x=0, field_y=0, apertureNA=1.5, apertureZGradient = 0):
        #print k**2
        #m = (u**2 + v**2) <= (n/lamb**2)
        #self.propFac = fftw3f.create_aligned_array(u.shape, 'complex64')
        #self.propFac = 1j*8*pi*sqrt(np.maximum((n/lamb)**2 - (u**2 + v**2), 0))
        #self.propFac = ((2*pi*n/lamb)*sqrt(np.maximum(1 - (u**2 + v**2), 0))).astype('f')
        self.propFac = ((2*pi*n/lamb)*cos(.5*pi*sqrt((u**2 + v**2)))).astype('f')
        self.pfm =(self.propFac > 0).astype('f')
        
        #self.field_x = field_x
        #self.field_y = field_y
        self.appR = apertureNA/n
        self.apertureZGrad = apertureZGradient
        self.x = u - field_x
        self.y = v - field_y

        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()
Esempio n. 4
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')
Esempio n. 5
0
    def prep(self):
        #allocate memory
        
        self._F = fftw3f.create_aligned_array(self.FTshape, 'complex64')
        self._r = fftw3f.create_aligned_array(self.shape, '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')
Esempio n. 6
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
Esempio n. 7
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
Esempio n. 8
0
    def InitBuffers(self):
        self._flush()
        bufSize = self.ImageSizeBytes.getValue()
        #print bufSize
        for i in range(self.nBuffers):
            #buf = np.empty(bufSize, 'uint8')
            buf = create_aligned_array(bufSize, 'uint8')
            self._queueBuffer(buf)

        self.doPoll = True
Esempio n. 9
0
    def InitBuffers(self):
        self._flush()
        bufSize = self.ImageSizeBytes.getValue()
        # print bufSize
        for i in range(self.nBuffers):
            # buf = np.empty(bufSize, 'uint8')
            buf = create_aligned_array(bufSize, "uint8")
            self._queueBuffer(buf)

        self.doPoll = True
Esempio n. 10
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)

        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()
Esempio n. 11
0
    def InitBuffers(self):
        self._flush()
        bufSize = self.ImageSizeBytes.getValue()
        vRed = int(self.SensorHeight.getValue() / self.AOIHeight.getValue())
        self.nBuffers = vRed * self.defBuffers
        #print bufSize
        for i in range(self.nBuffers):
            #buf = np.empty(bufSize, 'uint8')
            buf = create_aligned_array(bufSize, 'uint8')
            self._queueBuffer(buf)

        self.doPoll = True
 def InitBuffers(self):
     self._flush()
     bufSize = self.ImageSizeBytes.getValue()
     vRed = int(self.SensorHeight.getValue()/self.AOIHeight.getValue())
     self.nBuffers = vRed*self.defBuffers
     #print bufSize
     for i in range(self.nBuffers):
         #buf = np.empty(bufSize, 'uint8')
         buf = create_aligned_array(bufSize, 'uint8')
         self._queueBuffer(buf)
         
     self.doPoll = True
Esempio n. 13
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
Esempio n. 14
0
    def __init__(self, ps, vox, PSSize):
        ps = ps.max(2)
        ps = ps - ps.min()

        ps = ps * scipy.signal.hanning(
            ps.shape[0])[:, None] * scipy.signal.hanning(ps.shape[1])[None, :]
        ps = ps / ps.sum()
        #PSFFileName = PSFFilename

        pw = (numpy.array(PSSize) - ps.shape) / 2.
        pw1 = numpy.floor(pw)
        pw2 = numpy.ceil(pw)

        self.cachedPSF = pad.with_constant(ps, ((pw2[0], pw1[0]),
                                                (pw2[1], pw1[1])), (0, ))
        self.cachedOTFH = (ifftn(self.cachedPSF) *
                           self.cachedPSF.size).astype('complex64')
        self.cachedOTF2 = (self.cachedOTFH *
                           fftn(self.cachedPSF)).astype('complex64')

        self.weinerFT = fftw3.create_aligned_array(self.cachedOTFH.shape,
                                                   'complex64')
        self.weinerR = fftw3.create_aligned_array(self.cachedOTFH.shape,
                                                  'float32')

        self.planForward = fftw3.Plan(self.weinerR,
                                      self.weinerFT,
                                      flags=FFTWFLAGS,
                                      nthreads=NTHREADS)
        self.planInverse = fftw3.Plan(self.weinerFT,
                                      self.weinerR,
                                      direction='reverse',
                                      flags=FFTWFLAGS,
                                      nthreads=NTHREADS)

        fftwWisdom.save_wisdom()

        self.otf2mean = self.cachedOTF2.mean()
Esempio n. 15
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)
    
        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()
Esempio n. 16
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
Esempio n. 17
0
    def psf_calc(self, psf, data_size):
        '''Precalculate the OTF etc...'''
        #        pw = (numpy.array(data_size) - psf.shape)/2.
        #        pw1 = numpy.floor(pw)
        #        pw2 = numpy.ceil(pw)
        #
        #        g = psf/psf.sum()
        #
        #        #work out how we're going to need to pad to get the PSF the same size as our data
        #        if pw1[0] < 0:
        #            if pw2[0] < 0:
        #                g = g[-pw1[0]:pw2[0]]
        #            else:
        #                g = g[-pw1[0]:]
        #
        #            pw1[0] = 0
        #            pw2[0] = 0
        #
        #        if pw1[1] < 0:
        #            if pw2[1] < 0:
        #                g = g[-pw1[1]:pw2[1]]
        #            else:
        #                g = g[-pw1[1]:]
        #
        #            pw1[1] = 0
        #            pw2[1] = 0
        #
        #        if pw1[2] < 0:
        #            if pw2[2] < 0:
        #                g = g[-pw1[2]:pw2[2]]
        #            else:
        #                g = g[-pw1[2]:]
        #
        #            pw1[2] = 0
        #            pw2[2] = 0
        #
        #
        #        #do the padding
        #        #g = pad.with_constant(g, ((pw2[0], pw1[0]), (pw2[1], pw1[1]),(pw2[2], pw1[2])), (0,))
        #        g_ = fftw3f.create_aligned_array(data_size, 'float32')
        #        g_[:] = 0
        #        #print g.shape, g_.shape, g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:-pw1[2]].shape
        #        if pw1[2] == 0:
        #            g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:] = g
        #        else:
        #            g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:-pw1[2]] = g
        #        #g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:-pw1[2]] = g
        #        g = g_

        print psf.sum()

        g = resizePSF(psf, data_size)
        print g.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

        print('Calculating OTF')

        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(FTshape, 'complex64')
        self.Ht = fftw3f.create_aligned_array(FTshape, 'complex64')
        #self.f = zeros(self.shape, 'f4')
        #self.res = zeros(self.shape, 'f4')
        #self.S = zeros((size(self.f), 3), 'f4')

        self._F = fftw3f.create_aligned_array(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

        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')
Esempio n. 18
0
    def __init__(self, config, rig):
        self.config = config.corr
        self.performance = config.performance
        self.rig = rig
        self.subpx = subpxObj.newSubPx()

        self.fft_size = 2
        while self.fft_size < self.rig.size_small[
                0] or self.fft_size < self.rig.size_small[1]:
            self.fft_size *= 2
        # mask for short images (altitude)
        a = np.hanning(self.rig.size_short[1])
        self.mask_stereo = np.float32(
            np.repeat([a], self.rig.size_short[0], axis=0))
        self.disparity = np.float32(np.zeros(self.rig.size_short[0]))

        # mask for small images (registration)
        a = np.hanning(self.rig.size_small[1])
        b = np.hanning(self.rig.size_small[0])
        #a = np.hanning(self.fft_size)
        #b = np.hanning(self.fft_size)
        #a = a[(self.fft_size-self.rig.size_small[1])/2:(self.fft_size+self.rig.size_small[1])/2]
        #b = b[(self.fft_size-self.rig.size_small[0])/2:(self.fft_size+self.rig.size_small[0])/2]
        self.mask_motion = np.float32(np.dot(np.transpose([b]), [a]))

        # high pass filter for fft
        a = np.linspace(-0.5, 0.5, self.fft_size + 1)
        a = a[0:np.size(a) - 1]
        Xetanu = np.dot(np.transpose([np.cos(np.pi * a)]), [np.cos(np.pi * a)])
        self.high_pass = np.float32((1 - Xetanu) * (2 - Xetanu))
        middle = self.high_pass < 1
        self.high_pass[middle] = np.sqrt(self.high_pass[middle])

        # log polar transform
        self.log_base = 10
        self.rho = np.logspace(np.log(1) / np.log(self.log_base),
                               np.log(self.fft_size / 2) /
                               np.log(self.log_base),
                               num=self.fft_size,
                               base=self.log_base)
        c = (self.fft_size / 2, self.fft_size / 2)
        theta = np.linspace(0, np.pi, num=self.fft_size + 1)
        self.theta = theta[0:np.size(theta) - 1]
        x = np.dot(np.transpose([np.cos(self.theta)]), [self.rho]) + c[1]
        y = np.dot(np.transpose([np.sin(self.theta)]), [self.rho]) + c[0]
        self.logpolar_mapx = cv.fromarray(np.float32(x))
        self.logpolar_mapy = cv.fromarray(np.float32(y))

        # mask for log polar
        self.mask_lp = np.ones(x.shape)
        #a = np.hanning(self.fft_size)
        #self.mask_lp = np.float32(np.repeat([a], self.fft_size, axis=0))

        # memory allocation
        self.im_lp = cv.CreateMat(self.fft_size, self.fft_size, cv.CV_32FC1)

        # oh boy it's fftw time
        self.fftw_in = fftw.create_aligned_array(
            (self.fft_size, self.fft_size), dtype='complex64')
        self.fftw_out = fftw.create_aligned_array(
            (self.fft_size, self.fft_size), dtype='complex64')
        self.fftw_plan = fftw.planning.Plan(self.fftw_in,
                                            self.fftw_out,
                                            direction='forward',
                                            nthreads=self.performance.nthreads,
                                            flags=('measure', 'destroy input'))

        self.ifftw_in = fftw.create_aligned_array(
            (self.fft_size, self.fft_size), dtype='complex64')
        self.ifftw_out = fftw.create_aligned_array(
            (self.fft_size, self.fft_size), dtype='complex64')
        self.ifftw_plan = fftw.planning.Plan(
            self.ifftw_in,
            self.ifftw_out,
            direction='backward',
            nthreads=self.performance.nthreads,
            flags=('measure', 'destroy input'))
Esempio n. 19
0
    def psf_calc(self, psf, data_size):
        '''Precalculate the OTF etc...'''
#        pw = (numpy.array(data_size) - psf.shape)/2.
#        pw1 = numpy.floor(pw)
#        pw2 = numpy.ceil(pw)
#
#        g = psf/psf.sum()
#
#        #work out how we're going to need to pad to get the PSF the same size as our data
#        if pw1[0] < 0:
#            if pw2[0] < 0:
#                g = g[-pw1[0]:pw2[0]]
#            else:
#                g = g[-pw1[0]:]
#
#            pw1[0] = 0
#            pw2[0] = 0
#
#        if pw1[1] < 0:
#            if pw2[1] < 0:
#                g = g[-pw1[1]:pw2[1]]
#            else:
#                g = g[-pw1[1]:]
#
#            pw1[1] = 0
#            pw2[1] = 0
#
#        if pw1[2] < 0:
#            if pw2[2] < 0:
#                g = g[-pw1[2]:pw2[2]]
#            else:
#                g = g[-pw1[2]:]
#
#            pw1[2] = 0
#            pw2[2] = 0
#
#
#        #do the padding
#        #g = pad.with_constant(g, ((pw2[0], pw1[0]), (pw2[1], pw1[1]),(pw2[2], pw1[2])), (0,))
#        g_ = fftw3f.create_aligned_array(data_size, 'float32')
#        g_[:] = 0
#        #print g.shape, g_.shape, g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:-pw1[2]].shape
#        if pw1[2] == 0:
#            g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:] = g
#        else:
#            g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:-pw1[2]] = g
#        #g_[pw2[0]:-pw1[0], pw2[1]:-pw1[1], pw2[2]:-pw1[2]] = g
#        g = g_
        
        
        print psf.sum()
        
        g = resizePSF(psf, data_size)
        print g.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
        
        print('Calculating OTF') 

        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(FTshape, 'complex64')
        self.Ht = fftw3f.create_aligned_array(FTshape, 'complex64')
        #self.f = zeros(self.shape, 'f4')
        #self.res = zeros(self.shape, 'f4')
        #self.S = zeros((size(self.f), 3), 'f4')

        self._F = fftw3f.create_aligned_array(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;
        
        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')