def coronagraph(wfo, f_lens, occulter_type, diam): proper.prop_lens(wfo, f_lens, "coronagraph imaging lens") proper.prop_propagate(wfo, f_lens, "occulter") # occulter sizes are specified here in units of lambda/diameter; # convert lambda/diam to radians then to meters lamda = proper.prop_get_wavelength(wfo) occrad = 4. # occulter radius in lam/D occrad_rad = occrad * lamda / diam # occulter radius in radians dx_m = proper.prop_get_sampling(wfo) dx_rad = proper.prop_get_sampling_radians(wfo) occrad_m = occrad_rad * dx_m / dx_rad # occulter radius in meters plt.figure(figsize=(12,8)) if occulter_type == "GAUSSIAN": r = proper.prop_radius(wfo) h = np.sqrt(-0.5 * occrad_m**2 / np.log(1 - np.sqrt(0.5))) gauss_spot = 1 - np.exp(-0.5 * (r/h)**2) proper.prop_multiply(wfo, gauss_spot) plt.suptitle("Gaussian spot", fontsize = 18) elif occulter_type == "SOLID": proper.prop_circular_obscuration(wfo, occrad_m) plt.suptitle("Solid spot", fontsize = 18) elif occulter_type == "8TH_ORDER": proper.prop_8th_order_mask(wfo, occrad, CIRCULAR = True) plt.suptitle("8th order band limited spot", fontsize = 18) # After occulter plt.subplot(1,2,1) plt.imshow(np.sqrt(proper.prop_get_amplitude(wfo)), origin = "lower", cmap = plt.cm.gray) plt.text(200, 10, "After Occulter", color = "w") proper.prop_propagate(wfo, f_lens, "pupil reimaging lens") proper.prop_lens(wfo, f_lens, "pupil reimaging lens") proper.prop_propagate(wfo, 2*f_lens, "lyot stop") plt.subplot(1,2,2) plt.imshow(proper.prop_get_amplitude(wfo)**0.2, origin = "lower", cmap = plt.cm.gray) plt.text(200, 10, "Before Lyot Stop", color = "w") plt.show() if occulter_type == "GAUSSIAN": proper.prop_circular_aperture(wfo, 0.25, NORM = True) elif occulter_type == "SOLID": proper.prop_circular_aperture(wfo, 0.84, NORM = True) elif occulter_type == "8TH_ORDER": proper.prop_circular_aperture(wfo, 0.50, NORM = True) proper.prop_propagate(wfo, f_lens, "reimaging lens") proper.prop_lens(wfo, f_lens, "reimaging lens") proper.prop_propagate(wfo, f_lens, "final focus") return
def add_speckles(wfo, pair=True): sys.path.append(tp.FPWFSdir) import speckle_killer_v3 as skv3 # speckle = np.roll(np.roll(wfo.wfarr, loc[0],1),loc[1],0)*I#[92,92] # wfo.wfarr = (wfo.wfarr+speckle) # if pair: # speckle = np.roll(np.roll(wfo.wfarr, -1*loc[0],1),-1*loc[1],0)*I#[92,92] # wfo.wfarr = (wfo.wfarr+speckle) # dm_z = proper.prop_fits_read('dm.fits') # tp.diam = 0.1 # telescope diameter in meters configfilename = tp.FPWFSdir + 'speckle_null_config_Rupe.ini' configspecfile = tp.FPWFSdir + 'speckle_null_config.spec' config = ConfigObj(configfilename, configspec=configspecfile) val = Validator() check = config.validate(val) num_speck = len(tp.speck_locs) for s in range(num_speck): # in creating speckle object it will measure speckle intensity (in the pupil plane), just assign after speck = skv3.speckle(proper.prop_get_amplitude(wfo), tp.speck_locs[s][0], tp.speck_locs[s][1], config) # print tp.speck_phases # tp.speck_phases = [-np.pi] # print tp.speck_phases phase = tp.speck_phases[s] speck.intensity = tp.speck_peakIs[s] dm_z = speck.generate_flatmap(phase) #*4*I # quicklook_im(dm_z, logAmp=False) FPWFS.propagate_DM(wfo, tp.f_lens, dm_z)
def quicklook_wf(wfo, logAmp=True, show=True): after_dm = proper.prop_get_amplitude(wfo) phase_afterdm = proper.prop_get_phase(wfo) fig = plt.figure(figsize=(14, 10)) ax1 = plt.subplot2grid((3, 2), (0, 0), rowspan=2) ax2 = plt.subplot2grid((3, 2), (0, 1), rowspan=2) ax3 = plt.subplot2grid((3, 2), (2, 0)) ax4 = plt.subplot2grid((3, 2), (2, 1)) if logAmp: ax1.imshow(after_dm, origin='lower', cmap="YlGnBu_r", norm=LogNorm()) else: ax1.imshow(after_dm, origin='lower', cmap="YlGnBu_r") ax2.imshow(phase_afterdm, origin='lower', cmap="YlGnBu_r") #, vmin=-0.5, vmax=0.5) ax3.plot(after_dm[int(tp.grid_size / 2)]) ax3.plot(np.sum(np.eye(tp.grid_size) * after_dm, axis=1)) # plt.plot(np.sum(after_dm,axis=1)/after_dm[128,128]) ax4.plot(phase_afterdm[int(tp.grid_size / 2)]) # ax4.plot(np.sum(np.eye(tp.grid_size)*phase_afterdm,axis=1)) plt.xlim([0, proper.prop_get_gridsize(wfo)]) fig.set_tight_layout(True) if show == True: plt.show()
def take_src_return_imagedata(self, wfo, exptime=4): 1 #print("Warning, using fake pharo simulator!") self.i = self.i + 1 # imdata = np.zeros((1024, 1024)) # FPWFS.propagate_DM(wfo, f_lens, obj_map) # FPWFS.quicklook_wf(wfo) # FPWFS.quicklook_wf(wfo) return proper.prop_get_amplitude(wfo)
def lyot_stop(wf, mode='RAVC', ravc_r=0.6, ls_dRext=0.03, ls_dRint=0.05, ls_dRspi=0.04, spi_width=0.5, spi_angles=[0,60,120], diam_ext=37, diam_int=11, ls_misalign=None, file_app_phase='', file_app_amp='', ngrid=1024, npupil=285, margin=50, get_amp=False, get_phase=False, verbose=False, **conf): """Add a Lyot stop, or an APP.""" # case 1: Lyot stop if mode in ['CVC', 'RAVC']: # LS parameters r_obstr = ravc_r if mode in ['RAVC'] else diam_int/diam_ext ls_int = r_obstr + ls_dRint ls_ext = 1 - ls_dRext ls_spi = spi_width/diam_ext + ls_dRspi # LS misalignments ls_misalign = [0,0,0,0,0,0] if ls_misalign is None else list(ls_misalign) dx_amp, dy_amp, dz_amp = ls_misalign[0:3] dx_phase, dy_phase, dz_phase = ls_misalign[3:6] # create Lyot stop proper.prop_circular_aperture(wf, ls_ext, dx_amp, dy_amp, NORM=True) if diam_int > 0: proper.prop_circular_obscuration(wf, ls_int, dx_amp, dy_amp, NORM=True) if spi_width > 0: for angle in spi_angles: proper.prop_rectangular_obscuration(wf, ls_spi, 2, \ dx_amp, dy_amp, ROTATION=angle, NORM=True) if verbose is True: print('Create Lyot stop') print(' ls_int=%3.4f, ls_ext=%3.4f, ls_spi=%3.4f'\ %(ls_int, ls_ext, ls_spi)) print('') # case 2: APP elif mode in ['APP']: if verbose is True: print('Load APP from files\n') # get amplitude and phase data APP_amp = fits.getdata(file_app_amp) if os.path.isfile(file_app_amp) \ else np.ones((npupil, npupil)) APP_phase = fits.getdata(file_app_phase) if os.path.isfile(file_app_phase) \ else np.zeros((npupil, npupil)) # resize to npupil APP_amp = impro.resize_img(APP_amp, npupil) APP_phase = impro.resize_img(APP_phase, npupil) # pad with zeros to match PROPER ngrid APP_amp = impro.pad_img(APP_amp, ngrid, 1) APP_phase = impro.pad_img(APP_phase, ngrid, 0) # multiply the loaded APP proper.prop_multiply(wf, APP_amp*np.exp(1j*APP_phase)) # get the LS amplitude and phase for output LS_amp = impro.crop_img(proper.prop_get_amplitude(wf), npupil, margin)\ if get_amp is True else None LS_phase = impro.crop_img(proper.prop_get_phase(wf), npupil, margin)\ if get_phase is True else None return wf, LS_amp, LS_phase
def speckle_killer(wf, phase_map): # with open(iop.phase_ideal, 'rb') as handle: # phase_ideal = pickle.load(handle) # quicklook_im(phase_map, logAmp=False) ijofinterest = skv3.identify_bright_points(proper.prop_get_amplitude(wf), controlregion) xyofinterest = [p[::-1] for p in ijofinterest] print(xyofinterest, len(xyofinterest)) if len(xyofinterest) == 0: y = int(np.random.uniform(fp.controlregion[0], fp.controlregion[1])) x = int(np.random.uniform(fp.controlregion[2], fp.controlregion[3])) xyofinterest = [(y, x)] if len(xyofinterest) < fp.max_specks: fp.max_specks = len(xyofinterest) print(fp.max_specks) fps = skv3.filterpoints(xyofinterest, max=fp.max_specks, rad=fp.exclusionzone) print(fps) null_map = np.zeros((tp.ao_act, tp.ao_act)) for speck in fps: print(speck) kvecx, kvecy = DM.convert_pixels_kvecs(speck[0], speck[1], tp.grid_size / 2, tp.grid_size / 2, angle=0, lambdaoverd=fp.lod) dm_phase = phase_map[speck[1], speck[0]] s_amp = proper.prop_get_amplitude(wf)[speck[1], speck[0]] * 5.3 null_map += -DM.make_speckle_kxy(kvecx, kvecy, s_amp, dm_phase) #+s_ideal#- 1.9377 null_map /= len(fps) area_sum = np.sum(proper.prop_get_amplitude(wf) * controlregion) print(area_sum) with open(iop.measured_var, 'ab') as handle: pickle.dump(area_sum, handle, protocol=pickle.HIGHEST_PROTOCOL) return null_map
def imshow_amp(wf, npupil=None, margin=0): amp = proper.prop_get_amplitude(wf) ngrid = amp.shape[0] if npupil is None: npupil = ngrid start = int((ngrid - npupil + npupil % 2) / 2 - margin) start = 0 if start < 0 else start end = ngrid - start + npupil % 2 plt.imshow(amp[start:end, start:end], origin='lower')
def quicklook(self, wf=None, logZ=True, show=True, title=None): """ Produces a figure with an image of amplitude and one of phase as well as 1D slices through these images :param wf: optics.Wavefront :param logZ: bool logarithmic Z scaling :param show: bool display figure now or leave show() to be called by user later on :param title: str :return: """ if wf == None: wf = self.wf_collection[0,0] amp_map = proper.prop_get_amplitude(wf) phase_map = proper.prop_get_phase(wf) fig = plt.figure(figsize=(12, 10)) ax1 = plt.subplot2grid((1, 2), (0, 0), rowspan=2) # ((shape of grid to place axis x,y),(location x,y)) ax2 = plt.subplot2grid((1, 2), (0, 1), rowspan=2) # ax3 = plt.subplot2grid((3, 2), (2, 0)) # ax4 = plt.subplot2grid((3, 2), (2, 1)) if logZ: im1 = ax1.imshow(amp_map, origin='lower', cmap="YlGnBu_r", norm=LogNorm()) else: im1 = ax1.imshow(amp_map, origin='lower', cmap="YlGnBu_r") ax1.set_title('Amplitude Map') plt.colorbar(im1, ax=ax1) im2 = ax2.imshow(phase_map, origin='lower', cmap=sunlight) # , vmin=-0.5, vmax=0.5) ax2.set_title('Phase Map') plt.colorbar(im2, ax=ax2) # ax3.plot(after_dm[int(sp.grid_size / 2)]) # ax3.plot(np.sum(np.eye(sp.grid_size) * after_dm, axis=1), label=f'row {int(sp.grid_size / 2)}') # ax3.legend() # # # plt.plot(np.sum(after_dm,axis=1)/after_dm[128,128]) # # ax4.plot(phase_afterdm[int(sp.grid_size / 2)], label=f'row {int(sp.grid_size / 2)}') # ax4.legend() # # ax4.plot(np.sum(np.eye(ap.grid_size)*phase_afterdm,axis=1)) # plt.xlim([0, proper.prop_get_gridsize(wf)]) if not title: title = input(f"Always Add A Title\n " f"Please Enter Plane Name:") fig.suptitle(f"plane: {title}, lambda: {wf.lamda} m, body: {wf.name}", fontsize=18) else: fig.suptitle(f"plane: {title}, lambda: {wf.lamda} m, body: {wf.name}", fontsize=18) plt.subplots_adjust(top=0.9) if show: plt.show(block=True)
def apodize_pupil(wf): phase_map = proper.prop_get_phase(wf) amp_map = proper.prop_get_amplitude(wf) h, w = wf.wfarr.shape[:2] wavelength = wf.lamda scale = ap.wvl_range[0] / wavelength inds = circular_mask(h, w, radius=scale * 0.95 * h * sp.beam_ratio / 2) #TO DO remove hardcoded sizing, especially if use is default mask = np.zeros_like(phase_map) mask[inds] = 1 smooth_mask = gaussian_filter(mask, 1.5, mode='nearest') #TO DO remove hardcoded sizing, especially if use is default smoothed = phase_map * smooth_mask wf.wfarr = proper.prop_shift_center(amp_map * np.cos(smoothed) + 1j * amp_map * np.sin(smoothed))
def get_wf(wf, plane, npupil=None, margin=0, savefits=False): assert plane in ['amp','phi'], 'plane must be "amp" or "phi"' if plane is 'amp': img = proper.prop_get_amplitude(wf) elif plane is 'phi': img = proper.prop_get_phase(wf) ngrid = img.shape[0] if npupil is None: npupil = ngrid start = int((ngrid - npupil + npupil%2)/2 - margin) start = 0 if start < 0 else start end = ngrid - start + npupil%2 img = img[start:end,start:end] if savefits is True: fits.writeto('%s_npupil=%s_margin=%s.fits'%(plane, npupil, margin), \ np.float32(img), overwrite=True) return img
def hardmask_pupil(wf): """ hard-edged circular mask of the pupil plane. Masks out the WFS map outside of the beam since the DM modeled by proper can only be a square nxn grid of actuators, and thus the influence function surrounding each DM actuator could be affecting on-beam pixels, even if the actuator is acting on off-beam signal. In other words, even if a cornerDM actuator doesn't actuate on the beam, if there was non-zero signal in the WFS map, it will try to act on it, and it could 'influence' nearby DM actuators that are acting on the beam. This hard-edged mask is different from prop_circular_aperture in that it does not anti-alias the edges of the mask based on the 'fill factor' of the edge pixels. Instead, it has a boolean mask to zero everything > a fixed radius, in this case determined by the grid size and beam ratio of each wavefront passed into it. :param wf: a single wavefront :return: nothing is returned but the wf passed into it has been masked """ phase_map = proper.prop_get_phase(wf) amp_map = proper.prop_get_amplitude(wf) # Sizing the Mask h, w = wf.wfarr.shape[:2] center = (int(w / 2), int(h / 2)) radius = np.floor( sp.grid_size * wf.beam_ratio / 2) # Should scale with wavelength if sp.focused_system=False, # np.ceil used to oversize map so don't clip the beam # Making the Circular Boolean Mask Y, X = np.mgrid[:h, :w] dist_from_center = np.sqrt((X - center[0])**2 + (Y - center[1])**2) inds = dist_from_center <= radius # Applying the Mask to the Complex Array mask = np.zeros_like(phase_map) mask[inds] = 1 masked = phase_map * mask wf.wfarr = proper.prop_shift_center(amp_map * np.cos(masked) + 1j * amp_map * np.sin(masked))
def lyotstop(self, wf, RAVC=None, APP=None, get_pupil='no', dnpup=50): """Add a Lyot stop, or an APP.""" # load parameters npupil = 1 #conf['NPUPIL'] pad = int((210 - npupil) / 2) # get LS misalignments LS_misalignment = (np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) * npupil).astype(int) dx_amp, dy_amp, dz_amp = LS_misalignment[0:3] dx_phase, dy_phase, dz_phase = LS_misalignment[3:6] # case 1: Lyot stop (no APP) if APP is not True: # Lyot stop parameters: R_out, dR_in, spi_width # outer radius (absolute %), inner radius (relative %), spider width (m) (R_out, dR_in, spi_width) = [0.98, 0.03, 0] # Lyot stop inner radius at least as large as obstruction radius R_in = 0.15 # case of a ring apodizer if RAVC is True: # define the apodizer transmission and apodizer radius [Mawet2013] # apodizer radius at least as large as obstruction radius T_ravc = 1 - (R_in**2 + R_in * np.sqrt(R_in**2 + 8)) / 4 R_in /= np.sqrt(1 - T_ravc) # oversize Lyot stop inner radius R_in += dR_in # create Lyot stop proper.prop_circular_aperture(wf, R_out, dx_amp, dy_amp, NORM=True) if R_in > 0: proper.prop_circular_obscuration(wf, R_in, dx_amp, dy_amp, NORM=True) if spi_width > 0: for angle in [10]: proper.prop_rectangular_obscuration(wf, 0.05 * 8, 8 * 1.3, ROTATION=20) proper.prop_rectangular_obscuration(wf, 8 * 1.3, 0.05 * 8, ROTATION=20) # proper.prop_rectangular_obscuration(wf, spi_width, 2 * 8, \ # dx_amp, dy_amp, ROTATION=angle) # case 2: APP (no Lyot stop) else: # get amplitude and phase files APP_amp_file = os.path.join(conf['INPUT_DIR'], conf['APP_AMP_FILE']) APP_phase_file = os.path.join(conf['INPUT_DIR'], conf['APP_PHASE_FILE']) # get amplitude and phase data APP_amp = getdata(APP_amp_file) if os.path.isfile(APP_amp_file) \ else np.ones((npupil, npupil)) APP_phase = getdata(APP_phase_file) if os.path.isfile(APP_phase_file) \ else np.zeros((npupil, npupil)) # resize to npupil APP_amp = resize(APP_amp, (npupil, npupil), preserve_range=True, mode='reflect') APP_phase = resize(APP_phase, (npupil, npupil), preserve_range=True, mode='reflect') # pad with zeros to match PROPER gridsize APP_amp = np.pad(APP_amp, [(pad + 1 + dx_amp, pad - dx_amp), \ (pad + 1 + dy_amp, pad - dy_amp)], mode='constant') APP_phase = np.pad(APP_phase, [(pad + 1 + dx_phase, pad - dx_phase), \ (pad + 1 + dy_phase, pad - dy_phase)], mode='constant') # multiply the loaded APP proper.prop_multiply(wf, APP_amp * np.exp(1j * APP_phase)) # get the pupil amplitude or phase for output if get_pupil.lower() in 'amplitude': return wf, proper.prop_get_amplitude(wf)[pad + 1 - dnpup:-pad + dnpup, pad + 1 - dnpup:-pad + dnpup] elif get_pupil.lower() in 'phase': return wf, proper.prop_get_phase(wf)[pad + 1 - dnpup:-pad + dnpup, pad + 1 - dnpup:-pad + dnpup] else: return wf
def pupil(diam, gridsize, spiders_width, spiders_angle, pixelsize, r_obstr, wavelength, pupil_file, missing_segments_number=0, Debug='False', Debug_print='False', prefix='test'): beam_ratio = pixelsize * 4.85e-9 / (wavelength / diam) wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) n = int(gridsize) npupil = np.ceil( gridsize * beam_ratio ) # compute the pupil size --> has to be ODD (proper puts the center in the up right pixel next to the grid center) if npupil % 2 == 0: npupil = npupil + 1 if (Debug_print == True): print("npupil: ", npupil) print("lambda: ", wavelength) if (missing_segments_number == 0): if (isinstance(pupil_file, (list, tuple, np.ndarray)) == True): pupil = pupil_file pupil_pixels = (pupil.shape)[0] ## fits file size scaling_factor = float(npupil) / float( pupil_pixels ) ## scaling factor between the fits file size and the pupil size of the simulation if (Debug_print == True): print("scaling_factor: ", scaling_factor) pupil_scale = cv2.resize( pupil.astype(np.float32), (0, 0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR ) # scale the pupil to the pupil size of the simualtions if (Debug_print == True): print("pupil_resample", pupil_scale.shape) pupil_large = np.zeros( (n, n)) # define an array of n-0s, where to insert the pupuil if (Debug_print == True): print("n: ", n) print("npupil: ", npupil) pupil_large[ int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 + int(npupil / 2), int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 + int(npupil / 2 )] = pupil_scale # insert the scaled pupil into the 0s grid proper.prop_circular_aperture( wfo, diam / 2) # create a wavefront with a circular pupil if (isinstance(pupil_file, (list, tuple, np.ndarray)) == True): proper.prop_multiply(wfo, pupil_large) # multiply the saved pupil else: proper.prop_circular_obscuration( wfo, r_obstr, NORM=True ) # create a wavefront with a circular central obscuration if (spiders_width != 0): for iter in range(0, len(spiders_angle)): proper.prop_rectangular_obscuration( wfo, spiders_width, 2 * diam, ROTATION=spiders_angle[iter]) # define the spiders else: if (missing_segments_number == 1): pupil = fits.getdata( input_dir + '/ELT_2048_37m_11m_5mas_nospiders_1missing_cut.fits') if (missing_segments_number == 2): pupil = fits.getdata( input_dir + '/ELT_2048_37m_11m_5mas_nospiders_2missing_cut.fits') if (missing_segments_number == 4): pupil = fits.getdata( input_dir + '/ELT_2048_37m_11m_5mas_nospiders_4missing_cut.fits') if (missing_segments_number == 7): pupil = fits.getdata( input_dir + '/ELT_2048_37m_11m_5mas_nospiders_7missing_1_cut.fits') pupil_pixels = (pupil.shape)[0] ## fits file size scaling_factor = float(npupil) / float( pupil_pixels ) ## scaling factor between the fits file size and the pupil size of the simulation if (Debug_print == True): print("scaling_factor: ", scaling_factor) pupil_scale = cv2.resize( pupil.astype(np.float32), (0, 0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR ) # scale the pupil to the pupil size of the simualtions if (Debug_print == True): print("pupil_resample", pupil_scale.shape) pupil_large = np.zeros( (n, n)) # define an array of n-0s, where to insert the pupuil if (Debug_print == True): print("n: ", n) print("npupil: ", npupil) pupil_large[ int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 + int(npupil / 2), int(n / 2) + 1 - int(npupil / 2) - 1:int(n / 2) + 1 + int(npupil / 2)] = pupil_scale # insert the scaled pupil into the 0s grid proper.prop_multiply(wfo, pupil_large) # multiply the saved pupil if (spiders_width != 0): for iter in range(0, len(spiders_angle)): proper.prop_rectangular_obscuration( wfo, spiders_width, 2 * diam, ROTATION=spiders_angle[iter]) # define the spiders if (Debug == True): fits.writeto( out_dir + prefix + '_intial_pupil.fits', proper.prop_get_amplitude(wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) proper.prop_define_entrance(wfo) #define the entrance wavefront wfo.wfarr *= 1. / np.amax(wfo._wfarr) # max(amplitude)=1 return (npupil, wfo)
def create_pupil(nhr=2**10, npupil=285, pupil_img_size=40, diam_ext=37, diam_int=11, spi_width=0.5, spi_angles=[0, 60, 120], seg_width=0, seg_gap=0, seg_rms=0, seg_ny=[ 10, 13, 16, 19, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 19, 16, 13, 10 ], seg_missing=[], seed=123456, **conf): ''' Create a pupil. Args: nhr: int high resolution grid npupil: int number of pixels of the pupil pupil_img_size: float pupil image (for PROPER) in m diam_ext: float outer circular aperture in m diam_int: float central obscuration in m spi_width: float spider width in m spi_angles: list of float spider angles in deg seg_width: float segment width in m seg_gap: float gap between segments in m seg_rms: float rms of the reflectivity of all segments seg_ny: list of int number of hexagonal segments per column (from left to right) seg_missing: list of tupples coordinates of missing segments ''' # create a high res pupil with PROPER of even size (nhr) nhr_size = pupil_img_size * nhr / (nhr - 1) wf_tmp = proper.prop_begin(nhr_size, 1, nhr, diam_ext / nhr_size) if diam_ext > 0: proper.prop_circular_aperture(wf_tmp, 1, NORM=True) if diam_int > 0: proper.prop_circular_obscuration(wf_tmp, diam_int / diam_ext, NORM=True) if spi_width > 0: for angle in spi_angles: proper.prop_rectangular_obscuration(wf_tmp, spi_width/nhr_size, 2, \ ROTATION=angle, NORM=True) pup = proper.prop_get_amplitude(wf_tmp) # crop the pupil to odd size (nhr-1), and resize to npupil pup = pup[1:, 1:] pup = resize_img(pup, npupil) # add segments if seg_width > 0: segments = np.zeros((nhr, nhr)) # sampling in meters/pixel sampling = pupil_img_size / nhr # dist between center of two segments, side by side seg_d = seg_width * np.cos(np.pi / 6) + seg_gap # segment radius seg_r = seg_width / 2 # segment radial distance wrt x and y axis seg_ny = np.array(seg_ny) seg_nx = len(seg_ny) seg_rx = np.arange(seg_nx) - (seg_nx - 1) / 2 seg_ry = (seg_ny - 1) / 2 # loop through segments np.random.seed(seed) for i in range(seg_nx): seg_x = seg_rx[i] * seg_d * np.cos(np.pi / 6) seg_y = -seg_ry[i] * seg_d for j in range(1, seg_ny[i] + 1): # removes secondary and if any missing segment is present if (np.sqrt(seg_x**2 + seg_y**2) <= 4.01*seg_d) \ or ((seg_rx[i], j) in seg_missing): seg_y += seg_d else: # creates one hexagonal segment at x, y position in meters segment = create_hexagon(nhr, seg_r, seg_y, seg_x, sampling) # multiply by segment reflectivity and add to segments seg_refl = np.random.normal(1, seg_rms) segments += segment * seg_refl seg_y += seg_d # need to transpose, due to the orientation of hexagons in create_hexagon segments = segments.T # resize to npupil, and add to pupil segments = resize_img(segments, npupil) pup *= segments return pup
def apodizer(wf, mode='RAVC', ravc_t=0.8, ravc_r=0.6, ravc_misalign=None, ngrid=1024, npupil=285, file_ravc_amp='', file_ravc_phase='', margin=50, get_amp=False, get_phase=False, verbose=False, **conf): ''' Create a wavefront object at the entrance pupil plane. The pupil is either loaded from a fits file, or created using pupil parameters. Can also select only one petal and mask the others. wf: WaveFront PROPER wavefront object mode: str HCI mode ravc_t: float RA transmittance ravc_r: float RA radius ravc_misalign: list of float RA misalignment ngrid: int number of pixels of the wavefront array npupil: int number of pixels of the pupil file_ravc_amp: str file_ravc_phase: str ring apodizer files (optional) ''' if mode in ['RAVC']: # load apodizer from files if provided if os.path.isfile(file_ravc_amp) and os.path.isfile(file_ravc_phase): if verbose is True: print('Load ring apodizer from files\n') # get amplitude and phase data RAVC_amp = fits.getdata(file_ravc_amp) RAVC_phase = fits.getdata(file_ravc_phase) # resize to npupil RAVC_amp = impro.resize_img(RAVC_amp, npupil) RAVC_phase = impro.resize_img(RAVC_phase, npupil) # pad with zeros to match PROPER gridsize RAVC_amp = impro.pad_img(RAVC_amp, ngrid) RAVC_phase = impro.pad_img(RAVC_phase, ngrid) # build complex apodizer apo = RAVC_amp * np.exp(1j * RAVC_phase) # or else, define the apodizer as a ring (with % misalignments) else: # RAVC misalignments ravc_misalign = [ 0, 0, 0, 0, 0, 0 ] if ravc_misalign is None else list(ravc_misalign) dx_amp, dy_amp, dz_amp = ravc_misalign[0:3] dx_phase, dy_phase, dz_phase = ravc_misalign[3:6] # create apodizer apo = circular_apodization(wf, ravc_r, 1., ravc_t, xc=dx_amp, \ yc=dy_amp, NORM=True) apo = proper.prop_shift_center(apo) if verbose is True: print('Create ring apodizer') print(' ravc_t=%3.4f, ravc_r=%3.4f'\ %(ravc_t, ravc_r)) print(' ravc_misalign=%s' % ravc_misalign) print('') # multiply the loaded apodizer proper.prop_multiply(wf, apo) # get the apodizer amplitude and phase for output apo_amp = impro.crop_img(proper.prop_get_amplitude(wf), npupil,\ margin) if get_amp is True else None apo_phase = impro.crop_img(proper.prop_get_phase(wf), npupil,\ margin) if get_phase is True else None return wf, apo_amp, apo_phase else: # no ring apodizer return wf, None, None
def speck_killing_loop(wfo): #configfilename = 'speckle_null_config.ini' #config = ConfigObj(configfilename) configfilename = tp.FPWFSdir + 'speckle_null_config_Rupe.ini' hardwareconfigfile = tp.FPWFSdir + 'speckle_instruments.ini' configspecfile = tp.FPWFSdir + 'speckle_null_config.spec' print(configfilename) config = ConfigObj(configfilename, configspec=configspecfile) val = Validator() check = config.validate(val) #pharo = hardware.PHARO_COM('PHARO', # configfile = hardwareconfigfile) #p3k = hardware.P3K_COM('P3K_COM', configfile = hardwareconfigfile) camera = hardware.camera() ao = hardware.ao() apmask = False if not apmask: aperturemask = np.ones((66, 66)) if apmask: aperturemask = dm.annularmask(66, 12, 33) # nulled_field = None im_params = config['IM_PARAMS'] null_params = config['NULLING'] abc = config['INTENSITY_CAL']['abc'] use_centoffs = config['NULLING']['cent_off'] #bgds = flh.setup_bgd_dict(config) fake_bgds = { 'bkgd': np.zeros((tp.grid_size, tp.grid_size)), 'masterflat': np.ones((tp.grid_size, tp.grid_size)), 'badpix': np.zeros((tp.grid_size, tp.grid_size)) } print("WARNING: USING FAKE BGDS") bgds = fake_bgds.copy() # controlregion = pf.open(tp.FPWFSdir+config['CONTROLREGION']['filename'])[0].data # controlregion = controlregion[512-int(tp.grid_size/2):512+int(tp.grid_size/2), 512-int(tp.grid_size/2):512+int(tp.grid_size/2)] # controlregion = np.roll(controlregion, 15) # controlregion[:,0:70] = 0 # controlregion[:80] = 0 # controlregion[-80:] = 0 controlregion = np.zeros((tp.grid_size, tp.grid_size)) controlregion[50:80, 35:50] = 1 boarder = get_ctrlrgnBoarder(controlregion) quicklook_im(controlregion, logAmp=False) # plt.show(block=True) #Notes==>scale exptime in snr exp = config['INTENSITY_CAL']['exptime'] #Setup # initial_flatmap = ao.grab_current_flatmap() # initial_centoffs= ao.grab_current_centoffs() defaultim = np.ones((tp.grid_size, tp.grid_size)) vertsx = config['CONTROLREGION']['verticesx'] vertsy = config['CONTROLREGION']['verticesy'] # plt.ion() fig = plt.figure(figsize=(12, 12)) ax1 = plt.subplot2grid((4, 4), (0, 0), rowspan=2, colspan=2) ax2 = plt.subplot2grid((4, 4), (0, 2), rowspan=2, colspan=2) ax3 = plt.subplot2grid((4, 4), (3, 0)) ax4 = plt.subplot2grid((4, 4), (2, 2), rowspan=2, colspan=2) #ax5 = plt.subplot2grid((4,4),(3,2)) # ax1b =plt.subplot2grid((4,4),(0, 0), rowspan =2, colspan = 2) title = fig.suptitle('Speckle destruction') ax1.set_title('Image') ax2.set_title('Control region') ax3.set_title('RMS in region') ax4.set_title('Image') #ax5.set_title('Intensity') w1 = ax1.imshow(np.log10(np.abs(defaultim)) + boarder, origin='lower', interpolation='nearest') current_cmap = cm.get_cmap() current_cmap.set_bad(color='white') # w1b = ax1b.imshow(boarder*10, origin='lower', interpolation = 'none') # ax1.set_xlim(min(vertsx), max(vertsx)) # ax1.set_ylim(min(vertsy), max(vertsy)) #ax1.set_ylim(int(im_params['centery'])-25, int(im_params['centery']+50)) w2 = ax2.imshow(np.log(np.abs(controlregion * defaultim)), origin='lower', interpolation='nearest') # ax2.set_xlim(min(vertsx), max(vertsx)) # ax2.set_ylim(min(vertsy), max(vertsy)) w3 = ax3.plot([], []) ax3.set_xlim(0, 10) w4, = ax4.plot(np.abs(defaultim[64])) # w4 = ax4.imshow(np.log10(np.abs(defaultim))+boarder, origin='lower', interpolation = 'nearest') current_cmap = cm.get_cmap() current_cmap.set_bad(color='white') N_iterations = 10 itcounter = [] maxfluxes = [] meanfluxes = [] totalfluxes = [] rmsfluxes = [] #w5 = ax5.plot(np.arange(10)*0, np.arange(10)*0) # w4 = ax4.imshow(np.log(camera.take_src_return_imagedata(exptime =exp)[242:758, 242:758]), origin='lower', interpolation = 'nearest') plt.show() tstamp = time.strftime("%Y%m%d-%H%M%S").replace(' ', '_') cubeoutputdir = os.path.join(null_params['outputdir'], tstamp) if not os.path.exists(cubeoutputdir): os.makedirs(cubeoutputdir) print(configfilename) result_imagecube = output_imagecube(N_iterations, tp.grid_size, filepath=os.path.join( cubeoutputdir, 'test_' + tstamp + '.fits'), comment='fun', configfile=configfilename) clean_imagecube = output_imagecube(N_iterations, tp.grid_size, filepath=os.path.join( cubeoutputdir, 'test_clean_' + tstamp + '.fits'), comment='fun', configfile=configfilename) cal_imagecube = output_imagecube(4, tp.grid_size, filepath=os.path.join( cubeoutputdir, 'test_cals_' + tstamp + '.fits'), comment='fun', configfile=configfilename) cal_imagecube.update(controlregion) cal_imagecube.update(bgds['bkgd']) cal_imagecube.update(bgds['masterflat']) cal_imagecube.update(bgds['badpix']) ####MAIN LOOP STARTS HERE##### print("BEGINNING NULLING LOOP") for iteration in range(N_iterations): # quicklook_wf(wfo) itcounter.append(iteration) if use_centoffs == False: current_flatmap = ao.grab_current_flatmap() if use_centoffs == True: current_centoffs = ao.grab_current_centoffs() # quicklook_im(current_flatmap, logAmp=False, show=True) print("Taking image of speckle field") # if nulled_field != None: # raw_im = nulled_field # else: raw_im = camera.take_src_return_imagedata(wfo, exptime=exp) result_imagecube.update(raw_im) field_im = pre.equalize_image(raw_im, **bgds) clean_imagecube.update(field_im) field_ctrl = field_im * controlregion # print np.shape(field_im), np.shape(controlregion), np.shape(field_ctrl) # plt.figure() # plt.imshow(field_im) # plt.figure() # plt.imshow(controlregion) # plt.figure() # plt.imshow(field_ctrl) # plt.show(block=True) meanfluxes.append(np.mean(field_ctrl[field_ctrl > 0])) maxfluxes.append(np.max(field_ctrl[field_ctrl > 0])) totalfluxes.append(np.sum(field_ctrl)) rmsfluxes.append( np.std(field_ctrl[field_ctrl > 0]) / config['NULLING']['referenceval']) ax3.plot(itcounter, rmsfluxes) #w5 = plt.plot(itcounter, maxfluxes) #w5 = plt.plot(itcounter, totalfluxes) ax1.set_title('Iteration: ' + str(iteration) + ', Mean: ' + str(meanfluxes[iteration]) + ', Max: ' + str(maxfluxes[iteration])) w1.set_data(np.log(np.abs(field_ctrl)) + boarder) w1.autoscale() plt.draw() plt.pause(0.02) if iteration > 0: try: printstats(field_im, speckleslist) except: pass flh.writeout(current_flatmap, 'latestiteration.fits') # ans = raw_input('Do you want to run a speckle nulling iteration[Y/N]?') ans = 'Y' if ans == 'N': flatmapans = eval( input('Do you want to reload the' + 'flatmap/centoffs you started with[Y/N]?')) if flatmapans == 'Y': print("Reloading initial flatmap/centoffs") if use_centoffs == False: status = ao.load_new_flatmap((initial_flatmap)) if use_centoffs == True: status = ao.load_new_centoffs((initial_centoffs)) #ao.load_new_flatmap(initial_flatmap) break print(('Iteration ' + str(iteration) + ' total_intensity: ' + str(np.sum(field_ctrl)))) #return a list of points print("computing interesting bright spots") #note indices and coordinates are reversed ijofinterest = identify_bright_points(field_ctrl, controlregion) xyofinterest = [p[::-1] for p in ijofinterest] print(("computed ", str(len(xyofinterest)), " bright spots")) max_specks = config['DETECTION']['max_speckles'] #if len(xyofinterest)>50: # xyofinterest = xyofinterest[0:49] if len(xyofinterest) < max_specks: max_specks = len(xyofinterest) fps = filterpoints(xyofinterest, max=max_specks, rad=config['NULLING']['exclusionzone']) print(fps) print("creating speckle objects") speckleslist = [speckle(field_im, xy[0], xy[1], config) for xy in fps] speckleslist = [x for x in speckleslist if (x.intensity) > 0] #old way--filter the speckles #speckleslist =[speckle(field_im, xy[0], xy[1], config) for xy in xyofinterest] #speckleslist = filterspeckles(speckleslist, max = max_specks) phases = null_params['phases'] # phases = [-np.pi/2.,0,np.pi/2.,np.pi] for idx, phase in enumerate(phases): print(("Phase ", phase)) phaseflat = 0 allspeck_aps = 0 #put in sine waves at speckle locations for speck in speckleslist: #XXX # phaseflat= phaseflat+speck.generate_flatmap(phase) phaseflat = speck.generate_flatmap(phase) # quicklook_im(speck.generate_flatmap(phase), logAmp=False) allspeck_aps = allspeck_aps + speck.aperture print('here') ax2.set_title('Phase: ' + str(phase)) if idx == 0: # w1.set_data( (allspeck_aps*field_ctrl)-0.95*field_ctrl) w1.set_data( np.log(np.abs((allspeck_aps * field_im) - 0.95 * field_im)) + boarder) w1.autoscale() plt.draw() #w1.set_data(field_ctrl); w1.autoscale(); plt.draw() phaseflat = phaseflat * aperturemask # plt.figure() # plt.imshow(allspeck_aps) # plt.show() # ans = raw_input('press enter') wf_temp = copy.copy(wfo) if use_centoffs == False: status = ao.load_new_flatmap(current_flatmap + phaseflat, wf_temp) # if use_centoffs == True: # status = ao.load_new_centoffs(current_centoffs+ # fmf.convert_flatmap_centoffs(phaseflat)) tp.variable = proper.prop_get_phase(wf_temp)[20, 20] print(('speck phase', tp.variable, 'intensity', proper.prop_get_amplitude(wf_temp)[20, 20])) # plt.show(block=True) # quicklook_wf(wf_temp, show=True) phaseim = camera.take_src_return_imagedata(wf_temp, exptime=exp) # quicklook_im(phaseim, show=True) phaseim = pre.equalize_image(phaseim, **bgds) # quicklook_im(phaseim, show=True) w2.set_data(np.log(np.abs(phaseim * controlregion))) w2.autoscale() plt.draw() plt.pause(0.02) # w4.set_data(range(128), np.sum(np.eye(tp.grid_size)*proper.prop_get_amplitude(wf_temp),axis=1))#ax4.plot(range(128), proper.prop_get_amplitude(wf_temp)[20])#np.abs(field_im[20]))#+boarder) w4.set_data( list(range(128)), proper.prop_get_amplitude(wf_temp)[64] ) # ax4.plot(range(128), proper.prop_get_amplitude(wf_temp)[20])#np.abs(field_im[20]))#+boarder) ax4.set_xlim([0, 128]) ax4.set_ylim([0, 0.2]) print("recomputing intensities") for speck in speckleslist: phase_int = speck.recompute_intensity(phaseim) speck.phase_intensities[idx] = phase_int print((speck.phase_intensities)) time.sleep(3) # if use_centoffs == False: # ao.load_new_flatmap(current_flatmap, wf_temp) # # if use_centoffs == True: # # ao.load_new_centoffs(current_centoffs) if config['NULLING']['null_gain'] == False: defaultgain = config['NULLING']['default_flatmap_gain'] nullmap = generate_phase_nullmap(speckleslist, defaultgain, phases) nullmap = nullmap * aperturemask if use_centoffs == False: # ao.load_new_flatmap(current_flatmap + nullmap, wfo) ao.load_new_flatmap(nullmap, wfo) # FPWFS.quicklook_wf(wfo) # camera.take_src_return_imagedata(wfo, exptime=exp) # if use_centoffs == True: # ao.load_new_centoffs(current_centoffs+ fmf.convert_flatmap_centoffs(nullmap)) # ans = raw_input('press enter') if config['NULLING']['null_gain'] == True: ##NOW CALCULATE GAIN NULLS print("DETERMINING NULL GAINS") gains = config['NULLING']['amplitudegains'] for idx, gain in enumerate(gains): print("Checking optimal gains") nullmap = generate_phase_nullmap(speckleslist, gain, phases) nullmap = nullmap * aperturemask wf_temp = copy.copy(wfo) if use_centoffs == False: ao.load_new_flatmap(current_flatmap + nullmap, wf_temp) # if use_centoffs == True: # ao.load_new_centoffs(current_centoffs+ fmf.convert_flatmap_centoffs(nullmap)) ampim = camera.take_src_return_imagedata(wf_temp, exptime=exp) # quicklook_wf(wf_temp) ampim = pre.equalize_image(ampim, **bgds) w2.set_data(np.log(np.abs(ampim * controlregion))) ax2.set_title('Gain: ' + str(gain)) w2.autoscale() plt.draw() plt.pause(0.02) for speck in speckleslist: amp_int = speck.recompute_intensity(ampim) speck.gain_intensities[idx] = amp_int print((speck.gain_intensities)) w4.set_data( list(range(128)), proper.prop_get_amplitude(wf_temp)[64] ) #ax4.plot(range(128), proper.prop_get_amplitude(wf_temp)[20])#np.abs(field_im[20]))#+boarder) ax4.set_xlim([0, 128]) ax4.set_ylim([0, 0.2]) for speck in speckleslist: speck.compute_null_gain() supernullmap = generate_super_nullmap(speckleslist, phases) print( "Loading supernullmap now that optimal gains have been found!") supernullmap = supernullmap * aperturemask if use_centoffs == False: # ao.load_new_flatmap(current_flatmap + supernullmap, wfo) ao.load_new_flatmap(supernullmap, wfo) # FPWFS.quicklook_wf(wfo) # quicklook_im(supernullmap,logAmp=False, show=True) # camera.take_src_return_imagedata(wfo, exptime=exp) # if use_centoffs == True: # ao.load_new_centoffs(current_centoffs+ fmf.convert_flatmap_centoffs(supernullmap)) #ao.load_new_flatmap(supernullmap) # w3.set_data(nullmap) # plt.draw() # w4.set_data(np.log(np.abs(field_im))+boarder) # plt.draw() # w4.autoscale(); # quicklook_im(field_im, logAmp=False) quicklook_wf(wfo) plt.show(block=True) # ans = raw_input('press enter') # try: # check = raw_input("would you like to continue?: ") # except EOFError: # print ("Error: EOF or empty input!") # check = "" # print check plt.show(block=False)
def simple_telescope(wavelength, gridsize): # Define entrance aperture diameter and other quantities d_objective = 5.0 # objective diameter in meters fl_objective = 20.0 * d_objective # objective focal length in meters fl_eyepiece = 0.021 # eyepiece focal length fl_eye = 0.022 # human eye focal length beam_ratio = 0.3 # initial beam width/grid width # Define the wavefront wfo = proper.prop_begin(d_objective, wavelength, gridsize, beam_ratio) # print d_objective, wavelength, gridsize, beam_ratio # Define a circular aperture proper.prop_circular_aperture(wfo, d_objective / 2) # proper.prop_propagate(wfo, fl_objective) # proper.prop_propagate(wfo, fl_objective) # proper.prop_propagate(wfo, fl_objective) # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() # Define entrance proper.prop_define_entrance(wfo) # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() # proper.prop_propagate(wfo, fl_objective+fl_eyepiece, "eyepiece") # # plt.imshow(proper.prop_get_amplitude(wfo)) # # plt.show() # # proper.prop_propagate(wfo, fl_objective+fl_eyepiece, "eyepiece") # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() # # proper.prop_propagate(wfo, fl_objective+fl_eyepiece, "eyepiece") # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() # Define a lens proper.prop_lens(wfo, fl_objective, "objective") # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() # Propagate the wavefront proper.prop_propagate(wfo, fl_objective + fl_eyepiece, "eyepiece") # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() # Define another lens proper.prop_lens(wfo, fl_eyepiece, "eyepiece") # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() exit_pupil_distance = fl_eyepiece / (1 - fl_eyepiece / (fl_objective + fl_eyepiece)) proper.prop_propagate(wfo, exit_pupil_distance, "exit pupil at eye lens") # quicklook_wf(wfo) # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() proper.prop_lens(wfo, fl_eye, "eye") proper.prop_propagate(wfo, fl_eye, "retina") # plt.imshow(proper.prop_get_amplitude(wfo)) # plt.show() quicklook_wf(wfo) phase_map = proper.prop_get_phase(wfo) amp_map = proper.prop_get_amplitude(wfo) # quicklook_im(phase_map) amp_map[80:100, 80:100] = 0 quicklook_im(amp_map, logAmp=True) import numpy as np wfo.wfarr = proper.prop_shift_center(amp_map * np.cos(phase_map) + 1j * amp_map * np.sin(phase_map)) # quicklook_wf(wf_array[iw,0]) proper.prop_propagate(wfo, fl_eye, "retina") proper.prop_lens(wfo, fl_eye, "eye") quicklook_wf(wfo) # End (wfo, sampling) = proper.prop_end(wfo) return (wfo, sampling)
def lyotstop(wf, conf, RAVC): input_dir = conf['INPUT_DIR'] diam = conf['DIAM'] npupil = conf['NPUPIL'] spiders_angle = conf['SPIDERS_ANGLE'] r_obstr = conf['R_OBSTR'] Debug = conf['DEBUG'] Debug_print = conf['DEBUG_PRINT'] LS_amplitude_apodizer_file = conf['AMP_APODIZER'] LS_misalignment = np.array(conf['LS_MIS_ALIGN']) if conf['PHASE_APODIZER_FILE'] == 0: LS_phase_apodizer_file = 0 else: LS_phase_apodizer_file = fits.getdata(input_dir + '/' + conf['PHASE_APODIZER_FILE']) LS = conf['LYOT_STOP'] LS_parameters = np.array(conf['LS_PARA']) n = proper.prop_get_gridsize(wf) if (RAVC == True): # define the inner radius of the Lyot Stop t1_opt = 1. - 1. / 4 * ( r_obstr**2 + r_obstr * (math.sqrt(r_obstr**2 + 8.)) ) # define the apodizer transmission [Mawet2013] R1_opt = (r_obstr / math.sqrt(1. - t1_opt) ) # define teh apodizer radius [Mawet2013] r_LS = R1_opt + LS_parameters[ 1] # when a Ring apodizer is present, the inner LS has to have at least the value of the apodizer radius else: r_LS = r_obstr + LS_parameters[ 1] # when no apodizer, the LS has to have at least the radius of the pupil central obstruction if LS == True: # apply the LS if (Debug_print == True): print("LS parameters: ", LS_parameters) proper.prop_circular_aperture(wf, LS_parameters[0], LS_misalignment[0], LS_misalignment[1], NORM=True) proper.prop_circular_obscuration(wf, r_LS, LS_misalignment[0], LS_misalignment[1], NORM=True) if (LS_parameters[2] != 0): for iter in range(0, len(spiders_angle)): if (Debug_print == True): print("LS_misalignment: ", LS_misalignment) proper.prop_rectangular_obscuration( wf, LS_parameters[2], 2 * diam, LS_misalignment[0], LS_misalignment[1], ROTATION=spiders_angle[iter]) # define the spiders if (Debug == True): out_dir = str('./output_files/') fits.writeto( out_dir + '_Lyot_stop.fits', proper.prop_get_amplitude(wf)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) if (isinstance(LS_phase_apodizer_file, (list, tuple, np.ndarray)) == True): xc_pixels = int(LS_misalignment[3] * npupil) yc_pixels = int(LS_misalignment[4] * npupil) apodizer_pixels = (LS_phase_apodizer_file.shape)[0] ## fits file size scaling_factor = float(npupil) / float( apodizer_pixels ) ## scaling factor between the fits file size and the pupil size of the simulation # scaling_factor = float(npupil)/float(pupil_pixels) ## scaling factor between the fits file size and the pupil size of the simulation if (Debug_print == True): print("scaling_factor: ", scaling_factor) apodizer_scale = cv2.resize( LS_phase_apodizer_file.astype(np.float32), (0, 0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR ) # scale the pupil to the pupil size of the simualtions if (Debug_print == True): print("apodizer_resample", apodizer_scale.shape) apodizer_large = np.zeros( (n, n)) # define an array of n-0s, where to insert the pupuil if (Debug_print == True): print("npupil: ", npupil) apodizer_large[ int(n / 2) + 1 - int(npupil / 2) - 1 + xc_pixels:int(n / 2) + 1 + int(npupil / 2) + xc_pixels, int(n / 2) + 1 - int(npupil / 2) - 1 + yc_pixels:int(n / 2) + 1 + int(npupil / 2) + yc_pixels] = apodizer_scale # insert the scaled pupil into the 0s grid phase_multiply = np.array(np.zeros((n, n)), dtype=complex) # create a complex array phase_multiply.imag = apodizer_large # define the imaginary part of the complex array as the atm screen apodizer = np.exp(phase_multiply) proper.prop_multiply(wf, apodizer) if (Debug == True): fits.writeto('LS_apodizer.fits', proper.prop_get_phase(wf), overwrite=True) if (isinstance(LS_amplitude_apodizer_file, (list, tuple, np.ndarray)) == True): print('4th') xc_pixels = int(LS_misalignment[0] * npupil) yc_pixels = int(LS_misalignment[1] * npupil) apodizer_pixels = ( LS_amplitude_apodizer_file.shape)[0] ## fits file size scaling_factor = float(npupil) / float( pupil_pixels ) ## scaling factor between the fits file size and the pupil size of the simulation if (Debug_print == True): print("scaling_factor: ", scaling_factor) apodizer_scale = cv2.resize( amplitude_apodizer_file.astype(np.float32), (0, 0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR ) # scale the pupil to the pupil size of the simualtions if (Debug_print == True): print("apodizer_resample", apodizer_scale.shape) apodizer_large = np.zeros( (n, n)) # define an array of n-0s, where to insert the pupuil if (Debug_print == True): print("grid_size: ", n) print("npupil: ", npupil) apodizer_large[ int(n / 2) + 1 - int(npupil / 2) - 1 + xc_pixels:int(n / 2) + 1 + int(npupil / 2) + xc_pixels, int(n / 2) + 1 - int(npupil / 2) - 1 + yc_pixels:int(n / 2) + 1 + int(npupil / 2) + yc_pixels] = apodizer_scale # insert the scaled pupil into the 0s grid apodizer = apodizer_large proper.prop_multiply(wf, apodizer) if (Debug == True): fits.writeto('LS_apodizer.fits', proper.prop_get_amplitude(wf), overwrite=True) return wf
def scexao_model(lmda, grid_size, kwargs): """ propagates instantaneous complex E-field thru Subaru from the DM through SCExAO uses PyPROPER3 to generate the complex E-field at the pupil plane, then propagates it through SCExAO 50x50 DM, then coronagraph, to the focal plane :returns spectral cube at instantaneous time in the focal_plane() """ # print("Propagating Broadband Wavefront Through Subaru") # Initialize the Wavefront in Proper wfo = proper.prop_begin(entrance_d, lmda, grid_size, beam_ratio) # Defines aperture (baffle-before primary) proper.prop_circular_aperture(wfo, entrance_d / 2) proper.prop_define_entrance(wfo) # normalizes abs intensity # Test Sampling if kwargs['verbose'] and kwargs['ix'] == 0: check1 = proper.prop_get_sampling(wfo) print( f"\n\tDM Pupil Plane\n" f"sampling at aperture is {check1 * 1e3:.4f} mm\n" f"Total Sim is {check1 * 1e3 * grid_size:.2f}x{check1 * 1e3 * grid_size:.2f} mm\n" f"Diameter of beam is {check1 * 1e3 * grid_size * beam_ratio:.4f} mm over {grid_size * beam_ratio} pix" ) # SCExAO Reimaging 1 proper.prop_lens( wfo, fl_SxOAPG) # produces f#14 beam (approx exit beam of AO188) proper.prop_propagate(wfo, fl_SxOAPG * 2) # move to second pupil if kwargs['verbose'] and kwargs['ix'] == 0: print(f"initial f# is {proper.prop_get_fratio(wfo):.2f}\n") ######################################## # Import/Apply Actual DM Map # ####################################### plot_flag = False if kwargs['verbose'] and kwargs['ix'] == 0: plot_flag = True dm_map = kwargs['map'] errormap(wfo, dm_map, SAMPLING=dm_pitch, MIRROR_SURFACE=True, MASKING=True, BR=beam_ratio, PLOT=plot_flag) # MICRONS=True if kwargs['verbose'] and kwargs['ix'] == 0: fig, subplot = plt.subplots(nrows=1, ncols=2, figsize=(12, 5)) ax1, ax2 = subplot.flatten() fig.suptitle('SCExAO Model WFO after errormap', fontweight='bold', fontsize=14) ax1.imshow(proper.prop_get_amplitude(wfo), interpolation='none' ) # np.abs(proper.prop_shift_center(wfo.wfarr))**2 ax1.set_title('Amplitude') ax2.imshow( proper.prop_get_phase(wfo), interpolation= 'none', # np.angle(proper.prop_shift_center(wfo.wfarr)) vmin=-1 * np.pi, vmax=1 * np.pi, cmap='hsv') # , cmap='hsv' ax2.set_title('Phase') # ------------------------------------------------ # SCExAO Reimaging 2 proper.prop_lens(wfo, fl_SxOAPG) proper.prop_propagate(wfo, fl_SxOAPG) # focus at exit of DM telescope system proper.prop_lens(wfo, fl_SxOAPG) proper.prop_propagate(wfo, fl_SxOAPG) # focus at exit of DM telescope system # # Coronagraph SubaruPupil(wfo) # focal plane mask # if kwargs['verbose'] and kwargs['ix']==0: # fig, subplot = plt.subplots(nrows=1, ncols=2, figsize=(12, 5)) # ax1, ax2 = subplot.flatten() # fig.suptitle('SCExAO Model WFO after FPM', fontweight='bold', fontsize=14) # # ax.imshow(dm_map, interpolation='none') # ax1.imshow(np.abs(proper.prop_shift_center(wfo.wfarr))**2, interpolation='none', norm=LogNorm(vmin=1e-7,vmax=1e-2)) # ax1.set_title('Amplitude') # ax2.imshow(np.angle(proper.prop_shift_center(wfo.wfarr)), interpolation='none', # vmin=-2*np.pi, vmax=2*np.pi, cmap='hsv') # , cmap='hsv' # ax2.set_title('Phase') proper.prop_propagate(wfo, fl_SxOAPG) proper.prop_lens(wfo, fl_SxOAPG) proper.prop_propagate(wfo, fl_SxOAPG) # middle of 2f system proper.prop_circular_aperture(wfo, lyot_size, NORM=True) # lyot stop proper.prop_propagate(wfo, fl_SxOAPG) # proper.prop_lens(wfo, fl_SxOAPG) # exit lens of gaussian telescope proper.prop_propagate(wfo, fl_SxOAPG) # to focus # MEC Pickoff reimager. proper.prop_propagate(wfo, mec_parax_fl) # to another pupil proper.prop_lens( wfo, mec_parax_fl) # collimating lens, pupil size should be 8 mm proper.prop_propagate(wfo, mec1_fl + .0142557) # mec1_fl .054 mec1_fl+.0101057 # if kwargs['verbose'] and kwargs['ix']==0: # current = proper.prop_get_beamradius(wfo) # print(f'Beam Radius after SCExAO exit (at MEC foreoptics entrance) is {current*1e3:.3f} mm\n' # f'current f# is {proper.prop_get_fratio(wfo):.2f}\n') # ################################## # MEC Optics Box # ################################### proper.prop_circular_aperture(wfo, 0.00866) # reading off the zemax diameter proper.prop_lens(wfo, mec1_fl) # MEC lens 1 proper.prop_propagate(wfo, mec_l1_l2) # there is a image plane at z=mec1_fl proper.prop_lens(wfo, mec2_fl) # MEC lens 2 (tiny lens) proper.prop_propagate(wfo, mec_l2_l3) proper.prop_lens(wfo, mec3_fl) # MEC lens 3 proper.prop_propagate(wfo, mec3_fl, TO_PLANE=False) # , TO_PLANE=True mec_l3_focus # ####################################### # Focal Plane # ####################################### # Check Sampling in focal plane # shifts wfo from Fourier Space (origin==lower left corner) to object space (origin==center) # wf, samp = proper.prop_end(wfo, NoAbs=True) wf = proper.prop_shift_center(wfo.wfarr) wf = extract_center(wf, new_size=np.array(kwargs['psf_size'])) samp = proper.prop_get_sampling(wfo) smp_asec = proper.prop_get_sampling_arcsec(wfo) if kwargs['verbose'] and kwargs['ix'] == 0: fig, subplot = plt.subplots(nrows=1, ncols=2, figsize=(12, 5)) fig.subplots_adjust(left=0.08, hspace=.4, wspace=0.2) ax1, ax2 = subplot.flatten() fig.suptitle('SCExAO Model Focal Plane', fontweight='bold', fontsize=14) tic_spacing, tic_labels, axlabel = scale_lD( wfo, newsize=kwargs['psf_size'][0]) tic_spacing[0] = tic_spacing[0] + 1 # hack for edge effects tic_spacing[-1] = tic_spacing[-1] - 1 # hack for edge effects im = ax1.imshow( np.abs(wf)**2, interpolation='none', norm=LogNorm( vmin=1e-7, vmax=1e-2)) # np.abs(proper.prop_shift_center(wfo.wfarr))**2 ax1.set_xticks(tic_spacing) ax1.set_xticklabels(tic_labels) ax1.set_yticks(tic_spacing) ax1.set_yticklabels(tic_labels) ax1.set_ylabel(axlabel, fontsize=8) add_colorbar(im) im = ax2.imshow(np.angle(wf), interpolation='none', vmin=-np.pi, vmax=np.pi, cmap='hsv') ax2.set_xticks(tic_spacing) ax2.set_xticklabels(tic_labels) ax2.set_yticks(tic_spacing) ax2.set_yticklabels(tic_labels) ax2.set_ylabel(axlabel, fontsize=8) add_colorbar(im) if kwargs['verbose'] and kwargs['ix'] == 0: print( f"\nFocal Plane\n" f"sampling at focal plane is {samp*1e6:.1f} um ~= {smp_asec * 1e3:.4f} mas\n" f"\tfull FOV is {samp * kwargs['psf_size'][0] * 1e3:.2f} x {samp * kwargs['psf_size'][1] * 1e3:.2f} mm " ) # s_rad = proper.prop_get_sampling_radians(wfo) # print(f"sampling at focal plane is {s_rad * 1e6:.6f} urad") print(f'final focal ratio is {proper.prop_get_fratio(wfo)}') print(f"Finished simulation") return wf, samp
def lyotstop(wf, diam, r_obstr, npupil, RAVC, LS, LS_parameters, spiders_angle, LS_phase_apodizer_file, LS_amplitude_apodizer_file, LS_misalignment, path, Debug_print, Debug): if (RAVC==True): # define the inner radius of the Lyot Stop t1_opt = 1. - 1./4*(r_obstr**2 + r_obstr*(math.sqrt(r_obstr**2 + 8.))) # define the apodizer transmission [Mawet2013] R1_opt = (r_obstr/math.sqrt(1. - t1_opt)) # define teh apodizer radius [Mawet2013] r_LS = R1_opt + LS_parameters[1] # when a Ring apodizer is present, the inner LS has to have at least the value of the apodizer radius else: r_LS = r_obstr + LS_parameters[1] # when no apodizer, the LS has to have at least the radius of the pupil central obstruction if LS==True: # apply the LS if (Debug_print==True): print("LS parameters: ", LS_parameters) proper.prop_circular_aperture(wf, LS_parameters[0], LS_misalignment[0], LS_misalignment[1], NORM=True) proper.prop_circular_obscuration(wf, r_LS, LS_misalignment[0], LS_misalignment[1], NORM=True) if (LS_parameters[2]!=0): for iter in range(0,len(spiders_angle)): if (Debug_print==True): print("LS_misalignment: ", LS_misalignment) proper.prop_rectangular_obscuration(wf, LS_parameters[2], 2*diam,LS_misalignment[0], LS_misalignment[1], ROTATION=spiders_angle[iter]) # define the spiders if (isinstance(LS_phase_apodizer_file, (list, tuple, np.ndarray)) == True): xc_pixels = int(LS_misalignment[3]*npupil) yc_pixels = int(LS_misalignment[4]*npupil) apodizer_pixels = (LS_phase_apodizer_file.shape)[0]## fits file size scaling_factor = float(npupil)/float(pupil_pixels) ## scaling factor between the fits file size and the pupil size of the simulation if (Debug_print==True): print ("scaling_factor: ", scaling_factor) apodizer_scale = cv2.resize(phase_apodizer_file.astype(np.float32), (0,0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR) # scale the pupil to the pupil size of the simualtions if (Debug_print==True): print ("apodizer_resample", apodizer_scale.shape) apodizer_large = np.zeros((n,n)) # define an array of n-0s, where to insert the pupuil if (Debug_print==True): print("n: ", n) print("npupil: ", npupil) apodizer_large[int(n/2)+1-int(npupil/2)-1 + xc_pixels:int(n/2)+1+int(npupil/2)+ xc_pixels,int(n/2)+1-int(npupil/2)-1+ yc_pixels:int(n/2)+1+int(npupil/2)+ yc_pixels] =apodizer_scale # insert the scaled pupil into the 0s grid phase_multiply = np.array(np.zeros((n,n)), dtype=complex) # create a complex array phase_multiply.imag = apodizer_large # define the imaginary part of the complex array as the atm screen apodizer = np.exp(phase_multiply) proper.prop_multiply(wf, apodizer) if (Debug == True): fits.writeto(path + 'LS_apodizer.fits', proper.prop_get_phase(wf), overwrite=True) if (isinstance(LS_amplitude_apodizer_file, (list, tuple, np.ndarray)) == True): xc_pixels = int(LS_misalignment[0]*npupil) yc_pixels = int(LS_misalignment[1]*npupil) apodizer_pixels = (LS_amplitude_apodizer_file.shape)[0]## fits file size scaling_factor = float(npupil)/float(pupil_pixels) ## scaling factor between the fits file size and the pupil size of the simulation if (Debug_print==True): print ("scaling_factor: ", scaling_factor) apodizer_scale = cv2.resize(amplitude_apodizer_file.astype(np.float32), (0,0), fx=scaling_factor, fy=scaling_factor, interpolation=cv2.INTER_LINEAR) # scale the pupil to the pupil size of the simualtions if (Debug_print==True): print ("apodizer_resample", apodizer_scale.shape) apodizer_large = np.zeros((n,n)) # define an array of n-0s, where to insert the pupuil if (Debug_print==True): print("n: ", n) print("npupil: ", npupil) apodizer_large[int(n/2)+1-int(npupil/2)-1 + xc_pixels:int(n/2)+1+int(npupil/2)+ xc_pixels,int(n/2)+1-int(npupil/2)-1+ yc_pixels:int(n/2)+1+int(npupil/2)+ yc_pixels] =apodizer_scale # insert the scaled pupil into the 0s grid apodizer = apodizer_large proper.prop_multiply(wf, apodizer) if (Debug == True): fits.writeto(path + 'LS_apodizer.fits', proper.prop_get_amplitude(wf), overwrite=True) return
def telescope( wavelength, gridsize, PASSVALUE={ 'prefix': 'prova', 'path': os.path.abspath(os.path.join(__file__, os.pardir)), 'charge': 0, 'CAL': 0, 'diam': 37., 'spiders_width': 0.60, 'spiders_angle': [0., 60., 120.], 'beam_ratio': 0.25, 'f_lens': 658.6, 'npupil': 243, 'r_obstr': 0.3, 'pupil_file': 0, 'phase_apodizer_file': 0, 'amplitude_apodizer_file': 0, 'TILT': [0., 0.], 'LS': False, 'RAVC': False, 'LS_phase_apodizer_file': 0, 'LS_amplitude_apodizer_file': 0, 'LS_parameters': [0.0, 0.0, 0.0], 'atm_screen': 0, 'missing_segments_number': 0, 'apodizer_misalignment': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'LS_misalignment': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'Island_Piston': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'NCPA': 0, 'Debug_print': False, 'Debug': False }): ## call all the vues passed via passvalue prefix = PASSVALUE['prefix'] path = PASSVALUE['path'] charge = PASSVALUE['charge'] CAL = PASSVALUE['CAL'] diam = PASSVALUE['diam'] spiders_width = PASSVALUE['spiders_width'] spiders_angle = PASSVALUE['spiders_angle'] beam_ratio = PASSVALUE['beam_ratio'] f_lens = PASSVALUE['f_lens'] npupil = PASSVALUE['npupil'] r_obstr = PASSVALUE['r_obstr'] pupil_file = PASSVALUE['pupil_file'] phase_apodizer_file = PASSVALUE['phase_apodizer_file'] amplitude_apodizer_file = PASSVALUE['amplitude_apodizer_file'] TILT = PASSVALUE['TILT'] LS = PASSVALUE['LS'] RAVC = PASSVALUE['RAVC'] LS_phase_apodizer_file = PASSVALUE['LS_phase_apodizer_file'] LS_amplitude_apodizer_file = PASSVALUE['LS_amplitude_apodizer_file'] LS_parameters = PASSVALUE['LS_parameters'] atm_screen = PASSVALUE['atm_screen'] missing_segments_number = PASSVALUE['missing_segments_number'] apodizer_misalignment = PASSVALUE['apodizer_misalignment'] LS_misalignment = PASSVALUE['LS_misalignment'] Island_Piston = PASSVALUE['Island_Piston'] NCPA = PASSVALUE['NCPA'] Debug_print = PASSVALUE['Debug_print'] Debug = PASSVALUE['Debug'] TILT = np.array(TILT) apodizer_misalignment = np.array(apodizer_misalignment) LS_misalignment = np.array(LS_misalignment) Island_Piston = np.array(Island_Piston) ## call the size of the grid n = int(gridsize) wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) # define the simualtion pupil lamda = proper.prop_get_wavelength( wfo) #save the wavelength value [m] into lamda if (Debug_print == True): print("lambda: ", lamda) pupil(wfo, CAL, npupil, diam, r_obstr, spiders_width, spiders_angle, pupil_file, missing_segments_number, Debug, Debug_print) if (Debug == True): fits.writeto( path + prefix + '_pupil_pre_define.fits', proper.prop_get_amplitude(wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) proper.prop_define_entrance(wfo) #define the entrance wavefront #wfo.wfarr *= 1./np.amax(wfo._wfarr) # max(amplitude)=1 if (isinstance(atm_screen, (list, tuple, np.ndarray)) == True) and ( atm_screen.ndim >= 2): # when the atmosphere is present print('atmosphere') atmosphere(wfo, npupil, atm_screen, Debug_print, Debug) if (isinstance(NCPA, (list, tuple, np.ndarray)) == True) and (NCPA.ndim >= 2): # when the atmosphere is present NCPA_application(wfo, npupil, NCPA, path, Debug_print, Debug) if (RAVC == True) or (isinstance(phase_apodizer_file, (list, tuple, np.ndarray)) == True) or (isinstance(amplitude_apodizer_file, (list, tuple, np.ndarray)) == True): # when tha apodizer is present apodization(wfo, r_obstr, npupil, RAVC, phase_apodizer_file, amplitude_apodizer_file, apodizer_misalignment, Debug_print, Debug) if (all(v == 0 for v in Island_Piston) == False): # when the piston is present island_effect_piston(wfo, npupil, Island_Piston, path, Debug_print, Debug) if (TILT.any != 0.): # when tip/tilt if (Debug_print == True): print("TILT: ", TILT) print("lamda: ", lamda) tiptilt = (np.multiply( TILT, lamda )) / 4 # translate the tip/tilt from lambda/D into RMS phase errors proper.prop_zernikes(wfo, [2, 3], tiptilt) # 2-->xtilt, 3-->ytilt if (Debug == True): if CAL == 1: fits.writeto(path + prefix + '_pupil_amplitude_CAL1.fits', proper.prop_get_amplitude(wfo) [int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) fits.writeto( path + prefix + '_pupil_phase_CAL1.fits', proper.prop_get_phase(wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) else: fits.writeto( path + prefix + '_pupil_amplitude_CAL0_RA' + str(int(RAVC)) + '_charge' + str(charge) + '_ATM' + str( int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)) + '.fits', proper.prop_get_amplitude( wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) fits.writeto( path + prefix + '_pupil_phase_CAL0_RA' + str(int(RAVC)) + '_charge' + str(charge) + '_ATM' + str( int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)) + '.fits', proper.prop_get_phase(wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) proper.prop_propagate(wfo, f_lens, 'inizio') # propagate wavefront proper.prop_lens(wfo, f_lens, 'focusing lens vortex') # propagate through a lens proper.prop_propagate(wfo, f_lens, 'VC') # propagate wavefront vortex(wfo, CAL, charge, f_lens, path, Debug_print) if (Debug == True): if CAL == 1: fits.writeto(path + prefix + '_afterVortex_CAL1.fits', proper.prop_get_amplitude(wfo) [int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) fits.writeto( path + prefix + '_afterVortex_CAL1_phase.fits', proper.prop_get_phase(wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) else: print( 'ATM: ', str( int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True))) if ((((int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)))) == 1): print('atm_screen: ', atm_screen.shape) print( 'ATM: ', int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)) fits.writeto( path + prefix + '_afterVortex_CAL0_RA' + str(int(RAVC)) + '_charge' + str(charge) + '_ATM' + str( int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)) + '.fits', proper.prop_get_amplitude( wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) fits.writeto( path + prefix + '_afterVortex_phase_CAL0_RA' + str(int(RAVC)) + '_charge' + str(charge) + '_ATM' + str( int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)) + '.fits', proper.prop_get_phase(wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) proper.prop_propagate(wfo, f_lens, 'Lyot Collimetor') # propagate wavefront proper.prop_lens(wfo, f_lens, 'Lyot Collimetor') # propagate wavefront through a lens proper.prop_propagate(wfo, f_lens, 'Lyot Stop') # propagate wavefront if (Debug == True): if CAL == 1: fits.writeto(path + prefix + '_beforeLS_CAL1.fits', proper.prop_get_amplitude(wfo) [int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) else: fits.writeto( path + prefix + '_beforeLS_CAL0_charge' + str(charge) + '_ATM' + str( int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)) + '.fits', proper.prop_get_amplitude( wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) lyotstop(wfo, diam, r_obstr, npupil, RAVC, LS, LS_parameters, spiders_angle, LS_phase_apodizer_file, LS_amplitude_apodizer_file, LS_misalignment, path, Debug_print, Debug) if (Debug == True): if CAL == 1: fits.writeto(path + prefix + '_afterLS_CAL1.fits', proper.prop_get_amplitude(wfo) [int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) else: fits.writeto( path + prefix + '_afterLS_CAL0_charge' + str(charge) + '_LS' + str(int(LS)) + '_RA' + str(int(RAVC)) + '_ATM' + str( int( isinstance(atm_screen, (list, tuple, np.ndarray)) == True)) + '.fits', proper.prop_get_amplitude( wfo)[int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50), int(n / 2) - int(npupil / 2 + 50):int(n / 2) + int(npupil / 2 + 50)], overwrite=True) proper.prop_propagate(wfo, f_lens) # propagate wavefront proper.prop_lens(wfo, f_lens) # propagate wavefront through a lens proper.prop_propagate(wfo, f_lens) # propagate wavefront (wfo, sampling) = proper.prop_end( wfo, NOABS=True ) # conclude the simulation --> noabs= the wavefront array will be complex return (wfo, sampling) # return the wavefront
def get_intensity(wf_array, sp, logAmp=True, show=False, save=True, phase=False): if show == True: wfo = wf_array[0, 0] after_dm = proper.prop_get_amplitude(wfo) phase_afterdm = proper.prop_get_phase(wfo) fig = plt.figure(figsize=(14, 10)) ax1 = plt.subplot2grid((3, 2), (0, 0), rowspan=2) ax2 = plt.subplot2grid((3, 2), (0, 1), rowspan=2) ax3 = plt.subplot2grid((3, 2), (2, 0)) ax4 = plt.subplot2grid((3, 2), (2, 1)) if logAmp: ax1.imshow(after_dm, origin='lower', cmap="YlGnBu_r", norm=LogNorm()) else: ax1.imshow(after_dm, origin='lower', cmap="YlGnBu_r") ax2.imshow(phase_afterdm, origin='lower', cmap="YlGnBu_r") #, vmin=-0.5, vmax=0.5) ax3.plot(after_dm[int(tp.grid_size / 2)]) ax3.plot(np.sum(np.eye(tp.grid_size) * after_dm, axis=1)) # plt.plot(np.sum(after_dm,axis=1)/after_dm[128,128]) ax4.plot(phase_afterdm[int(tp.grid_size / 2)]) # ax4.plot(np.sum(np.eye(tp.grid_size)*phase_afterdm,axis=1)) plt.xlim([0, proper.prop_get_gridsize(wfo)]) fig.set_tight_layout(True) plt.show() if save: shape = wf_array.shape ws = sp.get_ints['w'] cs = sp.get_ints['c'] int_maps = np.empty((0, tp.grid_size, tp.grid_size)) for iw in ws: for iwf in cs: # int_maps.append(proper.prop_shift_center(np.abs(wf_array[iw, iwf].wfarr) ** 2)) if phase: int_map = proper.prop_get_phase(wf_array[iw, iwf]) # int_map = proper.prop_shift_center(np.abs(wf_array[iw, iwf].wfarr) ** 2) else: int_map = proper.prop_shift_center( np.abs(wf_array[iw, iwf].wfarr)**2) int_maps = np.vstack((int_maps, [int_map])) # quicklook_im(int_map)#, logAmp=True) # int_maps = np.array(int_maps) # view_datacube(int_maps) import pickle, os if os.path.exists(iop.int_maps): # "with" statements are very handy for opening files. with open(iop.int_maps, 'rb') as rfp: # dprint(np.array(pickle.load(rfp)).shape) int_maps = np.vstack((int_maps, pickle.load(rfp))) with open(iop.int_maps, 'wb') as wfp: pickle.dump(int_maps, wfp, protocol=pickle.HIGHEST_PROTOCOL)