def update_probe_nonmodal(self, i, psi_old, psi_new): d1, d2 = self.positions.data id1, id2 = d1//1, d2//1 object_intensity_max = (abs(self.object)**2.0).data[0].max() self.probe.modes[0] += \ CXData.shift(conj(self.object[id1[i] - self.p2:id1[i] + self.p2, id2[i] - self.p2:id2[i] + self.p2]) * (psi_new-psi_old)[0] / object_intensity_max, d1[i]%1, d2[i]%1) self.probe.normalise()
def update_probe(self, i, psi_old, psi_new): d1, d2 = self.positions.data id1, id2 = d1//1, d2//1 object_intensity_max = (abs(self.object)**2.0).data[0].max() for mode in range(len(self.probe)): self.probe.modes[mode] += \ CXData.shift(conj(self.object[id1[i] - self.p2:id1[i] + self.p2, id2[i] - self.p2:id2[i] + self.p2]) * (psi_new-psi_old)[mode] / object_intensity_max, d1[i]%1, d2[i]%1) self.probe.normalise() self.probe.orthogonalise()
def update_object(self, i, psi_old, psi_new): """ Update the object from a single ptycho position. """ then=time.time() d1, d2 = self.positions.data id1, id2 = d1//1, d2//1 probe_intensity_max = CXModal.modal_sum(abs(self.probe)**2.0).data[0].max() self.object[id1[i] - self.p2:id1[i] + self.p2, id2[i] - self.p2:id2[i] + self.p2] += \ CXData.shift(CXModal.modal_sum(conj(self.probe) * (psi_new-psi_old)) / probe_intensity_max, d1[i]%1, d2[i]%1) if self.total_its==0 and sp.mod(i, len(self.positions.data[0]) / 10) == 0: self.update_figure(i)
def simulate_data(self): CXP.log.info('Simulating diffraction patterns.') self.sample = CXData() self.sample.load(CXP.io.simulation_sample_filename[0]) self.sample.data[0] = self.sample.data[0].astype(float) self.sample.normalise(val=0.8) self.sample.data[0]+=0.2 self.input_probe = CXModal() if len(CXP.io.simulation_sample_filename)>1: ph = CXData() ph.load(CXP.io.simulation_sample_filename[1]) ph.data[0] = ph.data[0].astype(float) ph.normalise(val=np.pi/3) self.sample.data[0] = self.sample.data[0]*exp(complex(0., 1.)*ph.data[0]) p = self.sample.data[0].shape[0] ham_window = sp.hamming(p)[:,np.newaxis]*sp.hamming(p)[np.newaxis,:] sample_large = CXData(data=sp.zeros((CXP.ob_p, CXP.ob_p), complex)) sample_large.data[0][CXP.ob_p/2-p/2:CXP.ob_p/2+p/2, CXP.ob_p/2-p/2:CXP.ob_p/2+p/2] = self.sample.data[0]*ham_window ker = sp.arange(0, p) fwhm = p/3.0 radker = sp.hypot(*sp.ogrid[-p/2:p/2,-p/2:p/2]) gaussian = exp(-1.0*(fwhm/2.35)**-2. * radker**2.0 ) ortho_modes = lambda n1, n2 : gaussian*np.sin(n1*math.pi*ker/p)[:,np.newaxis]*np.sin(n2*math.pi*ker/p)[np.newaxis, :] mode_generator = lambda : sp.floor(4*sp.random.random(2))+1 used_modes = [] self.input_psi = CXModal() for mode in range(CXP.reconstruction.probe_modes): if mode==0: new_mode = [1,1] else: new_mode = list(mode_generator()) while new_mode in used_modes: new_mode = list(mode_generator()) used_modes.append(new_mode) CXP.log.info('Simulating mode {:d}: [{:d}, {:d}]'.format(mode, int(new_mode[0]), int(new_mode[1]))) ph_func = gauss_smooth(np.random.random((p,p)), 10) self.input_probe.modes.append(CXData(name='probe{:d}'.format(mode), data=ortho_modes(new_mode[0], new_mode[1])*exp(complex(0.,np.pi)*ph_func/ph_func.max()))) self.input_probe.normalise() self.input_probe.orthogonalise() for mode in range(CXP.reconstruction.probe_modes): p2 = p/2 x, y = self.positions.correct self.input_psi.modes.append(CXData(name='input_psi_mode{:d}'.format(mode), data=[])) for i in xrange(len(x)): if i%(len(x)/10)==0.: CXP.log.info('Simulating diff patt {:d}'.format(i)) tmp = (CXData.shift(sample_large, -1.0*(x[i]-CXP.ob_p/2), -1.0*(y[i]-CXP.ob_p/2)) [CXP.ob_p/2-p2:CXP.ob_p/2+p2, CXP.ob_p/2-p2:CXP.ob_p/2+p2]* self.input_probe[mode][0]) self.input_psi[mode].data.append(tmp.data[0]) # Add modes incoherently self.det_mod = CXModal.modal_sum(abs(fft2(self.input_psi))) self.det_mod.save(path=CXP.io.base_dir+'/'+CXP.io.scan_id+'/raw_data/{:s}.npy'.format('det_mod'))