def detector(wfo, conf): f_lens = conf['F_LENS'] nd = conf['N_D'] mode = conf['MODE'] prefix = conf['PREFIX'] Debug = conf['DEBUG'] n = proper.prop_get_gridsize(wfo) if (n >= nd): proper.prop_propagate(wfo, f_lens, "to reimaging lens") proper.prop_lens(wfo, f_lens, "apply reimaging lens") proper.prop_propagate(wfo, f_lens, "final focus") (wfo, sampling) = proper.prop_end( wfo, NOABS=False ) # conclude the simulation --> noabs= the wavefront array will be complex else: print('Error: final image is bigger than initial grid size') psf = wfo[int(n / 2 - nd / 2):int(n / 2 + nd / 2), int(n / 2 - nd / 2):int(n / 2 + nd / 2)] out_dir = str('./output_files/') if (Debug == True): fits.writeto(out_dir + prefix + '_' + mode + '_PSF' + '.fits', psf, overwrite=True) return psf
def simple_telescope(wavelength, gridsize): d_objective = 0.060 fl_objective = 15.0 * d_objective fl_eyepiece = 0.021 fl_eye = 0.022 beam_ratio = 0.5 wfo = proper.propbegin(d_objective, wavelength, gridsize, beam_ratio) proper.prop_circular_aperture(wfo, d_objective / 2) proper.prop_define_entrance(wfo) proper.prop_lens(wfo, fl_objective, "objective") proper.prop_propagate(wfo, fl_objective + fl_eyepiece, "eyepiece") proper.prop_lens(wfo, fl_eyepiece, "eyepiece") exit_pupil_distance = fl_eyepiece / (1 - fl_eyepiece / (fl_objective + fl_eyepiece)) proper.prop_propagate(wfo, exit_pupil_distance, "exit pupil at eye lens:") proper.prop_lenx(wfo, fl_eye, "eye") proper.prop_propagate(wfo, fl_eye, "retina") (wfo, sampling) = proper.prop_end(wfo) return (wfo, sampling)
def detector(wf, ngrid=1024, ndet=365, dir_output='output_files', savefits=False, verbose=False, **conf): "Extract PSF on the detector." assert (ngrid >= ndet), 'Error: final image is bigger than initial grid size' # get intensity (A^2) (psf, _) = proper.prop_end(wf, NOABS=False) # crop to detector size start = int(ngrid / 2 - ndet / 2) + 1 end = int(ngrid / 2 + ndet / 2) + 1 psf = psf[start:end, start:end] if verbose is True: print(" extract PSF on the detector: ndet=%s" % ndet) # save psf as fits file if savefits == True: os.makedirs(dir_output, exist_ok=True) filename = os.path.join(dir_output, 'PSF_IMG_%s.fits' % conf['band']) fits.writeto(filename, np.float32(psf), overwrite=True) return psf
def detector(wf, phase_screen=None, amp_screen=None, tiptilt=None, misalign=[0, 0, 0, 0, 0, 0], ngrid=1024, ndet=365, onaxis=False, dir_output='output_files', savefits=False, verbose=False, **conf): assert (ngrid >= ndet), 'Error: final image is bigger than initial grid size' # propagate to detector lens(wf, **conf) # add chromatic leakage if conf['add_det_chrom_leak'] is True and onaxis == True: if verbose == True: print(' Add chromatic leakage in detector plane') wf_cl = pupil(savefits=False, verbose=False, **conf) wf_cl = add_errors(wf_cl, phase_screen=phase_screen, amp_screen=amp_screen, \ tiptilt=tiptilt, misalign=misalign, **conf) wf_cl = lyot_stop(wf_cl, verbose=False, **conf) lens(wf_cl, **conf) proper.prop_multiply(wf_cl, np.sqrt(conf['vc_chrom_leak'])) wf._wfarr += np.transpose(wf_cl._wfarr) # get intensity (A^2) (psf, _) = proper.prop_end(wf, NOABS=False) # crop to detector size start = int(ngrid / 2 - ndet / 2) + 1 end = int(ngrid / 2 + ndet / 2) + 1 psf = psf[start:end, start:end] if verbose is True: print(" extract PSF on the detector: ndet=%s" % ndet) # save psf as fits file if savefits == True: os.makedirs(dir_output, exist_ok=True) filename = os.path.join(dir_output, 'PSF_IMG_%s.fits' % conf['band']) fits.writeto(filename, np.float32(psf), overwrite=True) return psf
def prefocal_image(wavelength, gridsize, PASSVAL): diam = PASSVAL['diam'] focal_length = PASSVAL['focal_length'] beam_ratio = PASSVAL['beam_ratio'] wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) proper.prop_circular_aperture(wfo, diam/2) proper.prop_define_entrance(wfo) proper.prop_zernikes(wfo, [i+1 for i in range(len(PASSVAL['ZERN']))], PASSVAL['ZERN']) #print(proper.prop_get_phase(wfo)[gridsize//2,:]) proper.prop_lens(wfo, focal_length) proper.prop_propagate(wfo, focal_length - PASSVAL['DEFOCUS'], TO_PLANE=False) (wfo, sampling) = proper.prop_end(wfo) return (wfo, sampling)
def detector(wf, focal=660, ngrid=1024, ndet=365, verbose=False, **conf): assert(ngrid >= ndet), 'Error: final image is bigger than initial grid size' # propagate to detector lens(wf, focal) # get intensity (A^2) (psf, _) = proper.prop_end(wf, NOABS = False) # crop to detector size start = int(ngrid/2 - ndet/2) + 1 end = int(ngrid/2 + ndet/2) + 1 psf = psf[start:end, start:end] if verbose is True: print("Extract PSF on the detector\n") return psf
def simple_telescope(wavelength, gridsize): diam = 1.0 focal_ratio = 15.0 focal_length = diam * focal_ratio beam_ratio = 0.5 wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) proper.prop_circular_aperture(wfo, diam / 2) proper.prop_zernikes(wfo, [5], [1e-6]) proper.prop_define_entrance(wfo) proper.prop_lens(wfo, focal_length * 0.98) proper.prop_propagate(wfo, focal_length) (wfo, sampling) = proper.prop_end(wfo) return (wfo, sampling)
def detector(wfo, f_lens, nd, coronagraph_type, prefix, Debug=False): n = proper.prop_get_gridsize(wfo) if (n >= nd): proper.prop_propagate(wfo, f_lens, "to reimaging lens") proper.prop_lens(wfo, f_lens, "apply reimaging lens") proper.prop_propagate(wfo, f_lens, "final focus") (wfo, sampling) = proper.prop_end( wfo, NOABS=False ) # conclude the simulation --> noabs= the wavefront array will be complex else: print('Error: final image is bigger than initial grid size') psf = wfo[int(n / 2 - nd / 2):int(n / 2 + nd / 2), int(n / 2 - nd / 2):int(n / 2 + nd / 2)] out_dir = str('./output_files/') if (Debug == True): fits.writeto(out_dir + prefix + '_' + coronagraph_type + '_PSF' + '.fits', psf, overwrite=True) return psf
def prescription_quad_tiltafter(wavelength, gridsize, PASSVALUE = {'diam': 0.3, 'm1_fl': 0.5717255, 'beam_ratio': 0.2, 'tilt_x': 0.0, 'tilt_y': 0.0 }): diam = PASSVALUE['diam'] # telescope diameter in meters m1_fl = PASSVALUE['m1_fl'] # primary focal length (m) beam_ratio = PASSVALUE['beam_ratio'] # initial beam width/grid width tilt_x = PASSVALUE['tilt_x'] # Tilt angle along x (arc seconds) tilt_y = PASSVALUE['tilt_y'] # Tilt angle along y (arc seconds) # Define the wavefront wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) # Input aperture proper.prop_circular_aperture(wfo, diam/2) # Define entrance proper.prop_define_entrance(wfo) # Primary mirror (treat as quadratic lens) proper.prop_lens(wfo, m1_fl, "primary") # Point off-axis prop_tilt(wfo, tilt_x, tilt_y) # Focus proper.prop_propagate(wfo, m1_fl, "focus", TO_PLANE=True) # End (wfo, sampling) = proper.prop_end(wfo) return (wfo, sampling)
def Hubble_frontend(empty_lamda, grid_size, PASSVALUE): """ propagates instantaneous complex E-field tSubaru from the primary through the AO188 AO system in loop over wavelength range this function is called a 'prescription' by proper uses PyPROPER3 to generate the complex E-field at the source, then propagates it through atmosphere, then telescope, to the focal plane the AO simulator happens here this does not include the observation of the wavefront by the detector :returns spectral cube at instantaneous time, sampling of the wavefront at final location """ # print("Propagating Broadband Wavefront Through Hubble Telescope") # Getting Parameters-import statements weren't working--RD passpara = PASSVALUE['params'] ap.__dict__ = passpara[0].__dict__ tp.__dict__ = passpara[1].__dict__ iop.__dict__ = passpara[2].__dict__ sp.__dict__ = passpara[3].__dict__ datacube = [] # Initialize the Wavefront in Proper wfo = opx.Wavefronts() wfo.initialize_proper() ######################################## # Hubble Propagation ####################################### # Defines aperture (baffle-before primary) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # clear inside, dark outside # Obscurations wfo.loop_collection(opx.add_obscurations, d_primary=tp.entrance_d, d_secondary=tp.d_secondary, legs_frac=0.01) wfo.loop_collection( proper.prop_define_entrance) # normalizes the intensity # Test Sampling if PASSVALUE['iter'] == 1: initial_sampling = proper.prop_get_sampling(wfo.wf_collection[0, 0]) dprint(f"initial sampling is {initial_sampling:.4f}") # Primary # CPA from Effective Primary # aber.add_aber(wfo.wf_collection, tp.entrance_d, step=PASSVALUE['iter'], lens_name='primary') # wfo.loop_collection(opx.prop_pass_lens, tp.flen_primary, tp.flen_primary) wfo.loop_collection(opx.prop_pass_lens, tp.flen_primary, tp.dist_pri_second) # Secondary # aber.add_aber(wfo.wf_collection, tp.d_secondary, step=PASSVALUE['iter'], lens_name='second') # # Zernike Aberrations- Low Order # wfo.loop_collection(aber.add_zern_ab, tp.zernike_orders, tp.zernike_vals) wfo.loop_collection(opx.prop_pass_lens, tp.flen_secondary, tp.dist_second_focus) ######################################## # Focal Plane # ####################################### # Converting Array of Arrays (wfo) into 3D array # wavefront array is now (number_wavelengths x number_astro_bodies x sp.grid_size x sp.grid_size) # prop_end moves center of the wavefront from lower left corner (Fourier space) back to the center # ^ also takes square modulus of complex values, so gives units as intensity not field shape = wfo.wf_collection.shape for iw in range(shape[0]): for io in range(shape[1]): if sp.maskd_size != sp.grid_size: wframes = np.zeros((sp.maskd_size, sp.maskd_size)) (wframe, sampling) = proper.prop_end(wfo.wf_collection[iw, io], EXTRACT=np.int(sp.maskd_size)) else: wframes = np.zeros((sp.grid_size, sp.grid_size)) (wframe, sampling) = proper.prop_end(wfo.wf_collection[ iw, io]) # Sampling returned by proper is in m wframes += wframe # adds 2D wavefront from all astro_bodies together into single wavefront, per wavelength # dprint(f"sampling in focal plane at wavelength={iw} is {sampling} m") datacube.append( wframes) # puts each wavlength's wavefront into an array # (number_wavelengths x sp.grid_size x sp.grid_size) datacube = np.array(datacube) datacube = np.roll(np.roll(datacube, tp.pix_shift[0], 1), tp.pix_shift[1], 2) # cirshift array for off-axis observing datacube = np.abs(datacube) # get intensity from datacube # Interpolating spectral cube from ap.n_wvl_init discreet wavelengths to ap.n_wvl_final if ap.interp_wvl and ap.n_wvl_init > 1 and ap.n_wvl_init < ap.n_wvl_final: wave_samps = np.linspace(0, 1, ap.n_wvl_init) f_out = interp1d(wave_samps, datacube, axis=0) new_heights = np.linspace(0, 1, ap.n_wvl_final) datacube = f_out(new_heights) print('Finished datacube at single timestep') return datacube, sampling
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 run_system(empty_lamda, grid_size, PASSVALUE): #'dm_disp':0 passpara = PASSVALUE['params'] ap.__dict__ = passpara[0].__dict__ tp.__dict__ = passpara[1].__dict__ iop.__dict__ = passpara[2].__dict__ # params.ap = passpara[0] # params.tp = passpara[1] # # ap = params.ap # tp = params.tp # print 'line 23', tp.occulter_type # print 'propagating frame:', PASSVALUE['iter'] wsamples = np.linspace(tp.band[0], tp.band[1], tp.nwsamp) / 1e9 # print wsamples datacube = [] # print proper.prop_get_sampling(wfp), proper.prop_get_nyquistsampling(wfp), proper.prop_get_fratio(wfp) # global phase_map, Imaps # Imaps = np.zeros((4,tp.grid_size,tp.grid_size)) # phase_map = np.zeros((tp.grid_size, tp.grid_size)) # wavefronts = np.empty((len(wsamples),1+len(ap.contrast)), dtype=object) for iw, w in enumerate(wsamples): # Define the wavefront beam_ratio = tp.beam_ratio * tp.band[0] / w * 1e-9 wfp = proper.prop_begin(tp.diam, w, tp.grid_size, beam_ratio) wfs = [wfp] names = ['primary'] if ap.companion: for id in range(len(ap.contrast)): wfc = proper.prop_begin(tp.diam, w, tp.grid_size, beam_ratio) wfs.append(wfc) names.append('companion_%i' % id) # proper.prop_circular_aperture(wfo, tp.diam / 2) # for iw, wf in enumerate([wfo, wfc]): wframes = np.zeros((tp.grid_size, tp.grid_size)) for iwf, wf in zip(names, wfs): # wavefronts[iw,iwf] = wf proper.prop_circular_aperture(wf, tp.diam / 2) # quicklook_wf(wf, show=True) if tp.use_atmos: tdm.add_atmos(wf, tp.f_lens, w, atmos_map=PASSVALUE['atmos_map']) if tp.rot_rate: tdm.rotate_atmos(wf, PASSVALUE['atmos_map']) # quicklook_wf(wf, show=True) # if tp.use_spiders: # tdm.add_spiders(wf, tp.diam) if tp.use_hex: tdm.add_hex(wf) proper.prop_define_entrance(wf) # normalizes the intensity if iwf[:9] == 'companion': tdm.offset_companion(wf, int(iwf[10:]), PASSVALUE['atmos_map']) # quicklook_wf(wf, show=True) if tp.use_apod: tdm.do_apod(wf, tp.grid_size, tp.beam_ratio, tp.apod_gaus) # quicklook_wf(wf, show=True) # obj_map = tdm.wfs_measurement(wfo)#, obj_map, tp.wfs_scale) proper.prop_propagate(wf, tp.f_lens) if tp.aber_params['CPA']: tdm.add_aber(wf, tp.f_lens, tp.aber_params, tp.aber_vals, PASSVALUE['iter'], Loc='CPA') # if tp.CPA_type == 'test': # tdm.add_single_speck(wf, PASSVALUE['iter'] ) # if tp.CPA_type == 'Static': # tdm.add_static(wf, tp.f_lens, loc = 'CPA') # if tp.CPA_type == 'Amp': # tdm.add_static(wf, tp.f_lens, loc = 'CPA', type='Amp') # if tp.CPA_type == 'Quasi': # tdm.add_quasi(wf, tp.f_lens, PASSVALUE['iter']) # rawImageIO.save_wf(wf, iop.datadir+'/beforeAO.pkl') # quicklook_wf(wf) # quicklook_im(obj_map, logAmp=False) proper.prop_propagate(wf, tp.f_lens) if tp.quick_ao: if iwf == 'primary': # and PASSVALUE['iter'] == 0: # quicklook_wf(wf, show=True) r0 = float(PASSVALUE['atmos_map'][-10:-5]) # dprint((r0, 'r0')) CPA_map = tdm.quick_wfs(wf, PASSVALUE['iter'], r0=r0) # , obj_map, tp.wfs_scale) # dprint('quick_ao') # quicklook_wf(wf, show=True) if tp.use_ao: tdm.quick_ao(wf, iwf, tp.f_lens, beam_ratio, PASSVALUE['iter'], CPA_map) # dprint('quick_ao') # quicklook_wf(wf, show=True) else: if tp.use_ao: tdm.adaptive_optics(wf, iwf, iw, tp.f_lens, beam_ratio, PASSVALUE['iter']) if iwf == 'primary': # and PASSVALUE['iter'] == 0: # quicklook_wf(wf, show=True) r0 = float(PASSVALUE['atmos_map'][-10:-5]) # dprint((r0, 'r0')) # if iw == np.ceil(tp.nwsamp/2): tdm.wfs_measurement(wf, PASSVALUE['iter'], iw, r0=r0) #, obj_map, tp.wfs_scale) proper.prop_propagate(wf, tp.f_lens) # rawImageIO.save_wf(wf, iop.datadir+'/loopAO_8act.pkl') # if iwf == 'primary': # quicklook_wf(wf, show=True) # if tp.active_modulate: # tdm.modulate(wf, w, PASSVALUE['iter']) # if iwf == 'primary': # quicklook_wf(wf, show=True) if tp.aber_params['NCPA']: tdm.add_aber(wf, tp.f_lens, tp.aber_params, tp.aber_vals, PASSVALUE['iter'], Loc='NCPA') # if tp.NCPA_type == 'Static': # tdm.add_static(wf, tp.f_lens, loc = 'NCPA') # if tp.NCPA_type == 'Wave': # tdm.add_IFS_ab(wf, tp.f_lens, w) # if tp.NCPA_type == 'Quasi': # tdm.add_quasi(wf, tp.f_lens, PASSVALUE['iter']) # quicklook_wf(wf, show=True) # if iwf == 'primary': # NCPA_phasemap = proper.prop_get_phase(wf) # quicklook_im(NCPA_phasemap, logAmp=False, show=False, colormap="jet", vmin=-3.14, vmax=3.14) # if iwf == 'primary': # global obj_map # r0 = float(PASSVALUE['atmos_map'][-10:-5]) # obj_map = tdm.wfs_measurement(wf, r0 = r0)#, obj_map, tp.wfs_scale) # # quicklook_im(obj_map, logAmp=False) proper.prop_propagate(wf, tp.f_lens) # spiders are introduced here for now since the phase unwrapping seems to ignore them and hence so does the DM # Check out http://scikit-image.org/docs/dev/auto_examples/filters/plot_phase_unwrap.html for masking argument if tp.use_spiders: tdm.add_spiders(wf, tp.diam) tdm.prop_mid_optics(wf, tp.f_lens) # if iwf == 'primary': # if PASSVALUE['iter']>ap.numframes-2 or PASSVALUE['iter']==0: # quicklook_wf(wf, show=True) # print proper.prop_get_sampling(wfp), proper.prop_get_sampling_arcsec(wfp), 'here' if tp.satelite_speck and iwf == 'primary': tdm.add_speckles(wf) # tp.variable = proper.prop_get_phase(wfo)[20,20] # print 'speck phase', tp.variable # import cPickle as pickle # dprint('just saved') # with open(iop.phase_ideal, 'wb') as handle: # pickle.dump(proper.prop_get_phase(wf), handle, protocol=pickle.HIGHEST_PROTOCOL) # exit() if tp.active_null and iwf == 'primary': FPWFS.active_null(wf, PASSVALUE['iter'], w) # if tp.speckle_kill and iwf == 'primary': # tdm.speckle_killer(wf) # tdm.speck_kill(wf) # iwf == 'primary': # parent_bright = aper_phot(proper.prop_get_amplitude(wf),0,8) # if iwf == 'primary' and iop.saveIQ: # save_pix_IQ(wf) # complex_map = proper.prop_shift_center(wf.wfarr) # complex_pix = complex_map[64, 64] # print complex_pix # if np.real(complex_pix) < 0.2: # quicklook_IQ(wf) # # if iwf == 'primary': # # print np.sum(proper.prop_get_amplitude(wf)), 'before', aper_phot(proper.prop_get_amplitude(wf),0,4) # quicklook_wf(wf, show=True, logAmp=True) # if iwf == 'primary': # quicklook_wf(wf, show=True) # if tp.active_modulate and PASSVALUE['iter'] >=8: # coronagraph(wf, tp.f_lens, tp.occulter_type, tp.occult_loc, tp.diam) # if not tp.active_modulate: coronagraph(wf, tp.f_lens, tp.occulter_type, tp.occult_loc, tp.diam) # dprint(proper.prop_get_sampling_arcsec(wf)) # exit() # tp.occult_factor = aper_phot(proper.prop_get_amplitude(wf),0,8)/parent_bright # if PASSVALUE['iter'] % 10 == 0: # with open(iop.logfile, 'a') as the_file: # the_file.write('\n', tp.occult_factor) # quicklook_wf(wf, show=True) if tp.occulter_type != 'None' and iwf == 'primary': #kludge for now until more sophisticated coronapraph has been installed wf.wfarr *= 0.1 # # print np.sum(proper.prop_get_amplitude(wf)), 'after', aper_phot(proper.prop_get_amplitude(wf), 0, 4) # quicklook_wf(wf, show=True) # print proper.prop_get_sampling(wfp), proper.prop_get_sampling_arcsec(wfp), 'here' # if iwf == 'primary': # quicklook_wf(wf, show=True) if tp.use_zern_ab: tdm.add_zern_ab(wf, tp.f_lens) (wframe, sampling) = proper.prop_end(wf) # dprint((np.sum(wframe), 'sum')) # wframe = proper.prop_get_amplitude(wf) # planet = np.roll(np.roll(wframe, 20, 1), 20, 0) * 0.1 # [92,92] # if ap.companion: # from scipy.ndimage.interpolation import shift # companion = shift(wframe, shift= np.array(ap.comp_loc[::-1])- np.array([tp.grid_size/2,tp.grid_size/2])) * ap.contrast # # planet = np.roll(wframe, 15, 0) * 0.1 # [92,92] # # wframe = (wframe + companion) # quicklook_im(wframe, logAmp=True) # '''test conserve=True on prop_magnify!''' # wframe = proper.prop_magnify(wframe, (w*1e9)/tp.band[0]) # wframe = tdm.scale_wframe(wframe, w, iwf) # print np.shape(wframe) quicklook_im(wframe) # quicklook_im(wframe) # mid = int(len(wframe)/2) # wframe = wframe[mid - tp.grid_size/2 : mid +tp.grid_size/2, mid - tp.grid_size/2 : mid +tp.grid_size/2] # if max(mp.array_size) < tp.grid_size: # # Photons seeded outside the array cannot have pixel phase uncertainty applied to them. Instead make both grids match in size # wframe = rawImageIO.resize_image(wframe, newsize=(max(mp.array_size),max(mp.array_size))) # dprint(np.sum(wframe)) # dprint(iwf) # if iwf == 'companion_0': wframes += wframe # if sp.show_wframe: # quicklook_im(wframes, logAmp=True, show=True) datacube.append(wframes) datacube = np.array(datacube) datacube = np.abs(datacube) # #normalize # datacube = np.transpose(np.transpose(datacube) / np.sum(datacube, axis=(1, 2)))/float(tp.nwsamp) # print 'Some pixels have negative values, possibly because of some Gaussian uncertainy you introduced. Taking abs for now.' # view_datacube(datacube) # # End # print type(wfo[0,0]), type(wfo) # # proper.prop_savestate(wfo) # # else: # # wfo = proper.prop_state(wfo) return (datacube, sampling)
def prescription_rc_quad(wavelength, gridsize, PASSVALUE = {}): # Assign parameters from PASSVALUE struct or use defaults diam = PASSVALUE.get('diam',0.3) # telescope diameter in meters m1_fl = PASSVALUE.get('m1_fl',0.5717255) # primary focal length (m) m1_hole_rad = PASSVALUE.get('m1_hole_rad',0.035) # Radius of hole in primary (m) m1_m2_sep = PASSVALUE.get('m1_m2_sep',0.549337630333726) # primary to secondary separation (m) m2_fl = PASSVALUE.get('m2_fl',-0.023378959) # secondary focal length (m) bfl = PASSVALUE.get('bfl',0.528110658881) # nominal distance from secondary to focus (m) beam_ratio = PASSVALUE.get('beam_ratio',0.2) # initial beam width/grid width m2_rad = PASSVALUE.get('m2_rad',0.059) # Secondary half-diameter (m) m2_strut_width = PASSVALUE.get('m2_strut_width',0.01) # Width of struts supporting M2 (m) m2_supports = PASSVALUE.get('m2_supports',5) # Number of support structs (assumed equally spaced) tilt_x = PASSVALUE.get('tilt_x',0.) # Tilt angle along x (arc seconds) tilt_y = PASSVALUE.get('tilt_y',0.) # Tilt angle along y (arc seconds) noabs = PASSVALUE.get('noabs',False) # Output complex amplitude? use_caching = PASSVALUE.get('use_caching',False) # Use cached files if available? get_wf = PASSVALUE.get('get_wf',False) # Return wavefront # Can also specify a opd_func function with signature opd_func(r, phi) if 'phase_func' in PASSVALUE: print('DEPRECATED setting "phase_func": use "opd_func" instead') if 'opd_func' not in PASSVALUE: PASSVALUE['opd_func'] = PASSVALUE['phase_func'] if 'phase_func_sec' in PASSVALUE: print('DEPRECATED setting "phase_func_sec": use "opd_func_sec" instead') if 'opd_func_sec' not in PASSVALUE: PASSVALUE['opd_func_sec'] = PASSVALUE['phase_func_sec'] def build_m2_obs(): # Input aperture grid = build_prop_circular_aperture(wfo, diam/2) # Secondary and structs obscuration grid *= build_prop_circular_obscuration(wfo, m2_rad) # secondary mirror obscuration # Spider struts/vanes, arranged evenly radiating out from secondary strut_length = diam/2 - m2_rad strut_step = 360/m2_supports strut_centre = m2_rad + strut_length/2 for i in range(0, m2_supports): angle = i*strut_step radians = math.radians(angle) xoff = math.cos(radians)*strut_centre yoff = math.sin(radians)*strut_centre grid *= build_prop_rectangular_obscuration(wfo, m2_strut_width, strut_length, xoff, yoff, ROTATION = angle + 90) return grid # Define the wavefront wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) # Point off-axis prop_tilt(wfo, tilt_x, tilt_y) wfo.wfarr *= load_cacheable_grid('m2_obs', wfo, build_m2_obs, use_caching) # Normalize wavefront proper.prop_define_entrance(wfo) #if get_wf: # wf = proper.prop_get_wavefront(wfo) # print('Got wavefront') proper.prop_propagate(wfo, m1_m2_sep, "primary") # Primary mirror if 'opd_func' in PASSVALUE: opd1_func = PASSVALUE['opd_func'] def build_m1_opd(): return gen_opdmap(opd1_func, proper.prop_get_gridsize(wfo), proper.prop_get_sampling(wfo)) wfo.wfarr *= build_phase_map(wfo, load_cacheable_grid(opd1_func.__name__, wfo, build_m1_opd, use_caching)) if get_wf: wf = proper.prop_get_wavefront(wfo) print('Got wavefront') if 'm1_conic' in PASSVALUE: prop_conic(wfo, m1_fl, PASSVALUE['m1_conic'], "conic primary") else: proper.prop_lens(wfo, m1_fl, "primary") wfo.wfarr *= build_prop_circular_obscuration(wfo, m1_hole_rad) # Secondary mirror proper.prop_propagate(wfo, m1_m2_sep, "secondary") if 'opd_func_sec' in PASSVALUE: opd2_func = PASSVALUE['opd_func_sec'] def build_m2_opd(): return gen_opdmap(opd2_func, proper.prop_get_gridsize(wfo), proper.prop_get_sampling(wfo)) wfo.wfarr *= build_phase_map(wfo, load_cacheable_grid(opd2_func.__name__, wfo, build_m2_opd, use_caching)) if 'm1_conic' in PASSVALUE: prop_conic(wfo, m2_fl, PASSVALUE['m2_conic'], "conic secondary") else: proper.prop_lens(wfo, m2_fl, "secondary") def build_m2_ap(): return build_prop_circular_aperture(wfo, m2_rad) wfo.wfarr *= load_cacheable_grid('m2_ap', wfo, build_m2_ap) # proper.prop_state(wfo) # Hole through primary if m1_m2_sep<bfl: proper.prop_propagate(wfo, m1_m2_sep, "M1 hole") def build_m1_hole(): return build_prop_circular_aperture(wfo, m1_hole_rad) wfo.wfarr *= load_cacheable_grid('m1_hole', wfo, build_m1_hole) # Focus - bfl can be varied between runs if m1_m2_sep<bfl: proper.prop_propagate(wfo, bfl-m1_m2_sep, "focus", TO_PLANE=True) else: proper.prop_propagate(wfo, bfl, "focus", TO_PLANE=True) # # End # return proper.prop_end(wfo, NOABS = noabs) # End (wfo, sampling) = proper.prop_end(wfo) if get_wf: return (wfo, wf, sampling) else: return (wfo, sampling)
def wfirst_phaseb(lambda_m, output_dim0, PASSVALUE={'dummy': 0}): # "output_dim" is used to specify the output dimension in pixels at the final image plane. # Computational grid sizes are hardcoded for each coronagraph. # Based on Zemax prescription "WFIRST_CGI_DI_LOWFS_Sep24_2018.zmx" by Hong Tang. data_dir = wfirst_phaseb_proper.data_dir if 'PASSVALUE' in locals(): if 'data_dir' in PASSVALUE: data_dir = PASSVALUE['data_dir'] map_dir = data_dir + wfirst_phaseb_proper.map_dir polfile = data_dir + wfirst_phaseb_proper.polfile cor_type = 'hlc' # coronagraph type ('hlc', 'spc', 'none') source_x_offset_mas = 0 # source offset in mas (tilt applied at primary) source_y_offset_mas = 0 source_x_offset = 0 # source offset in lambda0_m/D radians (tilt applied at primary) source_y_offset = 0 polaxis = 0 # polarization axis aberrations: # -2 = -45d in, Y out # -1 = -45d in, X out # 1 = +45d in, X out # 2 = +45d in, Y out # 5 = mean of modes -1 & +1 (X channel polarizer) # 6 = mean of modes -2 & +2 (Y channel polarizer) # 10 = mean of all modes (no polarization filtering) use_errors = 1 # use optical surface phase errors? 1 or 0 zindex = np.array([0, 0]) # array of Zernike polynomial indices zval_m = np.array([0, 0]) # array of Zernike coefficients (meters RMS WFE) use_aperture = 0 # use apertures on all optics? 1 or 0 cgi_x_shift_pupdiam = 0 # X,Y shear of wavefront at FSM (bulk displacement of CGI); normalized relative to pupil diameter cgi_y_shift_pupdiam = 0 cgi_x_shift_m = 0 # X,Y shear of wavefront at FSM (bulk displacement of CGI) in meters cgi_y_shift_m = 0 fsm_x_offset_mas = 0 # offset in focal plane caused by tilt of FSM in mas fsm_y_offset_mas = 0 fsm_x_offset = 0 # offset in focal plane caused by tilt of FSM in lambda0/D fsm_y_offset = 0 end_at_fsm = 0 # end propagation after propagating to FSM (no FSM errors) focm_z_shift_m = 0 # offset (meters) of focus correction mirror (+ increases path length) use_hlc_dm_patterns = 0 # use Dwight's HLC default DM wavefront patterns? 1 or 0 use_dm1 = 0 # use DM1? 1 or 0 use_dm2 = 0 # use DM2? 1 or 0 dm_sampling_m = 0.9906e-3 # actuator spacing in meters dm1_xc_act = 23.5 # for 48x48 DM, wavefront centered at actuator intersections: (0,0) = 1st actuator center dm1_yc_act = 23.5 dm1_xtilt_deg = 0 # tilt around X axis (deg) dm1_ytilt_deg = 5.7 # effective DM tilt in deg including 9.65 deg actual tilt and pupil ellipticity dm1_ztilt_deg = 0 # rotation of DM about optical axis (deg) dm2_xc_act = 23.5 # for 48x48 DM, wavefront centered at actuator intersections: (0,0) = 1st actuator center dm2_yc_act = 23.5 dm2_xtilt_deg = 0 # tilt around X axis (deg) dm2_ytilt_deg = 5.7 # effective DM tilt in deg including 9.65 deg actual tilt and pupil ellipticity dm2_ztilt_deg = 0 # rotation of DM about optical axis (deg) use_pupil_mask = 1 # SPC only: use SPC pupil mask (0 or 1) mask_x_shift_pupdiam = 0 # X,Y shear of shaped pupil mask; normalized relative to pupil diameter mask_y_shift_pupdiam = 0 mask_x_shift_m = 0 # X,Y shear of shaped pupil mask in meters mask_y_shift_m = 0 use_fpm = 1 # use occulter? 1 or 0 fpm_x_offset = 0 # FPM x,y offset in lambda0/D fpm_y_offset = 0 fpm_x_offset_m = 0 # FPM x,y offset in meters fpm_y_offset_m = 0 fpm_z_shift_m = 0 # occulter offset in meters along optical axis (+ = away from prior optics) pinhole_diam_m = 0 # FPM pinhole diameter in meters end_at_fpm_exit_pupil = 0 # return field at FPM exit pupil? output_field_rootname = '' # rootname of FPM exit pupil field file (must set end_at_fpm_exit_pupil=1) use_lyot_stop = 1 # use Lyot stop? 1 or 0 lyot_x_shift_pupdiam = 0 # X,Y shear of Lyot stop mask; normalized relative to pupil diameter lyot_y_shift_pupdiam = 0 lyot_x_shift_m = 0 # X,Y shear of Lyot stop mask in meters lyot_y_shift_m = 0 use_field_stop = 1 # use field stop (HLC)? 1 or 0 field_stop_radius_lam0 = 0 # field stop radius in lambda0/D (HLC or SPC-wide mask only) field_stop_x_offset = 0 # field stop offset in lambda0/D field_stop_y_offset = 0 field_stop_x_offset_m = 0 # field stop offset in meters field_stop_y_offset_m = 0 use_pupil_lens = 0 # use pupil imaging lens? 0 or 1 use_defocus_lens = 0 # use defocusing lens? Options are 1, 2, 3, 4, corresponding to +18.0, +9.0, -4.0, -8.0 waves P-V @ 550 nm defocus = 0 # instead of specific lens, defocus in waves P-V @ 550 nm (-8.7 to 42.0 waves) final_sampling_m = 0 # final sampling in meters (overrides final_sampling_lam0) final_sampling_lam0 = 0 # final sampling in lambda0/D output_dim = output_dim0 # dimension of output in pixels (overrides output_dim0) if 'PASSVALUE' in locals(): if 'use_fpm' in PASSVALUE: use_fpm = PASSVALUE['use_fpm'] if 'cor_type' in PASSVALUE: cor_type = PASSVALUE['cor_type'] is_spc = False is_hlc = False if cor_type == 'hlc': is_hlc = True file_directory = data_dir + '/hlc_20190210/' # must have trailing "/" prefix = file_directory + 'run461_' pupil_diam_pix = 309.0 pupil_file = prefix + 'pupil_rotated.fits' lyot_stop_file = prefix + 'lyot.fits' lambda0_m = 0.575e-6 lam_occ = [ 5.4625e-07, 5.49444444444e-07, 5.52638888889e-07, 5.534375e-07, 5.55833333333e-07, 5.59027777778e-07, 5.60625e-07, 5.62222222222e-07, 5.65416666667e-07, 5.678125e-07, 5.68611111111e-07, 5.71805555556e-07, 5.75e-07, 5.78194444444e-07, 5.81388888889e-07, 5.821875e-07, 5.84583333333e-07, 5.87777777778e-07, 5.89375e-07, 5.90972222222e-07, 5.94166666667e-07, 5.965625e-07, 5.97361111111e-07, 6.00555555556e-07, 6.0375e-07 ] lam_occs = [ '5.4625e-07', '5.49444444444e-07', '5.52638888889e-07', '5.534375e-07', '5.55833333333e-07', '5.59027777778e-07', '5.60625e-07', '5.62222222222e-07', '5.65416666667e-07', '5.678125e-07', '5.68611111111e-07', '5.71805555556e-07', '5.75e-07', '5.78194444444e-07', '5.81388888889e-07', '5.821875e-07', '5.84583333333e-07', '5.87777777778e-07', '5.89375e-07', '5.90972222222e-07', '5.94166666667e-07', '5.965625e-07', '5.97361111111e-07', '6.00555555556e-07', '6.0375e-07' ] lam_occs = [ prefix + 'occ_lam' + s + 'theta6.69polp_' for s in lam_occs ] # find nearest matching FPM wavelength wlam = (np.abs(lambda_m - np.array(lam_occ))).argmin() occulter_file_r = lam_occs[wlam] + 'real.fits' occulter_file_i = lam_occs[wlam] + 'imag.fits' n_default = 1024 # gridsize in non-critical areas if use_fpm == 1: n_to_fpm = 2048 else: n_to_fpm = 1024 n_from_lyotstop = 1024 field_stop_radius_lam0 = 9.0 elif cor_type == 'hlc_erkin': is_hlc = True file_directory = data_dir + '/hlc_20190206_v3/' # must have trailing "/" prefix = file_directory + 'dsn17d_run2_pup310_fpm2048_' pupil_diam_pix = 310.0 pupil_file = prefix + 'pupil.fits' lyot_stop_file = prefix + 'lyot.fits' lambda0_m = 0.575e-6 lam_occ = [ 5.4625e-07, 5.4944e-07, 5.5264e-07, 5.5583e-07, 5.5903e-07, 5.6222e-07, 5.6542e-07, 5.6861e-07, 5.7181e-07, 5.75e-07, 5.7819e-07, 5.8139e-07, 5.8458e-07, 5.8778e-07, 5.9097e-07, 5.9417e-07, 5.9736e-07, 6.0056e-07, 6.0375e-07 ] lam_occs = [ '5.4625e-07', '5.4944e-07', '5.5264e-07', '5.5583e-07', '5.5903e-07', '5.6222e-07', '5.6542e-07', '5.6861e-07', '5.7181e-07', '5.75e-07', '5.7819e-07', '5.8139e-07', '5.8458e-07', '5.8778e-07', '5.9097e-07', '5.9417e-07', '5.9736e-07', '6.0056e-07', '6.0375e-07' ] lam_occs = [ prefix + 'occ_lam' + s + 'theta6.69pols_' for s in lam_occs ] # find nearest matching FPM wavelength wlam = (np.abs(lambda_m - np.array(lam_occ))).argmin() occulter_file_r = lam_occs[wlam] + 'real_rotated.fits' occulter_file_i = lam_occs[wlam] + 'imag_rotated.fits' n_default = 1024 # gridsize in non-critical areas if use_fpm == 1: n_to_fpm = 2048 else: n_to_fpm = 1024 n_from_lyotstop = 1024 field_stop_radius_lam0 = 9.0 elif cor_type == 'spc-ifs_short' or cor_type == 'spc-ifs_long' or cor_type == 'spc-spec_short' or cor_type == 'spc-spec_long': is_spc = True file_dir = data_dir + '/spc_20190130/' # must have trailing "/" pupil_diam_pix = 1000.0 pupil_file = file_dir + 'pupil_SPC-20190130_rotated.fits' pupil_mask_file = file_dir + 'SPM_SPC-20190130.fits' fpm_file = file_dir + 'fpm_0.05lamdivD.fits' fpm_sampling = 0.05 # sampling in fpm_sampling_lambda_m/D of FPM mask if cor_type == 'spc-ifs_short' or cor_type == 'spc-spec_short': fpm_sampling_lambda_m = 0.66e-6 lambda0_m = 0.66e-6 else: fpm_sampling_lambda_m = 0.73e-6 lambda0_m = 0.73e-6 # FPM scaled for this central wavelength lyot_stop_file = file_dir + 'LS_SPC-20190130.fits' n_default = 2048 # gridsize in non-critical areas n_to_fpm = 2048 # gridsize to/from FPM n_mft = 1400 # gridsize to FPM (propagation to/from FPM handled by MFT) n_from_lyotstop = 4096 elif cor_type == 'spc-wide': is_spc = True file_dir = data_dir + '/spc_20181220/' # must have trailing "/" pupil_diam_pix = 1000.0 pupil_file = file_dir + 'pupil_SPC-20181220_1k_rotated.fits' pupil_mask_file = file_dir + 'SPM_SPC-20181220_1000_rounded9_gray.fits' fpm_file = file_dir + 'fpm_0.05lamdivD.fits' fpm_sampling = 0.05 # sampling in lambda0/D of FPM mask fpm_sampling_lambda_m = 0.825e-6 lambda0_m = 0.825e-6 # FPM scaled for this central wavelength lyot_stop_file = file_dir + 'LS_SPC-20181220_1k.fits' n_default = 2048 # gridsize in non-critical areas n_to_fpm = 2048 # gridsize to/from FPM n_mft = 1400 n_from_lyotstop = 4096 elif cor_type == 'none': file_directory = data_dir + '/hlc_20190210/' # must have trailing "/" prefix = file_directory + 'run461_' pupil_diam_pix = 309.0 pupil_file = prefix + 'pupil_rotated.fits' lambda0_m = 0.575e-6 use_fpm = 0 use_lyot_stop = 0 use_field_stop = 0 n_default = 1024 n_to_fpm = 1024 n_from_lyotstop = 1024 else: raise Exception('ERROR: Unsupported cor_type: ' + cor_type) if 'PASSVALUE' in locals(): if 'lam0' in PASSVALUE: lamba0_m = PASSVALUE['lam0'] * 1.0e-6 if 'lambda0_m' in PASSVALUE: lambda0_m = PASSVALUE['lambda0_m'] mas_per_lamD = lambda0_m * 360.0 * 3600.0 / ( 2 * np.pi * 2.363) * 1000 # mas per lambda0/D if 'source_x_offset' in PASSVALUE: source_x_offset = PASSVALUE['source_x_offset'] if 'source_y_offset' in PASSVALUE: source_y_offset = PASSVALUE['source_y_offset'] if 'source_x_offset_mas' in PASSVALUE: source_x_offset = PASSVALUE['source_x_offset_mas'] / mas_per_lamD if 'source_y_offset_mas' in PASSVALUE: source_y_offset = PASSVALUE['source_y_offset_mas'] / mas_per_lamD if 'use_errors' in PASSVALUE: use_errors = PASSVALUE['use_errors'] if 'polaxis' in PASSVALUE: polaxis = PASSVALUE['polaxis'] if 'zindex' in PASSVALUE: zindex = np.array(PASSVALUE['zindex']) if 'zval_m' in PASSVALUE: zval_m = np.array(PASSVALUE['zval_m']) if 'end_at_fsm' in PASSVALUE: end_at_fsm = PASSVALUE['end_at_fsm'] if 'cgi_x_shift_pupdiam' in PASSVALUE: cgi_x_shift_pupdiam = PASSVALUE['cgi_x_shift_pupdiam'] if 'cgi_y_shift_pupdiam' in PASSVALUE: cgi_y_shift_pupdiam = PASSVALUE['cgi_y_shift_pupdiam'] if 'cgi_x_shift_m' in PASSVALUE: cgi_x_shift_m = PASSVALUE['cgi_x_shift_m'] if 'cgi_y_shift_m' in PASSVALUE: cgi_y_shift_m = PASSVALUE['cgi_y_shift_m'] if 'fsm_x_offset' in PASSVALUE: fsm_x_offset = PASSVALUE['fsm_x_offset'] if 'fsm_y_offset' in PASSVALUE: fsm_y_offset = PASSVALUE['fsm_y_offset'] if 'fsm_x_offset_mas' in PASSVALUE: fsm_x_offset = PASSVALUE['fsm_x_offset_mas'] / mas_per_lamD if 'fsm_y_offset_mas' in PASSVALUE: fsm_y_offset = PASSVALUE['fsm_y_offset_mas'] / mas_per_lamD if 'focm_z_shift_m' in PASSVALUE: focm_z_shift_m = PASSVALUE['focm_z_shift_m'] if 'use_hlc_dm_patterns' in PASSVALUE: use_hlc_dm_patterns = PASSVALUE['use_hlc_dm_patterns'] if 'use_dm1' in PASSVALUE: use_dm1 = PASSVALUE['use_dm1'] if 'dm1_m' in PASSVALUE: dm1_m = PASSVALUE['dm1_m'] if 'dm1_xc_act' in PASSVALUE: dm1_xc_act = PASSVALUE['dm1_xc_act'] if 'dm1_yc_act' in PASSVALUE: dm1_yc_act = PASSVALUE['dm1_yc_act'] if 'dm1_xtilt_deg' in PASSVALUE: dm1_xtilt_deg = PASSVALUE['dm1_xtilt_deg'] if 'dm1_ytilt_deg' in PASSVALUE: dm1_ytilt_deg = PASSVALUE['dm1_ytilt_deg'] if 'dm1_ztilt_deg' in PASSVALUE: dm1_ztilt_deg = PASSVALUE['dm1_ztilt_deg'] if 'use_dm2' in PASSVALUE: use_dm2 = PASSVALUE['use_dm2'] if 'dm2_m' in PASSVALUE: dm2_m = PASSVALUE['dm2_m'] if 'dm2_xc_act' in PASSVALUE: dm2_xc_act = PASSVALUE['dm2_xc_act'] if 'dm2_yc_act' in PASSVALUE: dm2_yc_act = PASSVALUE['dm2_yc_act'] if 'dm2_xtilt_deg' in PASSVALUE: dm2_xtilt_deg = PASSVALUE['dm2_xtilt_deg'] if 'dm2_ytilt_deg' in PASSVALUE: dm2_ytilt_deg = PASSVALUE['dm2_ytilt_deg'] if 'dm2_ztilt_deg' in PASSVALUE: dm2_ztilt_deg = PASSVALUE['dm2_ztilt_deg'] if 'use_pupil_mask' in PASSVALUE: use_pupil_mask = PASSVALUE['use_pupil_mask'] if 'mask_x_shift_pupdiam' in PASSVALUE: mask_x_shift_pupdiam = PASSVALUE['mask_x_shift_pupdiam'] if 'mask_y_shift_pupdiam' in PASSVALUE: mask_y_shift_pupdiam = PASSVALUE['mask_y_shift_pupdiam'] if 'mask_x_shift_m' in PASSVALUE: mask_x_shift_m = PASSVALUE['mask_x_shift_m'] if 'mask_y_shift_m' in PASSVALUE: mask_y_shift_m = PASSVALUE['mask_y_shift_m'] if 'fpm_x_offset' in PASSVALUE: fpm_x_offset = PASSVALUE['fpm_x_offset'] if 'fpm_y_offset' in PASSVALUE: fpm_y_offset = PASSVALUE['fpm_y_offset'] if 'fpm_x_offset_m' in PASSVALUE: fpm_x_offset_m = PASSVALUE['fpm_x_offset_m'] if 'fpm_y_offset_m' in PASSVALUE: fpm_y_offset_m = PASSVALUE['fpm_y_offset_m'] if 'fpm_z_shift_m' in PASSVALUE: fpm_z_shift_m = PASSVALUE['fpm_z_shift_m'] if 'pinhole_diam_m' in PASSVALUE: pinhole_diam_m = PASSVALUE['pinhole_diam_m'] if 'end_at_fpm_exit_pupil' in PASSVALUE: end_at_fpm_exit_pupil = PASSVALUE['end_at_fpm_exit_pupil'] if 'output_field_rootname' in PASSVALUE: output_field_rootname = PASSVALUE['output_field_rootname'] if 'use_lyot_stop' in PASSVALUE: use_lyot_stop = PASSVALUE['use_lyot_stop'] if 'lyot_x_shift_pupdiam' in PASSVALUE: lyot_x_shift_pupdiam = PASSVALUE['lyot_x_shift_pupdiam'] if 'lyot_y_shift_pupdiam' in PASSVALUE: lyot_y_shift_pupdiam = PASSVALUE['lyot_y_shift_pupdiam'] if 'lyot_x_shift_m' in PASSVALUE: lyot_x_shift_m = PASSVALUE['lyot_x_shift_m'] if 'lyot_y_shift_m' in PASSVALUE: lyot_y_shift_m = PASSVALUE['lyot_y_shift_m'] if 'use_field_stop' in PASSVALUE: use_field_stop = PASSVALUE['use_field_stop'] if 'field_stop_x_offset' in PASSVALUE: field_stop_x_offset = PASSVALUE['field_stop_x_offset'] if 'field_stop_y_offset' in PASSVALUE: field_stop_y_offset = PASSVALUE['field_stop_y_offset'] if 'field_stop_x_offset_m' in PASSVALUE: field_stop_x_offset_m = PASSVALUE['field_stop_x_offset_m'] if 'field_stop_y_offset_m' in PASSVALUE: field_stop_y_offset_m = PASSVALUE['field_stop_y_offset_m'] if 'use_pupil_lens' in PASSVALUE: use_pupil_lens = PASSVALUE['use_pupil_lens'] if 'use_defocus_lens' in PASSVALUE: use_defocus_lens = PASSVALUE['use_defocus_lens'] if 'defocus' in PASSVALUE: defocus = PASSVALUE['defocus'] if 'output_dim' in PASSVALUE: output_dim = PASSVALUE['output_dim'] if 'final_sampling_m' in PASSVALUE: final_sampling_m = PASSVALUE['final_sampling_m'] if 'final_sampling_lam0' in PASSVALUE: final_sampling_lam0 = PASSVALUE['final_sampling_lam0'] diam = 2.3633372 fl_pri = 2.83459423440 * 1.0013 d_pri_sec = 2.285150515460035 d_focus_sec = d_pri_sec - fl_pri fl_sec = -0.653933011 * 1.0004095 d_sec_focus = 3.580188916677103 diam_sec = 0.58166 d_sec_fold1 = 2.993753476654728 d_fold1_focus = 0.586435440022375 diam_fold1 = 0.09 d_fold1_m3 = 1.680935841598811 fl_m3 = 0.430216463069001 d_focus_m3 = 1.094500401576436 d_m3_pupil = 0.469156807701977 d_m3_focus = 0.708841602661368 diam_m3 = 0.2 d_m3_m4 = 0.943514749358944 fl_m4 = 0.116239114833590 d_focus_m4 = 0.234673014520402 d_m4_pupil = 0.474357941656967 d_m4_focus = 0.230324117970585 diam_m4 = 0.07 d_m4_m5 = 0.429145636743193 d_m5_focus = 0.198821518772608 fl_m5 = 0.198821518772608 d_m5_pupil = 0.716529242882632 diam_m5 = 0.07 d_m5_fold2 = 0.351125431220770 diam_fold2 = 0.06 d_fold2_fsm = 0.365403811661862 d_fsm_oap1 = 0.354826767220001 fl_oap1 = 0.503331895563883 diam_oap1 = 0.06 d_oap1_focm = 0.768005607094041 d_focm_oap2 = 0.314483210543378 fl_oap2 = 0.579156922073536 diam_oap2 = 0.06 d_oap2_dm1 = 0.775775726154228 d_dm1_dm2 = 1.0 d_dm2_oap3 = 0.394833855161549 fl_oap3 = 1.217276467668519 diam_oap3 = 0.06 d_oap3_fold3 = 0.505329955078121 diam_fold3 = 0.06 d_fold3_oap4 = 1.158897671642761 fl_oap4 = 0.446951159052363 diam_oap4 = 0.06 d_oap4_pupilmask = 0.423013568764728 d_pupilmask_oap5 = 0.408810648253099 fl_oap5 = 0.548189351937178 diam_oap5 = 0.06 d_oap5_fpm = 0.548189083164429 d_fpm_oap6 = 0.548189083164429 fl_oap6 = 0.548189083164429 diam_oap6 = 0.06 d_oap6_lyotstop = 0.687567667550736 d_lyotstop_oap7 = 0.401748843470518 fl_oap7 = 0.708251083480054 diam_oap7 = 0.06 d_oap7_fieldstop = 0.708251083480054 d_fieldstop_oap8 = 0.210985967281651 fl_oap8 = 0.210985967281651 diam_oap8 = 0.06 d_oap8_pupil = 0.238185804200797 d_oap8_filter = 0.368452268225530 diam_filter = 0.01 d_filter_lens = 0.170799548215162 fl_lens = 0.246017378417573 + 0.050001306014153 diam_lens = 0.01 d_lens_fold4 = 0.246017378417573 diam_fold4 = 0.02 d_fold4_image = 0.050001578514650 fl_pupillens = 0.149260576823040 n = n_default # start off with less padding wavefront = proper.prop_begin(diam, lambda_m, n, float(pupil_diam_pix) / n) pupil = proper.prop_fits_read(pupil_file) proper.prop_multiply(wavefront, trim(pupil, n)) pupil = 0 if polaxis != 0: polmap(wavefront, polfile, pupil_diam_pix, polaxis) proper.prop_define_entrance(wavefront) proper.prop_lens(wavefront, fl_pri) if source_x_offset != 0 or source_y_offset != 0: # compute tilted wavefront to offset source by xoffset,yoffset lambda0_m/D xtilt_lam = -source_x_offset * lambda0_m / lambda_m ytilt_lam = -source_y_offset * lambda0_m / lambda_m x = np.tile((np.arange(n) - n // 2) / (pupil_diam_pix / 2.0), (n, 1)) y = np.transpose(x) proper.prop_multiply( wavefront, np.exp(complex(0, 1) * np.pi * (xtilt_lam * x + ytilt_lam * y))) x = 0 y = 0 if zindex[0] != 0: proper.prop_zernikes(wavefront, zindex, zval_m) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_PRIMARY_phase_error_V1.0.fits', WAVEFRONT=True) proper.prop_errormap( wavefront, map_dir + 'wfirst_phaseb_GROUND_TO_ORBIT_4.2X_phase_error_V1.0.fits', WAVEFRONT=True) proper.prop_propagate(wavefront, d_pri_sec, 'secondary') proper.prop_lens(wavefront, fl_sec) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_SECONDARY_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_sec / 2.0) proper.prop_propagate(wavefront, d_sec_fold1, 'FOLD_1') if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_FOLD1_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_fold1 / 2.0) proper.prop_propagate(wavefront, d_fold1_m3, 'M3') proper.prop_lens(wavefront, fl_m3) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_M3_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_m3 / 2.0) proper.prop_propagate(wavefront, d_m3_m4, 'M4') proper.prop_lens(wavefront, fl_m4) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_M4_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_m4 / 2.0) proper.prop_propagate(wavefront, d_m4_m5, 'M5') proper.prop_lens(wavefront, fl_m5) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_M5_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_m5 / 2.0) proper.prop_propagate(wavefront, d_m5_fold2, 'FOLD_2') if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_FOLD2_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_fold2 / 2.0) proper.prop_propagate(wavefront, d_fold2_fsm, 'FSM') if end_at_fsm == 1: (wavefront, sampling_m) = proper.prop_end(wavefront, NOABS=True) wavefront = trim(wavefront, n) return wavefront, sampling_m if cgi_x_shift_pupdiam != 0 or cgi_y_shift_pupdiam != 0 or cgi_x_shift_m != 0 or cgi_y_shift_m != 0: # bulk coronagraph pupil shear # FFT the field, apply a tilt, FFT back if cgi_x_shift_pupdiam != 0 or cgi_y_shift_pupdiam != 0: # offsets are normalized to pupil diameter xt = -cgi_x_shift_pupdiam * pupil_diam_pix * float( pupil_diam_pix) / n yt = -cgi_y_shift_pupdiam * pupil_diam_pix * float( pupil_diam_pix) / n else: # offsets are meters d_m = proper.prop_get_sampling(wavefront) xt = -cgi_x_shift_m / d_m * float(pupil_diam_pix) / n yt = -cgi_y_shift_m / d_m * float(pupil_diam_pix) / n x = np.tile((np.arange(n) - n // 2) / (pupil_diam_pix / 2.0), (n, 1)) y = np.transpose(x) tilt = complex(0, 1) * np.pi * (x * xt + y * yt) x = 0 y = 0 wavefront0 = proper.prop_get_wavefront(wavefront) wavefront0 = ffts(wavefront0, -1) wavefront0 *= np.exp(tilt) wavefront0 = ffts(wavefront0, 1) tilt = 0 wavefront.wfarr[:, :] = proper.prop_shift_center(wavefront0) wavefront0 = 0 if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_FSM_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_fsm / 2.0) if (fsm_x_offset != 0.0 or fsm_y_offset != 0.0): # compute tilted wavefront to offset source by fsm_x_offset,fsm_y_offset lambda0_m/D xtilt_lam = fsm_x_offset * lambda0_m / lambda_m ytilt_lam = fsm_y_offset * lambda0_m / lambda_m x = np.tile((np.arange(n) - n // 2) / (pupil_diam_pix / 2.0), (n, 1)) y = np.transpose(x) proper.prop_multiply( wavefront, np.exp(complex(0, 1) * np.pi * (xtilt_lam * x + ytilt_lam * y))) x = 0 y = 0 proper.prop_propagate(wavefront, d_fsm_oap1, 'OAP1') proper.prop_lens(wavefront, fl_oap1) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP1_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap1 / 2.0) proper.prop_propagate(wavefront, d_oap1_focm + focm_z_shift_m, 'FOCM') if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_FOCM_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_focm / 2.0) proper.prop_propagate(wavefront, d_focm_oap2 + focm_z_shift_m, 'OAP2') proper.prop_lens(wavefront, fl_oap2) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP2_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap2 / 2.0) proper.prop_propagate(wavefront, d_oap2_dm1, 'DM1') if use_dm1 != 0: proper.prop_dm(wavefront, dm1_m, dm1_xc_act, dm1_yc_act, dm_sampling_m, XTILT=dm1_xtilt_deg, YTILT=dm1_ytilt_deg, ZTILT=dm1_ztilt_deg) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_DM1_phase_error_V1.0.fits', WAVEFRONT=True) if is_hlc == True and use_hlc_dm_patterns == 1: dm1wfe = proper.prop_fits_read(prefix + 'dm1wfe.fits') proper.prop_add_phase(wavefront, trim(dm1wfe, n)) dm1wfe = 0 proper.prop_propagate(wavefront, d_dm1_dm2, 'DM2') if use_dm2 == 1: proper.prop_dm(wavefront, dm2_m, dm2_xc_act, dm2_yc_act, dm_sampling_m, XTILT=dm2_xtilt_deg, YTILT=dm2_ytilt_deg, ZTILT=dm2_ztilt_deg) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_DM2_phase_error_V1.0.fits', WAVEFRONT=True) if is_hlc == True: if use_hlc_dm_patterns == 1: dm2wfe = proper.prop_fits_read(prefix + 'dm2wfe.fits') proper.prop_add_phase(wavefront, trim(dm2wfe, n)) dm2wfe = 0 dm2mask = proper.prop_fits_read(prefix + 'dm2mask.fits') proper.prop_multiply(wavefront, trim(dm2mask, n)) dm2mask = 0 proper.prop_propagate(wavefront, d_dm2_oap3, 'OAP3') proper.prop_lens(wavefront, fl_oap3) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP3_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap3 / 2.0) proper.prop_propagate(wavefront, d_oap3_fold3, 'FOLD_3') if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_FOLD3_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_fold3 / 2.0) proper.prop_propagate(wavefront, d_fold3_oap4, 'OAP4') proper.prop_lens(wavefront, fl_oap4) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP4_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap4 / 2.0) proper.prop_propagate(wavefront, d_oap4_pupilmask, 'PUPIL_MASK') # flat/reflective shaped pupil if is_spc == True and use_pupil_mask != 0: pupil_mask = proper.prop_fits_read(pupil_mask_file) pupil_mask = trim(pupil_mask, n) if mask_x_shift_pupdiam != 0 or mask_y_shift_pupdiam != 0 or mask_x_shift_m != 0 or mask_y_shift_m != 0: # shift SP mask by FFTing it, applying tilt, and FFTing back if mask_x_shift_pupdiam != 0 or mask_y_shift_pupdiam != 0: # offsets are normalized to pupil diameter xt = -mask_x_shift_pupdiam * pupil_diam_pix * float( pupil_diam_pix) / n yt = -mask_y_shift_pupdiam * pupil_diam_pix * float( pupil_diam_pix) / n else: d_m = proper.prop_get_sampling(wavefront) xt = -mask_x_shift_m / d_m * float(pupil_diam_pix) / n yt = -mask_y_shift_m / d_m * float(pupil_diam_pix) / n x = np.tile((np.arange(n) - n // 2) / (pupil_diam_pix / 2.0), (n, 1)) y = np.transpose(x) tilt = complex(0, 1) * np.pi * (x * xt + y * yt) x = 0 y = 0 pupil_mask = ffts(pupil_mask, -1) pupil_mask *= np.exp(tilt) pupil_mask = ffts(pupil_mask, 1) pupil_mask = pupil_mask.real tilt = 0 proper.prop_multiply(wavefront, pupil_mask) pupil_mask = 0 if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_PUPILMASK_phase_error_V1.0.fits', WAVEFRONT=True) # while at a pupil, use more padding to provide 2x better sampling at FPM diam = 2 * proper.prop_get_beamradius(wavefront) (wavefront, dx) = proper.prop_end(wavefront, NOABS=True) n = n_to_fpm wavefront0 = trim(wavefront, n) wavefront = proper.prop_begin(diam, lambda_m, n, float(pupil_diam_pix) / n) wavefront.wfarr[:, :] = proper.prop_shift_center(wavefront0) wavefront0 = 0 proper.prop_propagate(wavefront, d_pupilmask_oap5, 'OAP5') proper.prop_lens(wavefront, fl_oap5) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP5_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap5 / 2.0) proper.prop_propagate(wavefront, d_oap5_fpm + fpm_z_shift_m, 'FPM', TO_PLANE=True) if use_fpm == 1: if fpm_x_offset != 0 or fpm_y_offset != 0 or fpm_x_offset_m != 0 or fpm_y_offset_m != 0: # To shift FPM, FFT field to pupil, apply tilt, FFT back to focus, # apply FPM, FFT to pupil, take out tilt, FFT back to focus if fpm_x_offset != 0 or fpm_y_offset != 0: # shifts are specified in lambda0/D x_offset_lamD = fpm_x_offset * lambda0_m / lambda_m y_offset_lamD = fpm_y_offset * lambda0_m / lambda_m else: d_m = proper.prop_get_sampling(wavefront) x_offset_lamD = fpm_x_offset_m / d_m * float( pupil_diam_pix) / n y_offset_lamD = fpm_y_offset_m / d_m * float( pupil_diam_pix) / n x = np.tile((np.arange(n) - n // 2) / (pupil_diam_pix / 2.0), (n, 1)) y = np.transpose(x) tilt = complex(0, 1) * np.pi * (x * x_offset_lamD + y * y_offset_lamD) x = 0 y = 0 wavefront0 = proper.prop_get_wavefront(wavefront) wavefront0 = ffts(wavefront0, -1) wavefront0 *= np.exp(tilt) wavefront0 = ffts(wavefront0, 1) wavefront.wfarr[:, :] = proper.prop_shift_center(wavefront0) wavefront0 = 0 if is_hlc == True: occ_r = proper.prop_fits_read(occulter_file_r) occ_i = proper.prop_fits_read(occulter_file_i) occ = np.array(occ_r + 1j * occ_i, dtype=np.complex128) proper.prop_multiply(wavefront, trim(occ, n)) occ_r = 0 occ_i = 0 occ = 0 elif is_spc == True: # super-sample FPM wavefront0 = proper.prop_get_wavefront(wavefront) wavefront0 = ffts(wavefront0, 1) # to virtual pupil wavefront0 = trim(wavefront0, n_mft) fpm = proper.prop_fits_read(fpm_file) nfpm = fpm.shape[1] fpm_sampling_lam = fpm_sampling * fpm_sampling_lambda_m / lambda_m wavefront0 = mft2(wavefront0, fpm_sampling_lam, pupil_diam_pix, nfpm, -1) # MFT to highly-sampled focal plane wavefront0 *= fpm fpm = 0 wavefront0 = mft2(wavefront0, fpm_sampling_lam, pupil_diam_pix, n, +1) # MFT to virtual pupil wavefront0 = ffts(wavefront0, -1) # back to normally-sampled focal plane wavefront.wfarr[:, :] = proper.prop_shift_center(wavefront0) wavefront0 = 0 if fpm_x_offset != 0 or fpm_y_offset != 0 or fpm_x_offset_m != 0 or fpm_y_offset_m != 0: wavefront0 = proper.prop_get_wavefront(wavefront) wavefront0 = ffts(wavefront0, -1) wavefront0 *= np.exp(-tilt) wavefront0 = ffts(wavefront0, 1) wavefront.wfarr[:, :] = proper.prop_shift_center(wavefront0) wavefront0 = 0 tilt = 0 if pinhole_diam_m != 0: # "pinhole_diam_m" is pinhole diameter in meters dx_m = proper.prop_get_sampling(wavefront) dx_pinhole_diam_m = pinhole_diam_m / 101.0 # 101 samples across pinhole n_out = 105 m_per_lamD = dx_m * n / float( pupil_diam_pix) # current focal plane sampling in lambda_m/D dx_pinhole_lamD = dx_pinhole_diam_m / m_per_lamD # pinhole sampling in lambda_m/D n_in = int(round(pupil_diam_pix * 1.2)) wavefront0 = proper.prop_get_wavefront(wavefront) wavefront0 = ffts(wavefront0, +1) # to virtual pupil wavefront0 = trim(wavefront0, n_in) m = dx_pinhole_lamD * n_in * float(n_out) / pupil_diam_pix wavefront0 = mft2(wavefront0, dx_pinhole_lamD, pupil_diam_pix, n_out, -1) # MFT to highly-sampled focal plane p = (radius(n_out) * dx_pinhole_diam_m) <= (pinhole_diam_m / 2.0) p = p.astype(np.int) wavefront0 *= p p = 0 wavefront0 = mft2(wavefront0, dx_pinhole_lamD, pupil_diam_pix, n, +1) # MFT back to virtual pupil wavefront0 = ffts(wavefront0, -1) # back to normally-sampled focal plane wavefront.wfarr[:, :] = proper.prop_shift_center(wavefront0) wavefront0 = 0 proper.prop_propagate(wavefront, d_fpm_oap6 - fpm_z_shift_m, 'OAP6') proper.prop_lens(wavefront, fl_oap6) if use_errors != 0 and end_at_fpm_exit_pupil == 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP6_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap6 / 2.0) proper.prop_propagate(wavefront, d_oap6_lyotstop, 'LYOT_STOP') # while at a pupil, switch back to less padding diam = 2 * proper.prop_get_beamradius(wavefront) (wavefront, dx) = proper.prop_end(wavefront, NOABS=True) n = n_from_lyotstop wavefront = trim(wavefront, n) if output_field_rootname != '': lams = format(lambda_m * 1e6, "6.4f") pols = format(int(round(polaxis))) hdu = pyfits.PrimaryHDU() hdu.data = np.real(wavefront) hdu.writeto(output_field_rootname + '_' + lams + 'um_' + pols + '_real.fits', overwrite=True) hdu = pyfits.PrimaryHDU() hdu.data = np.imag(wavefront) hdu.writeto(output_field_rootname + '_' + lams + 'um_' + pols + '_imag.fits', overwrite=True) if end_at_fpm_exit_pupil == 1: return wavefront, dx wavefront0 = wavefront.copy() wavefront = 0 wavefront = proper.prop_begin(diam, lambda_m, n, float(pupil_diam_pix) / n) wavefront.wfarr[:, :] = proper.prop_shift_center(wavefront0) wavefront0 = 0 if use_lyot_stop != 0: lyot = proper.prop_fits_read(lyot_stop_file) lyot = trim(lyot, n) if lyot_x_shift_pupdiam != 0 or lyot_y_shift_pupdiam != 0 or lyot_x_shift_m != 0 or lyot_y_shift_m != 0: # apply shift to lyot stop by FFTing the stop, applying a tilt, and FFTing back if lyot_x_shift_pupdiam != 0 or lyot_y_shift_pupdiam != 0: # offsets are normalized to pupil diameter xt = -lyot_x_shift_pupdiam * pupil_diam_pix * float( pupil_diam_pix) / n yt = -lyot_y_shift_pupdiam * pupil_diam_pix * float( pupil_diam_pix) / n else: d_m = proper.prop_get_sampling(wavefront) xt = -lyot_x_shift_m / d_m * float(pupil_diam_pix) / n yt = -lyot_y_shift_m / d_m * float(pupil_diam_pix) / n x = np.tile((np.arange(n) - n // 2) / (pupil_diam_pix / 2.0), (n, 1)) y = np.transpose(x) tilt = complex(0, 1) * np.pi * (x * xt + y * yt) x = 0 y = 0 lyot = ffts(lyot, -1) lyot *= np.exp(tilt) lyot = ffts(lyot, 1) lyot = lyot.real tilt = 0 proper.prop_multiply(wavefront, lyot) lyot = 0 if use_pupil_lens != 0 or pinhole_diam_m != 0: proper.prop_circular_aperture(wavefront, 1.1, NORM=True) proper.prop_propagate(wavefront, d_lyotstop_oap7, 'OAP7') proper.prop_lens(wavefront, fl_oap7) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP7_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap7 / 2.0) proper.prop_propagate(wavefront, d_oap7_fieldstop, 'FIELD_STOP') if use_field_stop != 0 and (cor_type == 'hlc' or cor_type == 'hlc_erkin'): sampling_lamD = float( pupil_diam_pix) / n # sampling at focus in lambda_m/D stop_radius = field_stop_radius_lam0 / sampling_lamD * ( lambda0_m / lambda_m) * proper.prop_get_sampling(wavefront) if field_stop_x_offset != 0 or field_stop_y_offset != 0: # convert offsets in lambda0/D to meters x_offset_lamD = field_stop_x_offset * lambda0_m / lambda_m y_offset_lamD = field_stop_y_offset * lambda0_m / lambda_m pupil_ratio = float(pupil_diam_pix) / n field_stop_x_offset_m = x_offset_lamD / pupil_ratio * proper.prop_get_sampling( wavefront) field_stop_y_offset_m = y_offset_lamD / pupil_ratio * proper.prop_get_sampling( wavefront) proper.prop_circular_aperture(wavefront, stop_radius, -field_stop_x_offset_m, -field_stop_y_offset_m) proper.prop_propagate(wavefront, d_fieldstop_oap8, 'OAP8') proper.prop_lens(wavefront, fl_oap8) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_OAP8_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_oap8 / 2.0) proper.prop_propagate(wavefront, d_oap8_filter, 'filter') if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_FILTER_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_filter / 2.0) proper.prop_propagate(wavefront, d_filter_lens, 'LENS') if use_pupil_lens == 0 and use_defocus_lens == 0 and defocus == 0: # use imaging lens to create normal focus proper.prop_lens(wavefront, fl_lens) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_LENS_phase_error_V1.0.fits', WAVEFRONT=True) elif use_pupil_lens != 0: # use pupil imaging lens proper.prop_lens(wavefront, fl_pupillens) if use_errors != 0: proper.prop_errormap( wavefront, map_dir + 'wfirst_phaseb_PUPILLENS_phase_error_V1.0.fits', WAVEFRONT=True) else: # table is waves P-V @ 575 nm z4_pv_waves = np.array([ -9.0545, -8.5543, -8.3550, -8.0300, -7.54500, -7.03350, -6.03300, -5.03300, -4.02000, -2.51980, 0.00000000, 3.028000, 4.95000, 6.353600, 8.030000, 10.10500, 12.06000, 14.06000, 20.26000, 28.34000, 40.77500, 56.65700 ]) fl_defocus_lens = np.array([ 5.09118, 1.89323, 1.54206, 1.21198, 0.914799, 0.743569, 0.567599, 0.470213, 0.406973, 0.350755, 0.29601868, 0.260092, 0.24516, 0.236606, 0.228181, 0.219748, 0.213278, 0.207816, 0.195536, 0.185600, 0.176629, 0.169984 ]) # subtract ad-hoc function to make z4 vs f_length more accurately spline interpolatible f = fl_defocus_lens / 0.005 f0 = 59.203738 z4t = z4_pv_waves - (0.005 * (f0 - f - 40)) / f**2 / 0.575e-6 if use_defocus_lens != 0: # use one of 4 defocusing lenses defocus = np.array([18.0, 9.0, -4.0, -8.0]) # waves P-V @ 575 nm f = interp1d(z4_pv_waves, z4t, kind='cubic') z4x = f(defocus) f = interp1d(z4t, fl_defocus_lens, kind='cubic') lens_fl = f(z4x) proper.prop_lens(wavefront, lens_fl[use_defocus_lens - 1]) if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_DEFOCUSLENS' + str(use_defocus_lens) + '_phase_error_V1.0.fits', WAVEFRONT=True) defocus = defocus[use_defocus_lens - 1] else: # specify amount of defocus (P-V waves @ 575 nm) f = interp1d(z4_pv_waves, z4t, kind='cubic') z4x = f(defocus) f = interp1d(z4t, fl_defocus_lens, kind='cubic') lens_fl = f(z4x) proper.prop_lens(wavefront, lens_fl) if use_errors != 0: proper.prop_errormap( wavefront, map_dir + 'wfirst_phaseb_DEFOCUSLENS1_phase_error_V1.0.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_lens / 2.0) proper.prop_propagate(wavefront, d_lens_fold4, 'FOLD_4') if use_errors != 0: proper.prop_errormap(wavefront, map_dir + 'wfirst_phaseb_FOLD4_phase_error_V1.1.fits', WAVEFRONT=True) if use_aperture != 0: proper.prop_circular_aperture(wavefront, diam_fold4 / 2.0) if defocus != 0 or use_defocus_lens != 0: if np.abs(defocus) <= 4: proper.prop_propagate(wavefront, d_fold4_image, 'IMAGE', TO_PLANE=True) else: proper.prop_propagate(wavefront, d_fold4_image, 'IMAGE') else: proper.prop_propagate(wavefront, d_fold4_image, 'IMAGE') (wavefront, sampling_m) = proper.prop_end(wavefront, NOABS=True) if final_sampling_lam0 != 0 or final_sampling_m != 0: if final_sampling_m != 0: mag = sampling_m / final_sampling_m sampling_m = final_sampling_m else: mag = (float(pupil_diam_pix) / n) / final_sampling_lam0 * (lambda_m / lambda0_m) sampling_m = sampling_m / mag wavefront = proper.prop_magnify(wavefront, mag, output_dim, AMP_CONSERVE=True) else: wavefront = trim(wavefront, output_dim) return wavefront, sampling_m
def prescription_quad(wavelength, gridsize, PASSVALUE={}): # Assign parameters from PASSVALUE struct or use defaults diam = PASSVALUE.get('diam', 0.3) # telescope diameter in meters m1_fl = PASSVALUE.get('m1_fl', 0.5717255) # primary focal length (m) beam_ratio = PASSVALUE.get('beam_ratio', 0.2) # initial beam width/grid width tilt_x = PASSVALUE.get('tilt_x', 0.) # Tilt angle along x (arc seconds) tilt_y = PASSVALUE.get('tilt_y', 0.) # Tilt angle along y (arc seconds) noabs = PASSVALUE.get('noabs', False) # Output complex amplitude? m1_hole_rad = PASSVALUE.get('m1_hole_rad', None) # Inner hole diameter use_caching = PASSVALUE.get('use_caching', False) # Use cached files if available? get_wf = PASSVALUE.get('get_wf', False) # Return wavefront """ Prescription for a single quad lens system """ if 'phase_func' in PASSVALUE: print('DEPRECATED setting "phase_func": use "opd_func" instead') if 'opd_func' not in PASSVALUE: PASSVALUE['opd_func'] = PASSVALUE['phase_func'] elif 'opd_func' not in PASSVALUE: print("no phase function") if 'phase_func_sec' in PASSVALUE: print( 'DEPRECATED setting "phase_func_sec": use "opd_func_sec" instead') if 'opd_func_sec' not in PASSVALUE: PASSVALUE['opd_func_sec'] = PASSVALUE['phase_func_sec'] # Define the wavefront wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) # Point off-axis prop_tilt(wfo, tilt_x, tilt_y) ### # Change to build ciruclar aperture?? # Input aperture proper.prop_circular_aperture(wfo, diam / 2.) ### # Define entrance proper.prop_define_entrance(wfo) proper.prop_lens(wfo, m1_fl, "primary") if 'opd_func' in PASSVALUE: opd1_func = PASSVALUE['opd_func'] def build_m1_opd(): return gen_opdmap(opd1_func, proper.prop_get_gridsize(wfo), proper.prop_get_sampling(wfo)) wfo.wfarr *= build_phase_map( wfo, load_cacheable_grid(opd1_func.__name__, wfo, build_m1_opd, use_caching)) if get_wf: wf = proper.prop_get_wavefront(wfo) print('Got wavefront') if m1_hole_rad is not None: proper.prop_circular_obscuration(wfo, m1_hole_rad) #if get_wf: # wf = proper.prop_get_wavefront(wfo) # print('Got wavefront') # Focus proper.prop_propagate(wfo, m1_fl, "focus", TO_PLANE=True) # End (wfo, sampling) = proper.prop_end(wfo) if get_wf: return (wfo, wf, sampling) else: return (wfo, sampling)
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 wfirst_phaseb_compact(lambda_m, output_dim0, PASSVALUE={'dummy': 0}): # "output_dim" is used to specify the output dimension in pixels at the final image plane. # Computational grid sizes are hardcoded for each coronagraph. # Based on Zemax prescription "WFIRST_CGI_DI_LOWFS_Sep24_2018.zmx" by Hong Tang. data_dir = wfirst_phaseb_proper.data_dir if 'PASSVALUE' in locals(): if 'data_dir' in PASSVALUE: data_dir = PASSVALUE['data_dir'] cor_type = 'hlc' # coronagraph type ('hlc', 'spc', 'none') input_field_rootname = '' # rootname of files containing aberrated pupil polaxis = 0 # polarization condition (only used with input_field_rootname) source_x_offset = 0 # source offset in lambda0_m/D radians (tilt applied at primary) source_y_offset = 0 use_hlc_dm_patterns = 0 # use Dwight's HLC default DM wavefront patterns? 1 or 0 use_dm1 = 0 # use DM1? 1 or 0 use_dm2 = 0 # use DM2? 1 or 0 dm_sampling_m = 0.9906e-3 # actuator spacing in meters dm1_xc_act = 23.5 # for 48x48 DM, wavefront centered at actuator intersections: (0,0) = 1st actuator center dm1_yc_act = 23.5 dm1_xtilt_deg = 0 # tilt around X axis (deg) dm1_ytilt_deg = 5.7 # effective DM tilt in deg including 9.65 deg actual tilt and pupil ellipticity dm1_ztilt_deg = 0 # rotation of DM about optical axis (deg) dm2_xc_act = 23.5 # for 48x48 DM, wavefront centered at actuator intersections: (0,0) = 1st actuator center dm2_yc_act = 23.5 dm2_xtilt_deg = 0 # tilt around X axis (deg) dm2_ytilt_deg = 5.7 # effective DM tilt in deg including 9.65 deg actual tilt and pupil ellipticity dm2_ztilt_deg = 0 # rotation of DM about optical axis (deg) fpm_axis = 'p' # HLC FPM axis: '', 's', 'p' final_sampling_lam0 = 0 # final sampling in lambda0/D output_dim = output_dim0 # dimension of output in pixels (overrides output_dim0) if 'PASSVALUE' in locals(): if 'cor_type' in PASSVALUE: cor_type = PASSVALUE['cor_type'] if 'fpm_axis' in PASSVALUE: fpm_axis = PASSVALUE['fpm_axis'] is_hlc = False is_spc = False if cor_type == 'hlc': is_hlc = True file_directory = data_dir + '/hlc_20190210/' # must have trailing "/" prefix = file_directory + 'run461_' pupil_diam_pix = 309.0 pupil_file = prefix + 'pupil_rotated.fits' lyot_stop_file = prefix + 'lyot.fits' lambda0_m = 0.575e-6 lam_occ = [ 5.4625e-07, 5.49444444444e-07, 5.52638888889e-07, 5.534375e-07, 5.55833333333e-07, 5.59027777778e-07, 5.60625e-07, 5.62222222222e-07, 5.65416666667e-07, 5.678125e-07, 5.68611111111e-07, 5.71805555556e-07, 5.75e-07, 5.78194444444e-07, 5.81388888889e-07, 5.821875e-07, 5.84583333333e-07, 5.87777777778e-07, 5.89375e-07, 5.90972222222e-07, 5.94166666667e-07, 5.965625e-07, 5.97361111111e-07, 6.00555555556e-07, 6.0375e-07 ] lam_occs = [ '5.4625e-07', '5.49444444444e-07', '5.52638888889e-07', '5.534375e-07', '5.55833333333e-07', '5.59027777778e-07', '5.60625e-07', '5.62222222222e-07', '5.65416666667e-07', '5.678125e-07', '5.68611111111e-07', '5.71805555556e-07', '5.75e-07', '5.78194444444e-07', '5.81388888889e-07', '5.821875e-07', '5.84583333333e-07', '5.87777777778e-07', '5.89375e-07', '5.90972222222e-07', '5.94166666667e-07', '5.965625e-07', '5.97361111111e-07', '6.00555555556e-07', '6.0375e-07' ] lam_occs = [ prefix + 'occ_lam' + s + 'theta6.69pol' + fpm_axis + '_' for s in lam_occs ] # find nearest matching FPM wavelength wlam = (np.abs(lambda_m - np.array(lam_occ))).argmin() occulter_file_r = lam_occs[wlam] + 'real_rotated.fits' occulter_file_i = lam_occs[wlam] + 'imag_rotated.fits' n_small = 1024 # gridsize in non-critical areas n_big = 2048 # gridsize to/from FPM elif cor_type == 'hlc_erkin': is_hlc = True file_directory = data_dir + '/hlc_20190206_v3/' # must have trailing "/" prefix = file_directory + 'dsn17d_run2_pup310_fpm2048_' pupil_diam_pix = 310.0 pupil_file = prefix + 'pupil.fits' lyot_stop_file = prefix + 'lyot.fits' lambda0_m = 0.575e-6 lam_occ = [ 5.4625e-07, 5.4944e-07, 5.5264e-07, 5.5583e-07, 5.5903e-07, 5.6222e-07, 5.6542e-07, 5.6861e-07, 5.7181e-07, 5.75e-07, 5.7819e-07, 5.8139e-07, 5.8458e-07, 5.8778e-07, 5.9097e-07, 5.9417e-07, 5.9736e-07, 6.0056e-07, 6.0375e-07 ] lam_occs = [ '5.4625e-07', '5.4944e-07', '5.5264e-07', '5.5583e-07', '5.5903e-07', '5.6222e-07', '5.6542e-07', '5.6861e-07', '5.7181e-07', '5.75e-07', '5.7819e-07', '5.8139e-07', '5.8458e-07', '5.8778e-07', '5.9097e-07', '5.9417e-07', '5.9736e-07', '6.0056e-07', '6.0375e-07' ] fpm_axis = 's' lam_occs = [ prefix + 'occ_lam' + s + 'theta6.69pol' + fpm_axis + '_' for s in lam_occs ] # find nearest matching FPM wavelength wlam = (np.abs(lambda_m - np.array(lam_occ))).argmin() occulter_file_r = lam_occs[wlam] + 'real.fits' occulter_file_i = lam_occs[wlam] + 'imag.fits' n_small = 1024 # gridsize in non-critical areas n_big = 2048 # gridsize to/from FPM elif cor_type == 'spc-ifs_short' or cor_type == 'spc-ifs_long' or cor_type == 'spc-spec_short' or cor_type == 'spc-spec_long': is_spc = True file_dir = data_dir + '/spc_20190130/' # must have trailing "/" pupil_diam_pix = 1000.0 pupil_file = file_dir + 'pupil_SPC-20190130_rotated.fits' pupil_mask_file = file_dir + 'SPM_SPC-20190130_rotated.fits' fpm_file = file_dir + 'fpm_0.05lamdivD.fits' fpm_sampling = 0.05 # sampling in lambda0/D of FPM mask if cor_type == 'spc-ifs_short' or cor_type == 'spc-spec_short': fpm_sampling_lambda_m = 0.66e-6 lambda0_m = 0.66e-6 else: fpm_sampling_lambda_m = 0.73e-6 lambda0_m = 0.73e-6 # FPM scaled for this central wavelength lyot_stop_file = file_dir + 'lyotstop_0.5mag.fits' n_small = 2048 # gridsize in non-critical areas n_big = 1400 # gridsize to FPM (propagation to/from FPM handled by MFT) elif cor_type == 'spc-wide': is_spc = True file_dir = data_dir + '/spc_20181220/' # must have trailing "/" pupil_diam_pix = 1000.0 pupil_file = file_dir + 'pupil_SPC-20181220_1k_rotated.fits' pupil_mask_file = file_dir + 'SPM_SPC-20181220_1000_rounded9_gray_rotated.fits' fpm_file = file_dir + 'fpm_0.05lamdivD.fits' fpm_sampling = 0.05 # sampling in lambda0/D of FPM mask lyot_stop_file = file_dir + 'LS_half_symm_CGI180718_Str3.20pct_38D91_N500_pixel.fits' fpm_sampling_lambda_m = 0.825e-6 lambda0_m = 0.825e-6 # FPM scaled for this central wavelength n_small = 2048 # gridsize in non-critical areas n_big = 1400 # gridsize to FPM (propagation to/from FPM handled by MFT) elif cor_type == 'none': file_directory = data_dir + '/hlc_20190210/' # must have trailing "/" prefix = file_directory + 'run461_' pupil_diam_pix = 309.0 pupil_file = prefix + 'pupil_rotated.fits' use_fpm = 0 use_lyot_stop = 0 n_small = 1024 n_big = 1024 else: raise Exception('wfirst_phaseb_compact: Unsuported cor_type: ' + cor_type) if 'PASSVALUE' in locals(): if 'lam0' in PASSVALUE: lamba0_m = PASSVALUE['lam0'] * 1.0e-6 if 'lambda0_m' in PASSVALUE: lambda0_m = PASSVALUE['lambda0_m'] if 'input_field_rootname' in PASSVALUE: input_field_rootname = PASSVALUE['input_field_rootname'] if 'polaxis' in PASSVALUE: polaxis = PASSVALUE['polaxis'] if 'source_x_offset' in PASSVALUE: source_x_offset = PASSVALUE['source_x_offset'] if 'source_y_offset' in PASSVALUE: source_y_offset = PASSVALUE['source_y_offset'] if 'use_hlc_dm_patterns' in PASSVALUE: use_hlc_dm_patterns = PASSVALUE['use_hlc_dm_patterns'] if 'use_dm1' in PASSVALUE: use_dm1 = PASSVALUE['use_dm1'] if 'dm1_m' in PASSVALUE: dm1_m = PASSVALUE['dm1_m'] if 'dm1_xc_act' in PASSVALUE: dm1_xc_act = PASSVALUE['dm1_xc_act'] if 'dm1_yc_act' in PASSVALUE: dm1_yc_act = PASSVALUE['dm1_yc_act'] if 'dm1_xtilt_deg' in PASSVALUE: dm1_xtilt_deg = PASSVALUE['dm1_xtilt_deg'] if 'dm1_ytilt_deg' in PASSVALUE: dm1_ytilt_deg = PASSVALUE['dm1_ytilt_deg'] if 'dm1_ztilt_deg' in PASSVALUE: dm1_ztilt_deg = PASSVALUE['dm1_ztilt_deg'] if 'use_dm2' in PASSVALUE: use_dm2 = PASSVALUE['use_dm2'] if 'dm2_m' in PASSVALUE: dm2_m = PASSVALUE['dm2_m'] if 'dm2_xc_act' in PASSVALUE: dm2_xc_act = PASSVALUE['dm2_xc_act'] if 'dm2_yc_act' in PASSVALUE: dm2_yc_act = PASSVALUE['dm2_yc_act'] if 'dm2_xtilt_deg' in PASSVALUE: dm2_xtilt_deg = PASSVALUE['dm2_xtilt_deg'] if 'dm2_ytilt_deg' in PASSVALUE: dm2_ytilt_deg = PASSVALUE['dm2_ytilt_deg'] if 'dm2_ztilt_deg' in PASSVALUE: dm2_ztilt_deg = PASSVALUE['dm2_ztilt_deg'] if 'final_sampling_lam0' in PASSVALUE: final_sampling_lam0 = PASSVALUE['final_sampling_lam0'] if 'output_dim' in PASSVALUE: output_dim = PASSVALUE['output_dim'] if polaxis != 0 and input_field_rootname == '': raise Exception( 'wfirst_phaseb_compact: polaxis can only be defined when input_field_rootname is given' ) diam_at_dm1 = 0.0463 d_dm1_dm2 = 1.0 n = n_small # start off with less padding wavefront = proper.prop_begin(diam_at_dm1, lambda_m, n, float(pupil_diam_pix) / n) if input_field_rootname == '': pupil = proper.prop_fits_read(pupil_file) proper.prop_multiply(wavefront, trim(pupil, n)) pupil = 0 else: lams = format(lambda_m * 1e6, "6.4f") pols = format(int(round(polaxis))) rval = proper.prop_fits_read(input_field_rootname + '_' + lams + 'um_' + pols + '_real.fits') ival = proper.prop_fits_read(input_field_rootname + '_' + lams + 'um_' + pols + '_imag.fits') proper.prop_multiply(wavefront, trim(rval + 1j * ival, n)) rval = 0 ival = 0 proper.prop_define_entrance(wavefront) if source_x_offset != 0 or source_y_offset != 0: # compute tilted wavefront to offset source by xoffset,yoffset lambda0_m/D xtilt_lam = -source_x_offset * lambda0_m / lambda_m ytilt_lam = -source_y_offset * lambda0_m / lambda_m x = np.tile((np.arange(n) - n // 2) / (pupil_diam_pix / 2.0), (n, 1)) y = np.transpose(x) proper.prop_multiply( wavefront, np.exp(complex(0, 1) * np.pi * (xtilt_lam * x + ytilt_lam * y))) x = 0 y = 0 if use_dm1 != 0: prop_dm(wavefront, dm1_m, dm1_xc_act, dm1_yc_act, dm_sampling_m, XTILT=dm1_xtilt_deg, YTILT=dm1_ytilt_deg, ZTILT=dm1_ztilt_deg) if is_hlc == True and use_hlc_dm_patterns == 1: dm1wfe = proper.prop_fits_read(prefix + 'dm1wfe.fits') proper.prop_add_phase(wavefront, trim(dm1wfe, n)) dm1wfe = 0 proper.prop_propagate(wavefront, d_dm1_dm2, 'DM2') if use_dm2 == 1: prop_dm(wavefront, dm2_m, dm2_xc_act, dm2_yc_act, dm_sampling_m, XTILT=dm2_xtilt_deg, YTILT=dm2_ytilt_deg, ZTILT=dm2_ztilt_deg) if is_hlc == True: if use_hlc_dm_patterns == 1: dm2wfe = proper.prop_fits_read(prefix + 'dm2wfe.fits') proper.prop_add_phase(wavefront, trim(dm2wfe, n)) dm2wfe = 0 dm2mask = proper.prop_fits_read(prefix + 'dm2mask.fits') proper.prop_multiply(wavefront, trim(dm2mask, n)) dm2mask = 0 proper.prop_propagate(wavefront, -d_dm1_dm2, 'back to DM1') (wavefront, sampling_m) = proper.prop_end(wavefront, NOABS=True) # apply shape pupil mask if is_spc == True: pupil_mask = proper.prop_fits_read(pupil_mask_file) wavefront *= trim(pupil_mask, n) pupil_mask = 0 # propagate to FPM and apply FPM if is_hlc == True: n = n_big wavefront = trim(wavefront, n) wavefront = ffts(wavefront, -1) # to focus occ_r = proper.prop_fits_read(occulter_file_r) occ_i = proper.prop_fits_read(occulter_file_i) occ = np.array(occ_r + 1j * occ_i, dtype=np.complex128) wavefront *= trim(occ, n) occ_r = 0 occ_i = 0 occ = 0 wavefront = ffts(wavefront, +1) # to lyot stop elif is_spc == True: n = n_big wavefront = trim(wavefront, n) fpm = proper.prop_fits_read(fpm_file) nfpm = fpm.shape[1] fpm_sampling_lam = fpm_sampling * fpm_sampling_lambda_m / lambda_m wavefront = mft2(wavefront, fpm_sampling_lam, pupil_diam_pix, nfpm, -1) # MFT to highly-sampled focal plane wavefront *= fpm fpm = 0 pupil_diam_pix = pupil_diam_pix / 2.0 # Shrink pupil by 1/2 wavefront = mft2(wavefront, fpm_sampling_lam, pupil_diam_pix, int(pupil_diam_pix), +1) # MFT to Lyot stop with 1/2 magnification n = n_small wavefront = trim(wavefront, n) lyot = proper.prop_fits_read(lyot_stop_file) wavefront *= trim(lyot, n) lyot = 0 wavefront *= n wavefront = ffts(wavefront, -1) # to focus # rotate to convention used by full prescription wavefront[:, :] = np.rot90(wavefront, 2) wavefront[:, :] = np.roll(wavefront, 1, axis=0) wavefront[:, :] = np.roll(wavefront, 1, axis=1) if final_sampling_lam0 != 0: mag = (float(pupil_diam_pix) / n) / final_sampling_lam0 * (lambda_m / lambda0_m) wavefront = proper.prop_magnify(wavefront, mag, output_dim, AMP_CONSERVE=True) else: wavefront = trim(wavefront, output_dim) sampling_m = 0.0 return wavefront, sampling_m
def toliman_prescription_simple(wavelength, gridsize): # Values from Eduardo's RC Toliman system diam = 0.3 # telescope diameter in meters fl_pri = 0.5 * 1.143451 # primary focal length (m) # BN 20180208 d_pri_sec = 0.549337630333726 # primary to secondary separation (m) # d_pri_sec = 0.559337630333726 # primary to secondary separation (m) fl_sec = -0.5 * 0.0467579189727913 # secondary focal length (m) d_sec_to_focus = 0.528110658881 # nominal distance from secondary to focus (from eqn) # d_sec_to_focus = 0.589999999989853 # nominal distance from secondary to focus beam_ratio = 0.2 # initial beam width/grid width m2_rad = 0.059 # Secondary half-diameter (m) m2_strut_width = 0.01 # Width of struts supporting M2 (m) m2_supports = 5 # Define the wavefront wfo = proper.prop_begin(diam, wavelength, gridsize, beam_ratio) # Input aperture proper.prop_circular_aperture(wfo, diam / 2) # NOTE: could prop_propagate() here if some baffling included # Secondary and structs obscuration proper.prop_circular_obscuration(wfo, m2_rad) # secondary mirror obscuration # Spider struts/vanes, arranged evenly radiating out from secondary strut_length = diam / 2 - m2_rad strut_step = 360 / m2_supports strut_centre = m2_rad + strut_length / 2 for i in range(0, m2_supports): angle = i * strut_step radians = math.radians(angle) xoff = math.cos(radians) * strut_centre yoff = math.sin(radians) * strut_centre proper.prop_rectangular_obscuration(wfo, m2_strut_width, strut_length, xoff, yoff, ROTATION=angle + 90) # Define entrance proper.prop_define_entrance(wfo) # Primary mirror (treat as quadratic lens) proper.prop_lens(wfo, fl_pri, "primary") # Propagate the wavefront proper.prop_propagate(wfo, d_pri_sec, "secondary") # Secondary mirror (another quadratic lens) proper.prop_lens(wfo, fl_sec, "secondary") # NOTE: hole through primary? # Focus # BN 20180208 - Need TO_PLANE=True if you want an intermediate plane proper.prop_propagate(wfo, d_sec_to_focus, "focus", TO_PLANE=True) # proper.prop_propagate(wfo, d_sec_to_focus, "focus", TO_PLANE = False) # End (wfo, sampling) = proper.prop_end(wfo) return (wfo, sampling)
def run_system(empty_lamda, grid_size, PASSVALUE): # 'dm_disp':0 passpara = PASSVALUE['params'] ap.__dict__ = passpara[0].__dict__ tp.__dict__ = passpara[1].__dict__ iop.__dict__ = passpara[2].__dict__ sp.__dict__ = passpara[3].__dict__ # params.ap = passpara[0] # params.tp = passpara[1] # # ap = params.ap # tp = params.tp # print 'line 23', tp.occulter_type # print 'propagating frame:', PASSVALUE['iter'] wsamples = np.linspace(tp.band[0], tp.band[1], tp.nwsamp) / 1e9 # print wsamples datacube = [] # print proper.prop_get_sampling(wfp), proper.prop_get_nyquistsampling(wfp), proper.prop_get_fratio(wfp) # global phase_map, Imaps # Imaps = np.zeros((4,tp.grid_size,tp.grid_size)) # phase_map = np.zeros((tp.grid_size, tp.grid_size)) if ap.companion: wf_array = np.empty((len(wsamples), 1 + len(ap.contrast)), dtype=object) else: wf_array = np.empty((len(wsamples), 1), dtype=object) beam_ratios = np.zeros_like((wsamples)) for iw, w in enumerate(wsamples): # Define the wavefront beam_ratios[iw] = tp.beam_ratio * tp.band[0] / w * 1e-9 wfp = proper.prop_begin(tp.diam, w, tp.grid_size, beam_ratios[iw]) wfs = [wfp] names = ['primary'] if ap.companion: for id in range(len(ap.contrast)): wfc = proper.prop_begin(tp.diam, w, tp.grid_size, beam_ratios[iw]) wfs.append(wfc) names.append('companion_%i' % id) for io, (iwf, wf) in enumerate(zip(names, wfs)): wf_array[iw, io] = wf iter_func(wf_array, proper.prop_circular_aperture, **{'radius':tp.diam/2}) if tp.use_atmos: tdm.add_atmos(wf_array, *(tp.f_lens, w, PASSVALUE['atmos_map'])) # quicklook_wf(wf_array[0, 0]) wf_array = tdm.abs_zeros(wf_array) # get_intensity(wf_array, sp, phase=True) if tp.rot_rate: iter_func(wf_array, tdm.rotate_atmos, *(PASSVALUE['atmos_map'])) if tp.use_spiders: iter_func(wf_array, tdm.add_spiders, tp.diam) wf_array = tdm.abs_zeros(wf_array) if sp.get_ints: get_intensity(wf_array, sp, phase=True) # tdm.add_spiders(wf, tp.diam) wf_array = tdm.abs_zeros(wf_array) # if tp.use_hex: # tdm.add_hex(wf) iter_func(wf_array,proper.prop_define_entrance) # normalizes the intensity if wf_array.shape[1] >=1: tdm.offset_companion(wf_array[:,1:], PASSVALUE['atmos_map'], ) # tdm.offset_companion(wf_array, PASSVALUE['atmos_map']) # if tp.use_apod: # tdm.do_apod(wf, tp.grid_size, tp.beam_ratio, tp.apod_gaus) # # iter_func(wf_array, proper.prop_propagate, tp.f_lens) if tp.aber_params['CPA']: tdm.add_aber(wf_array, tp.f_lens, tp.aber_params, tp.aber_vals, PASSVALUE['iter'], Loc='CPA') iter_func(wf_array, proper.prop_circular_aperture, **{'radius': tp.diam / 2}) iter_func(wf_array, tdm.add_spiders, tp.diam, legs=False) wf_array = tdm.abs_zeros(wf_array) if sp.get_ints: get_intensity(wf_array, sp, phase=True) # iter_func(wf_array, proper.prop_propagate, tp.f_lens) # quicklook_wf(wf_array[0,0]) # iter_func(wf_array, proper.prop_circular_aperture, **{'radius': tp.diam / 2}) # iter_func(wf_array, tdm.add_spiders, tp.diam, legs=False) # # proper.prop_rectangular_obscuration(wf_array[0,0], 0.05 * 8, 8 * 1.3, ROTATION=20) # # proper.prop_rectangular_obscuration(wf_array[0,0], 8 * 1.3, 0.05 * 8, ROTATION=20) # quicklook_wf(wf_array[0, 0]) if tp.quick_ao: r0 = float(PASSVALUE['atmos_map'][-10:-5]) tdm.flat_outside(wf_array) CPA_maps = tdm.quick_wfs(wf_array[:,0], PASSVALUE['iter'], r0=r0) # , obj_map, tp.wfs_scale) if tp.use_ao: tdm.quick_ao(wf_array, iwf, tp.f_lens, beam_ratios, PASSVALUE['iter'], CPA_maps) # iter_func(wf_array, proper.prop_circular_aperture, **{'radius': tp.diam / 2}) # iter_func(wf_array, tdm.add_spiders, tp.diam, legs=False) wf_array = tdm.abs_zeros(wf_array) if sp.get_ints: get_intensity(wf_array, sp, phase=True) # dprint('quick_ao') else: print('This need to be updated to the parrallel implementation') exit() # if tp.use_ao: # tdm.adaptive_optics(wf, iwf, iw, tp.f_lens, beam_ratio, PASSVALUE['iter']) # # if iwf == 'primary': # and PASSVALUE['iter'] == 0: # # quicklook_wf(wf, show=True) # r0 = float(PASSVALUE['atmos_map'][-10:-5]) # # dprint((r0, 'r0')) # # if iw == np.ceil(tp.nwsamp/2): # tdm.wfs_measurement(wf, PASSVALUE['iter'], iw, r0=r0) # , obj_map, tp.wfs_scale) # # iter_func(wf_array, proper.prop_propagate, tp.f_lens) # quicklook_wf(wf_array[0,0]) # rawImageIO.save_wf(wf, iop.datadir+'/loopAO_8act.pkl') # if iwf == 'primary': # quicklook_wf(wf, show=True) # if tp.active_modulate: # tdm.modulate(wf, w, PASSVALUE['iter']) # if iwf == 'primary': # quicklook_wf(wf, show=True) if tp.aber_params['NCPA']: tdm.add_aber(wf_array, tp.f_lens, tp.aber_params, tp.aber_vals, PASSVALUE['iter'], Loc='NCPA') iter_func(wf_array, proper.prop_circular_aperture, **{'radius': tp.diam / 2}) iter_func(wf_array, tdm.add_spiders, tp.diam, legs=False) wf_array = tdm.abs_zeros(wf_array) if sp.get_ints: get_intensity(wf_array, sp, phase=True) if tp.use_zern_ab: iter_func(wf_array, tdm.add_zern_ab, tp.f_lens) # # if iwf == 'primary': # # NCPA_phasemap = proper.prop_get_phase(wf) # # quicklook_im(NCPA_phasemap, logAmp=False, show=False, colormap="jet", vmin=-3.14, vmax=3.14) # # if iwf == 'primary': # # global obj_map # # r0 = float(PASSVALUE['atmos_map'][-10:-5]) # # obj_map = tdm.wfs_measurement(wf, r0 = r0)#, obj_map, tp.wfs_scale) # # # quicklook_im(obj_map, logAmp=False) # # iter_func(wf_array, proper.prop_propagate, 2*tp.f_lens) # # spiders are introduced here for now since the phase unwrapping seems to ignore them and hence so does the DM # Check out http://scikit-image.org/docs/dev/auto_examples/filters/plot_phase_unwrap.html for masking argument # if tp.use_spiders: # iter_func(wf_array, tdm.add_spiders, tp.diam) # # tdm.prop_mid_optics(wf, tp.f_lens) if tp.use_apod: from coronagraph import apodization iter_func(wf_array, apodization, True) iter_func(wf_array, tdm.prop_mid_optics, tp.f_lens) # # # if iwf == 'primary': # # if PASSVALUE['iter']>ap.numframes-2 or PASSVALUE['iter']==0: # # quicklook_wf(wf, show=True) # dprint((proper.prop_get_sampling(wf_array[0,0]), proper.prop_get_sampling_arcsec(wf_array[0,0]), 'here')) # if tp.satelite_speck and iwf == 'primary': # tdm.add_speckles(wf) # # # tp.variable = proper.prop_get_phase(wfo)[20,20] # # print 'speck phase', tp.variable # # # import cPickle as pickle # # dprint('just saved') # # with open(iop.phase_ideal, 'wb') as handle: # # pickle.dump(proper.prop_get_phase(wf), handle, protocol=pickle.HIGHEST_PROTOCOL) # # if tp.active_null and iwf == 'primary': # FPWFS.active_null(wf, PASSVALUE['iter'], w) # # if tp.speckle_kill and iwf == 'primary': # # tdm.speckle_killer(wf) # # tdm.speck_kill(wf) # # # iwf == 'primary': # # parent_bright = aper_phot(proper.prop_get_amplitude(wf),0,8) # # # # if iwf == 'primary' and iop.saveIQ: # # save_pix_IQ(wf) # # complex_map = proper.prop_shift_center(wf.wfarr) # # complex_pix = complex_map[64, 64] # # print complex_pix # # if np.real(complex_pix) < 0.2: # # quicklook_IQ(wf) # # # # if iwf == 'primary': # # # print np.sum(proper.prop_get_amplitude(wf)), 'before', aper_phot(proper.prop_get_amplitude(wf),0,4) # # quicklook_wf(wf, show=True, logAmp=True) # # if iwf == 'primary': # # quicklook_wf(wf, show=True) # # # if tp.active_modulate and PASSVALUE['iter'] >=8: # # coronagraph(wf, tp.f_lens, tp.occulter_type, tp.occult_loc, tp.diam) # # if not tp.active_modulate: if sp.get_ints: get_intensity(wf_array, sp, phase=False) # quicklook_wf(wf_array[0, 0], show=True) iter_func(wf_array, coronagraph, *(tp.f_lens, tp.occulter_type, tp.occult_loc, tp.diam)) # if 'None' not in tp.occulter_type: # kludge for now until more sophisticated coronagraph has been installed # for iw in range(len(wf_array)): # wf_array[iw,0].wfarr *= 0.1 if sp.get_ints: get_intensity(wf_array, sp, phase=False) # dprint(wf_array.shape) # quicklook_wf(wf_array[0, 0], show=True) # quicklook_wf(wf_array[0, 1], show=True) # quicklook_wf(wf_array[1, 0], show=True) dprint(proper.prop_get_sampling_arcsec(wf_array[0,0])) # dprint(proper.prop_get_sampling_arcsec(wf_array[0,1])) # # exit() # # tp.occult_factor = aper_phot(proper.prop_get_amplitude(wf),0,8)/parent_bright # # if PASSVALUE['iter'] % 10 == 0: # # with open(iop.logfile, 'a') as the_file: # # the_file.write('\n', tp.occult_factor) # # # quicklook_wf(wf, show=True) # if tp.occulter_type != 'None' and iwf == 'primary': # kludge for now until more sophisticated coronapraph has been installed # wf.wfarr *= 0.1 # # # print np.sum(proper.prop_get_amplitude(wf)), 'after', aper_phot(proper.prop_get_amplitude(wf), 0, 4) # # quicklook_wf(wf, show=True) # # print proper.prop_get_sampling(wfp), proper.prop_get_sampling_arcsec(wfp), 'here' # # if iwf == 'primary': # # quicklook_wf(wf, show=True) # if tp.use_zern_ab: # tdm.add_zern_ab(wf, tp.f_lens) # shape = wf_array.shape # comp_scaling = 10*np.arange(1,shape[0]+1)/shape[0] # dprint(comp_scaling) for iw in range(shape[0]): wframes = np.zeros((tp.grid_size, tp.grid_size)) for io in range(shape[1]): (wframe, sampling) = proper.prop_end(wf_array[iw,io]) # dprint((np.sum(wframe), 'sum')) # wframe = proper.prop_get_amplitude(wf) # planet = np.roll(np.roll(wframe, 20, 1), 20, 0) * 0.1 # [92,92] # if ap.companion: # from scipy.ndimage.interpolation import shift # companion = shift(wframe, shift= np.array(ap.comp_loc[::-1])- np.array([tp.grid_size/2,tp.grid_size/2])) * ap.contrast # # planet = np.roll(wframe, 15, 0) * 0.1 # [92,92] # # wframe = (wframe + companion) # quicklook_im(wframe, logAmp=True) # '''test conserve=True on prop_magnify!''' # wframe = proper.prop_magnify(wframe, (w*1e9)/tp.band[0]) # wframe = tdm.scale_wframe(wframe, w, iwf) # print np.shape(wframe) # quicklook_im(wframe, logAmp=True) # quicklook_im(wframe[57:201,59:199]) # mid = int(len(wframe)/2) # wframe = wframe[mid - tp.grid_size/2 : mid +tp.grid_size/2, mid - tp.grid_size/2 : mid +tp.grid_size/2] # if max(mp.array_size) < tp.grid_size: # # Photons seeded outside the array cannot have pixel phase uncertainty applied to them. Instead make both grids match in size # wframe = rawImageIO.resize_image(wframe, newsize=(max(mp.array_size),max(mp.array_size))) # dprint(np.sum(wframe)) # dprint(iwf) # if iwf == 'companion_0': # if io > 0: # wframe *= comp_scaling[iw] wframes += wframe # if sp.show_wframe: # quicklook_im(wframes, logAmp=True, show=True) datacube.append(wframes) datacube = np.array(datacube) # if tp.pix_shift: # datacube = np.roll(np.roll(datacube, tp.pix_shift[0], 1), tp.pix_shift[1], 2) datacube = np.abs(datacube) # #normalize # dprint(np.sum(datacube, axis=(1, 2))) # dprint((tp.interp_sample , tp.nwsamp>1 , tp.nwsamp<tp.w_bins)) if tp.interp_sample and tp.nwsamp>1 and tp.nwsamp<tp.w_bins: # view_datacube(datacube, logAmp=True) wave_samps = np.linspace(0, 1, tp.nwsamp) f_out = interp1d(wave_samps, datacube, axis=0) new_heights = np.linspace(0, 1, tp.w_bins) datacube = f_out(new_heights) # dprint(datacube.shape) # view_datacube(datacube, logAmp=True) # datacube = np.transpose(np.transpose(datacube) / np.sum(datacube, axis=(1, 2)))/float(tp.nwsamp) # print 'Some pixels have negative values, possibly because of some Gaussian uncertainy you introduced. Taking abs for now.' # view_datacube(datacube) # # End # print type(wfo[0,0]), type(wfo) # # proper.prop_savestate(wfo) # # else: # # wfo = proper.prop_state(wfo) return (datacube, sampling)
calib) # read the perfect-result vortex field perf_num = perf_num / psf0 * scale_psf wfo._wfarr = ( wfo._wfarr - psf_num ) * vvc + perf_num # the wavefront takes into account the real pupil with the perfect-result vortex field quicklook_wf(wfo) proper.prop_propagate(wfo, f_lens, "propagate to pupil reimaging lens") proper.prop_lens(wfo, f_lens, "apply pupil reimaging lens") proper.prop_propagate(wfo, f_lens, "lyot stop") quicklook_wf(wfo) return wfo wfo = proper.prop_begin(tp.diam, tp.band[0], tp.grid_size, tp.beam_ratio) proper.prop_circular_aperture(wfo, tp.diam / 2) proper.prop_define_entrance(wfo) # proper.prop_zernikes(wfo, [2, 3], np.array([3,3])*1e-6) vortex(wfo) # quicklook_wf(wfo) proper.prop_circular_aperture(wfo, 0.75, NORM=True) quicklook_wf(wfo) proper.prop_propagate(wfo, tp.f_lens) proper.prop_lens(wfo, tp.f_lens) # quicklook_wf(wfo) (wframe, sampling) = proper.prop_end(wfo) print np.sum(phot.aper_phot(wframe, 0, 5, plot=True)) quicklook_im(wframe, logAmp=True) quicklook_im(phot.aper_phot(wframe, 0, 5))