def group_retrieval(path_root, fname_flag): ''' path_root: the path to the directory containing the data files fname_flag: any string that you want to append to the file name while saving figures. ''' psf_list = glob.glob( path_root + "*.mat") # search all the .mat files and make the paths into a list psf_list.sort(key=os.path.getmtime) Strehl = [] pupil_list = {} FWHM = [] for fname in psf_list: session_name = os.path.split(fname)[-1][:-4] # show the psf filename print("psf:", session_name) psf_name = session_name psf_stack = load_mat(fname) figv, fhwm = psf_lineplot(psf_stack) figv.savefig(path_root + session_name + '_line') fl_nikon = 1000 * 200.0 / 60.0 FWHM.append(fhwm) pr = PSF_PF(psf_stack, dx=0.0800, dz=0.20, ld=0.520, nrefrac=1.33, NA=1.27, fl=fl_nikon, nIt=11) # phase retrieval core function. k_max = pr.PF.k_pxl # the radius of pupil in the unit of pixel (k-space) print("k_max:", k_max) pr.retrievePF(bscale=1.00, psf_diam=20 ) # psf_diam should be less than half of your array size pupil_final = pr.get_phase() # grab the phase from the pr class pupil_list[ psf_name] = pupil_final # save the pupil inside the dictionary Strehl.append(pr.strehl_ratio()) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.imshow(pupil_final, cmap='RdBu_r') ax.set_title(psf_name) plt.tight_layout() plt.axis('off') fig.savefig(path_root + psf_name + fname_flag) pf_crop = pupil_final[20 - k_max:20 + k_max, 20 - k_max:20 + k_max] print(pf_crop.shape) zfit = zern.fit_zernike(pf_crop, rad=k_max, nmodes=17)[0] / (2 * np.pi) zfit[:4] = 0.0 resync = zern.calc_zernike(zfit, rad=2 * k_max, mask=True) figr = IMshow_pupil(resync, axnum=False) figr.savefig(path_root + psf_name + '_zf_resync_' + fname_flag) figz = zern_display(zfit, z0=4, ylim=[-0.005, 0.02]) print("zshape:", zfit.shape) figz.savefig(path_root + psf_name + '_zfit_obj3') return Strehl, pupil_list
def zernSeg(self, z_ampli): """ Take amplitudes of zernike modes and synthesize into a pattern; convert into segment patterns. """ self.pattern = lzern.calc_zernike(z_ampli, self.radius, mask=self.useMask, zern_data={}) self.findSeg()
def syncRawZern(self, usemask=False): ''' create a raw_MOD. DM is not updated!!! ''' z_coeff = self.z_comps.sync_coeffs() self.raw_MOD = lzern.calc_zernike(z_coeff, self.radius, mask=usemask, zern_data={})
def syncRawZern(self): ''' create a raw_MOD. DM is not updated!!! ''' # self._switch_zern() usemask = self._ui.checkBox_mask.isChecked() # use mask or not? z_coeff = self.z_comps.sync_coeffs( ) # OK this is to be used only once. Otherwise too inconvenient. print("zernike coefficients:", z_coeff) self.raw_MOD = lzern.calc_zernike(z_coeff, self.radius, mask=usemask, zern_data={}) self.displayPhase()
def group_retrieval(path_root, fname_flag): ''' path_root: the path to the directory containing the data files fname_flag: any string that you want to append to the file name while saving figures. ''' psf_list = glob.glob(path_root+"*.mat") # search all the .mat files and make the paths into a list psf_list.sort(key = os.path.getmtime) Strehl = [] pupil_list = {} FWHM = [] for fname in psf_list: session_name = os.path.split(fname)[-1][:-4] # show the psf filename print("psf:", session_name) psf_name = session_name psf_stack = load_mat(fname) figv, fhwm = psf_lineplot(psf_stack) figv.savefig(path_root+session_name+'_line') fl_nikon = 1000*200.0/60.0 FWHM.append(fhwm) pr = PSF_PF(psf_stack, dx=0.0800, dz=0.20, ld=0.520, nrefrac=1.33, NA=1.27, fl=fl_nikon, nIt=11) # phase retrieval core function. k_max = pr.PF.k_pxl # the radius of pupil in the unit of pixel (k-space) print("k_max:", k_max) pr.retrievePF(bscale = 1.00, psf_diam = 20) # psf_diam should be less than half of your array size pupil_final = pr.get_phase() # grab the phase from the pr class pupil_list[psf_name] = pupil_final # save the pupil inside the dictionary Strehl.append(pr.strehl_ratio()) fig = plt.figure() ax = fig.add_subplot(1,1,1) ax.imshow(pupil_final, cmap = 'RdBu_r') ax.set_title(psf_name) plt.tight_layout() plt.axis('off') fig.savefig(path_root+psf_name+fname_flag) pf_crop = pupil_final[20-k_max:20+k_max, 20-k_max:20+k_max] print(pf_crop.shape) zfit = zern.fit_zernike(pf_crop,rad = k_max,nmodes = 17)[0]/(2*np.pi) zfit[:4] = 0.0 resync = zern.calc_zernike(zfit,rad = 2*k_max, mask = True) figr = IMshow_pupil(resync, axnum = False) figr.savefig(path_root+psf_name+'_zf_resync_'+ fname_flag) figz = zern_display(zfit, z0 = 4, ylim = [-0.005,0.02]) print("zshape:",zfit.shape) figz.savefig(path_root+psf_name+'_zfit_obj3') return Strehl, pupil_list
def rm4(self): ''' remove 1-4 modes of zernike ''' if self.z_fit is None: print( "The pupil function has not been fit to Zernike modes. Please fit first!" ) else: self.z_fit[:4] = 0. k_max = self._core.PF.k_pxl print("k_max:", k_max) cleaned_phase = zern.calc_zernike(self.z_fit, rad=k_max) print(cleaned_phase.shape) ampli = self._core.get_ampli(True) print(ampli.shape) strehl_clean = self.strehl_ratio(cleaned_phase, ampli) print("removed the first 4 modes. Strehl ratio:", strehl_clean) self.display_phase(cleaned_phase) self.display_fit(rm4=True) self.cleaned_phase = cleaned_phase
def aberration_coverslide_objective(NA, N_radius, g_tilt, lam = 0.550, n_med = 1.33, n_mis = 1.52): ''' Aberration of the whole objective. NA: the numerical aperture of the objective. N_radius: the grid number. The total grid number = 2*N_radius + 1. g_tilt: tilt angle of the coverslip ''' xx = np.arange([-N_radius, N_radius]) yy = xx [MX, MY] = np.meshgrid(xx,yy) a_max = np.arcsin(NA/n1) # maximum incidental angle, unit: radian h = N_radius/np.tan(a_max) MR = np.sqrt(MX**2 + MY**2) mask = MR<=N_radius M_inc = np.arctan(MR/h) M_rot = np.arccos(MX/MR) M_sl = cone_to_plane(np.pi-M_inc, a_max) # the mapped lateral position k_vec = incident_vec(np.pi-M_inc, M_rot) nz, ny, nx = k_vec.shape k_vec = np.reshape(k_vec, (nz, ny*nx)) # reshape the array n_vec = normal_vec(g_tilt, 0) n_ind = [n1,n2] for ip in np.arange(NN): ''' Iterate through NN vectors ''' nv = n_vec[:,ip] reflect_s = np.zeros(NK) reflect_p = np.zeros(NK) opd_array = np.zeros(NK) for ik in np.arange(NK): ''' iterate through the NN vectors of N_vec and NK vectors of K vec ''' kv = k_vec[:,ik] if(np.allclose(np.linalg.norm(kv),1.)): rv, Rs, Rp = refraction_plane(kv, nv, n1, n2) reflect_s[ik] = Rs reflect_p[ik] = Rp opl_diff = aberration_coverslide_ray(kv, rv, nv, d, n_ind)[0] opd_array[ik] = opl_diff else: print("Error!") opd_array = opd_array/lam rsm = reflect_s.reshape(ny, nx) rpm = reflect_p.reshape(ny, nx) rsm[np.logical_not(mask)] = 1. rpm[np.logical_not(mask)] = 1. RS_mat.append(rsm) RP_mat.append(rpm) raw_opd = opd_array.reshape(ny, nx) raw_opd[np.logical_not(mask)]=0 z_coeffs = zern.fit_zernike(raw_opd, rad = N_radius+0.5, nmodes = 25, zern_data={})[0] print(z_coeffs) z_deduct = z_coeffs[0:4] deduct_opd = zern.calc_zernike(z_deduct, rad = N_radius+0.5, mask = True) OPD_mat.append(raw_opd-deduct_opd) RSM = np.array(RS_mat) RPM = np.array(RP_mat) OPD = np.array(OPD_mat) T_aver = 1-(RSM+RPM) + 0.5*(RSM**2+RPM**2)
def aberration_coverslide_objective(NA, N_radius, g_tilt, lam=0.550, n_med=1.33, n_mis=1.52): ''' Aberration of the whole objective. NA: the numerical aperture of the objective. N_radius: the grid number. The total grid number = 2*N_radius + 1. g_tilt: tilt angle of the coverslip ''' xx = np.arange([-N_radius, N_radius]) yy = xx [MX, MY] = np.meshgrid(xx, yy) a_max = np.arcsin(NA / n1) # maximum incidental angle, unit: radian h = N_radius / np.tan(a_max) MR = np.sqrt(MX**2 + MY**2) mask = MR <= N_radius M_inc = np.arctan(MR / h) M_rot = np.arccos(MX / MR) M_sl = cone_to_plane(np.pi - M_inc, a_max) # the mapped lateral position k_vec = incident_vec(np.pi - M_inc, M_rot) nz, ny, nx = k_vec.shape k_vec = np.reshape(k_vec, (nz, ny * nx)) # reshape the array n_vec = normal_vec(g_tilt, 0) n_ind = [n1, n2] for ip in np.arange(NN): ''' Iterate through NN vectors ''' nv = n_vec[:, ip] reflect_s = np.zeros(NK) reflect_p = np.zeros(NK) opd_array = np.zeros(NK) for ik in np.arange(NK): ''' iterate through the NN vectors of N_vec and NK vectors of K vec ''' kv = k_vec[:, ik] if (np.allclose(np.linalg.norm(kv), 1.)): rv, Rs, Rp = refraction_plane(kv, nv, n1, n2) reflect_s[ik] = Rs reflect_p[ik] = Rp opl_diff = aberration_coverslide_ray(kv, rv, nv, d, n_ind)[0] opd_array[ik] = opl_diff else: print("Error!") opd_array = opd_array / lam rsm = reflect_s.reshape(ny, nx) rpm = reflect_p.reshape(ny, nx) rsm[np.logical_not(mask)] = 1. rpm[np.logical_not(mask)] = 1. RS_mat.append(rsm) RP_mat.append(rpm) raw_opd = opd_array.reshape(ny, nx) raw_opd[np.logical_not(mask)] = 0 z_coeffs = zern.fit_zernike(raw_opd, rad=N_radius + 0.5, nmodes=25, zern_data={})[0] print(z_coeffs) z_deduct = z_coeffs[0:4] deduct_opd = zern.calc_zernike(z_deduct, rad=N_radius + 0.5, mask=True) OPD_mat.append(raw_opd - deduct_opd) RSM = np.array(RS_mat) RPM = np.array(RP_mat) OPD = np.array(OPD_mat) T_aver = 1 - (RSM + RPM) + 0.5 * (RSM**2 + RPM**2)