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;
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()
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()
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 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')
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
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
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
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
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()
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
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
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()
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()
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
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')
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'))
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')