def Subaru_frontend(empty_lamda, grid_size, PASSVALUE): """ propagates instantaneous complex E-field thru Subaru 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 in the focal_plane() """ # print("Propagating Broadband Wavefront Through Subaru") # Initialize the Wavefront in Proper wfo = opx.Wavefronts() wfo.initialize_proper() # Atmosphere # atmos has only effect on phase delay, not intensity wfo.loop_collection(atmos.add_atmos, PASSVALUE['iter'], plane_name='atmosphere') # Defines aperture (baffle-before primary) # Obscurations (Secondary and Spiders) wfo.loop_collection(opx.add_obscurations, d_primary=tp.d_nsmyth, d_secondary=tp.d_secondary, legs_frac=0.05) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # clear inside, dark outside wfo.loop_collection( proper.prop_define_entrance, plane_name='entrance_pupil') # normalizes abs intensity if ap.companion: # Must do this after all calls to prop_define_entrance wfo.loop_collection(opx.offset_companion) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2 }) # clear inside, dark outside # Test Sampling if sp.verbose: opx.check_sampling(PASSVALUE['iter'], wfo, "initial", getframeinfo(stack()[0][0]), units='mm') # Testing Primary Focus (instead of propagating to focal plane) # wfo.loop_collection(opx.prop_pass_lens, tp.flen_nsmyth, tp.flen_nsmyth) # test only going to prime focus ######################################## # Subaru Propagation ####################################### # Effective Primary # CPA from Effective Primary wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='ao188-OAP1') # Zernike Aberrations- Low Order # wfo.loop_collection(aber.add_zern_ab, tp.zernike_orders, aber.randomize_zern_values(tp.zernike_orders)) wfo.loop_collection(opx.prop_pass_lens, tp.flen_nsmyth, tp.dist_nsmyth_ao1) ######################################## # AO188 Propagation ######################################## # # AO188-OAP1 wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='ao188-OAP1') wfo.loop_collection(opx.prop_pass_lens, tp.fl_ao1, tp.dist_ao1_dm) # AO System if tp.use_ao: WFS_map = ao.open_loop_wfs(wfo) wfo.loop_collection( ao.deformable_mirror, WFS_map, PASSVALUE['iter'], plane_name='woofer', debug=sp.debug ) # don't use PASSVALUE['WFS_map'] here because open loop # ------------------------------------------------ wfo.loop_collection(proper.prop_propagate, tp.dist_dm_ao2) # AO188-OAP2 wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='ao188-OAP2') # wfo.loop_collection(aber.add_zern_ab, tp.zernike_orders, aber.randomize_zern_values(tp.zernike_orders)/2) wfo.loop_collection(opx.prop_pass_lens, tp.fl_ao2, tp.dist_oap2_focus) ######################################## # Focal Plane # ####################################### # Check Sampling in focal plane if sp.verbose: wfo.loop_collection(opx.check_sampling, PASSVALUE['iter'], "focal plane", getframeinfo(stack()[0][0]), units='nm') # wfo.focal_plane fft-shifts wfo from Fourier Space (origin==lower left corner) to object space (origin==center) cpx_planes, sampling = wfo.focal_plane() print(f"Finished datacube at timestep = {PASSVALUE['iter']}") return cpx_planes, sampling
def SCExAO_DM(empty_lamda, grid_size, PASSVALUE): """ propagates instantaneous complex E-field thru Subaru from the DM through SCExAO this function is called a 'prescription' by proper uses PyPROPER3 to generate the complex E-field at the pupil plane, then propagates it through SCExAO 50x50 DM, then coronagraphope, to the focal plane :returns spectral cube at instantaneous time in the focal_plane() """ # print("Propagating Broadband Wavefront Through Subaru") # Initialize the Wavefront in Proper wfo = opx.Wavefronts(sp.debug) wfo.initialize_proper() # Defines aperture (baffle-before primary) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # clear inside, dark outside wfo.loop_collection(proper.prop_define_entrance, plane_name='entrance_pupil') # normalizes abs intensity wfo.loop_collection(opx.SubaruPupil, plane_name='SubaruPupil') # Test Sampling if sp.verbose: wfo.loop_collection(opx.check_sampling, PASSVALUE['iter'], "Telescope Aperture", getframeinfo(stack()[0][0]), units='mm') # Testing Primary Focus (instead of propagating to focal plane) # wfo.loop_collection(opx.prop_pass_lens, tp.flen_nsmyth, tp.flen_nsmyth) # test only going to prime focus ######################################## # SCExAO # ####################################### # AO System if tp.use_ao: WFS_map = ao.open_loop_wfs(wfo) wfo.loop_collection(ao.deformable_mirror, WFS_map, PASSVALUE['iter'], apodize=False, plane_name='tweeter', debug=sp.verbose) # ------------------------------------------------ wfo.loop_collection(proper.prop_propagate, tp.fl_SxOAPG) # from tweeter-DM to OAP2 # SXExAO Reimaging 2 wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='SxOAP2') wfo.loop_collection(aber.add_zern_ab, tp.zernike_orders, aber.randomize_zern_values(tp.zernike_orders)/2) wfo.loop_collection(opx.prop_pass_lens, tp.fl_SxOAP2, tp.fl_SxOAP2, plane_name='post-DM-focus') #tp.dist_sl2_focus # wfo.loop_collection(opx.check_sampling, PASSVALUE['iter'], "post-DM-focus", # getframeinfo(stack()[0][0]), units='nm') # Coronagraph # settings should be put into tp, and are not implicitly passed here wfo.loop_collection(cg.coronagraph, occulter_mode=tp.cg_type, plane_name='coronagraph') ######################################## # Focal Plane # ####################################### # Check Sampling in focal plane # wfo.focal_plane fft-shifts wfo from Fourier Space (origin==lower left corner) to object space (origin==center) cpx_planes, sampling = wfo.focal_plane() if sp.verbose: wfo.loop_collection(opx.check_sampling, PASSVALUE['iter'], "focal plane", getframeinfo(stack()[0][0]), units='nm') # opx.check_sampling(PASSVALUE['iter'], wfo, "focal plane", getframeinfo(stack()[0][0]), units='arcsec') if sp.verbose: print(f"Finished datacube at timestep = {PASSVALUE['iter']}") return cpx_planes, sampling
def Subaru_SCExAO(empty_lamda, grid_size, PASSVALUE): """ propagates instantaneous complex E-field thru Subaru from the primary through SCExAO 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 in the focal_plane() """ # print("Propagating Broadband Wavefront Through Subaru") # Initialize the Wavefront in Proper wfo = opx.Wavefronts(sp.debug) wfo.initialize_proper() # Atmosphere # atmos has only effect on phase delay, not intensity wfo.loop_collection(atmos.add_atmos, PASSVALUE['iter'], plane_name='atmosphere') # Defines aperture (baffle-before primary) # wfo.loop_collection(opx.add_obscurations, d_primary=tp.entrance_d, d_secondary=tp.d_secondary, legs_frac=0.05) wfo.loop_collection(opx.SubaruPupil, plane_name='SubaruPupil') wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # clear inside, dark outside wfo.loop_collection( proper.prop_define_entrance, plane_name='entrance_pupil') # normalizes abs intensity if ap.companion: # Must do this after all calls to prop_define_entrance wfo.loop_collection(opx.offset_companion) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2 }) # clear inside, dark outside # Test Sampling if sp.verbose: wfo.loop_collection(opx.check_sampling, PASSVALUE['iter'], "Telescope Aperture", getframeinfo(stack()[0][0]), units='mm') # Testing Primary Focus (instead of propagating to focal plane) # wfo.loop_collection(opx.prop_pass_lens, tp.flen_nsmyth, tp.flen_nsmyth) # test only going to prime focus ######################################## # Subaru Propagation ####################################### # Effective Primary # CPA from Effective Primary wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='effective-primary') # high order wfo.loop_collection(aber.add_zern_ab, tp.zernike_orders, aber.randomize_zern_values( tp.zernike_orders)) # low order wfo.loop_collection(opx.prop_pass_lens, tp.flen_nsmyth, tp.dist_nsmyth_ao1) ######################################## # AO188 Propagation ######################################## # # AO188-OAP1 wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='ao188-OAP1') # high order wfo.loop_collection(opx.prop_pass_lens, tp.fl_ao1, tp.dist_ao1_dm) # AO System if tp.use_ao: WFS_map = ao.open_loop_wfs(wfo) wfo.loop_collection( ao.deformable_mirror, WFS_map, PASSVALUE['iter'], apodize=True, plane_name='woofer', debug=sp.verbose ) # don't use PASSVALUE['WFS_map'] here because open loop # ------------------------------------------------ wfo.loop_collection(proper.prop_propagate, tp.dist_dm_ao2) # AO188-OAP2 wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='ao188-OAP2') # high order CPA wfo.loop_collection(aber.add_zern_ab, tp.zernike_orders, aber.randomize_zern_values(tp.zernike_orders) / 2) # low order CPA wfo.loop_collection(opx.prop_pass_lens, tp.fl_ao2, tp.dist_oap2_focus) ######################################## # SCExAO # ####################################### # SXExAO Reimaging 1 wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='SxOAPG') # high order CPA wfo.loop_collection(proper.prop_propagate, tp.fl_SxOAPG) # from AO188 focus to S-OAP1 wfo.loop_collection(opx.prop_pass_lens, tp.fl_SxOAPG, tp.fl_SxOAPG) # from SxOAP1 to tweeter-DM # # AO System if tp.use_ao: # WFS_map = ao.open_loop_wfs(wfo) wfo.loop_collection(ao.deformable_mirror, WFS_map, PASSVALUE['iter'], apodize=True, plane_name='tweeter', debug=sp.verbose) # ------------------------------------------------ wfo.loop_collection(proper.prop_propagate, tp.fl_SxOAPG) # from tweeter-DM to OAP2 # SXExAO Reimaging 2 wfo.loop_collection(aber.add_aber, step=PASSVALUE['iter'], lens_name='SxOAP2') # high order NCPA wfo.loop_collection(aber.add_zern_ab, tp.zernike_orders, aber.randomize_zern_values(tp.zernike_orders) / 2) # low order NCPA wfo.loop_collection(opx.prop_pass_lens, tp.fl_SxOAP2, tp.fl_SxOAP2, plane_name='post-DM-focus') #tp.dist_sl2_focus # wfo.loop_collection(opx.check_sampling, PASSVALUE['iter'], "post-DM-focus", # getframeinfo(stack()[0][0]), units='nm') # Coronagraph # settings should be put into tp, and are not implicitly passed here wfo.loop_collection(cg.coronagraph, occulter_mode=tp.cg_type, plane_name='coronagraph') ######################################## # Focal Plane # ####################################### # Check Sampling in focal plane # wfo.focal_plane fft-shifts wfo from Fourier Space (origin==lower left corner) to object space (origin==center) cpx_planes, sampling = wfo.focal_plane() if sp.verbose: wfo.loop_collection(opx.check_sampling, PASSVALUE['iter'], "focal plane", getframeinfo(stack()[0][0]), units='nm') # opx.check_sampling(PASSVALUE['iter'], wfo, "focal plane", getframeinfo(stack()[0][0]), units='arcsec') if sp.verbose: print(f"Finished datacube at timestep = {PASSVALUE['iter']}") return cpx_planes, sampling
def general_telescope(empty_lamda, grid_size, PASSVALUE): """ #TODO pass complex datacube for photon phases propagates instantaneous complex E-field through the optical system in loop over wavelength range this function is called as 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 currently: optics system "hard coded" as single aperture and lens the AO simulator happens here this does not include the observation of the wavefront by the detector :returns spectral cube at instantaneous time """ # print("Propagating Broadband Wavefront Through Telescope") # Parameters-import statements won't work through the function passpara = PASSVALUE['params'] ap.__dict__ = passpara[0].__dict__ tp.__dict__ = passpara[1].__dict__ iop.__dict__ = passpara[2].__dict__ sp.__dict__ = passpara[3].__dict__ # datacube = [] wfo = opx.Wavefronts() wfo.initialize_proper() ################################################### # Aperture, Atmosphere, and Secondary Obscuration ################################################### # Defines aperture (baffle-before primary) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # wfo.loop_collection(proper.prop_define_entrance) # normalizes the intensity # Obscure Baffle if tp.obscure: wfo.loop_collection(opx.add_obscurations, M2_frac=1 / 8, d_primary=tp.entrance_d, legs_frac=tp.legs_frac) # Pass through a mini-atmosphere inside the telescope baffle # The atmospheric model used here (as of 3/5/19) uses different scale heights, # wind speeds, etc to generate an atmosphere, but then flattens it all into # a single phase mask. The phase mask is a real-valued delay lengths across # the array from infinity. The delay length thus corresponds to a different # phase offset at a particular frequency. # quicklook_wf(wfo.wf_collection[0,0]) if tp.use_atmos: wfo.loop_collection(atmos.add_atmos, PASSVALUE['iter'], plane_name='atmosphere') # quicklook_wf(wfo.wf_collection[0, 0]) # quicklook_wf(wfo.wf_collection[0,0]) #TODO rotate atmos not yet implementid in 2.0 # if tp.rotate_atmos: # wfo.loop_collection(aber.rotate_atmos, *(PASSVALUE['iter'])) # Both offsets and scales the companion wavefront if wfo.wf_collection.shape[1] > 1: wfo.loop_collection(opx.offset_companion) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2 }) # clear inside, dark outside # TODO rotate atmos not yet implementid in 2.0 # if tp.rotate_sky: # wfo.loop_collection(opx.rotate_sky, *PASSVALUE['iter']) ######################################## # Telescope Primary-ish Aberrations ####################################### # Abberations before AO if tp.use_CPA: wfo.loop_collection(aber.add_aber, tp.entrance_d, tp.aber_params, tp.aber_vals, step=PASSVALUE['iter'], lens_name='CPA') # wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # wfo.wf_collection = aber.abs_zeros(wfo.wf_collection) ####################################### # AO ####################################### if tp.use_ao: if not sp.closed_loop: WFS_map = ao.open_loop_wfs(wfo) # tiptilt = np.zeros((sp.grid_size,sp.grid_size)) else: #TODO Rupert-CPA maps are no longer generated. Not sure what you want to do here. The CPA map is stored # as a fits file at f"{iop.aberdir}/t{iter}_CPA.fits" # WFS_map = PASSVALUE['CPA_maps'] # tiptilt = PASSVALUE['tiptilt'] # if tp.include_tiptilt: # CPA_maps, PASSVALUE['tiptilt'] = ao.tiptilt(wfo, CPA_maps, tiptilt) if tp.include_dm: wfo.loop_collection(ao.deformable_mirror, WFS_map, PASSVALUE['theta']) ######################################## # Post-AO Telescope Distortions # ####################################### # Abberations after the AO Loop if tp.use_NCPA: aber.add_aber(wfo, tp.f_lens, tp.aber_params, tp.aber_vals, PASSVALUE['iter'], lens_name='NCPA') wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # TODO does this need to be here? # wfo.loop_collection(opx.add_obscurations, tp.entrance_d/4, legs=False) # wfo.wf_collection = aber.abs_zeros(wfo.wf_collection) # Low-order aberrations if tp.use_zern_ab: wfo.loop_collection(aber.add_zern_ab) if tp.use_apod: wfo.loop_collection(apodization, True) # First Focusing Optics wfo.loop_collection(opx.prop_pass_lens, tp.f_lens, tp.f_lens) ######################################## # Coronagraph ######################################## # there are additional un-aberated optics in the coronagraph module if tp.use_coronagraph: wfo.loop_collection( coronagraph, *(tp.f_lens, tp.occulter_type, tp.occult_loc, tp.entrance_d)) ######################################## # Focal Plane ######################################## cpx_planes, sampling = wfo.focal_plane() print(f"Finished datacube at timestep = {PASSVALUE['iter']}") return cpx_planes, wfo.plane_sampling
def general_telescope(empty_lamda, grid_size, PASSVALUE): """ #TODO pass complex datacube for photon phases propagates instantaneous complex E-field through the optical system in loop over wavelength range this function is called as 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 currently: optics system "hard coded" as single aperture and lens the AO simulator happens here this does not include the observation of the wavefront by the detector :returns spectral cube at instantaneous time """ # print("Propagating Broadband Wavefront Through Telescope") wfo = opx.Wavefronts(debug=sp.debug) wfo.initialize_proper(set_up_beam=True) ################################################### # Atmosphere, and Secondary Obscuration ################################################### # Pass through a mini-atmosphere inside the telescope baffle # The atmospheric model used here (as of 3/5/19) uses different scale heights, # wind speeds, etc to generate an atmosphere, but then flattens it all into # a single phase mask. The phase mask is a real-valued delay lengths across # the array from infinity. The delay length thus corresponds to a different # phase offset at a particular frequency. if tp.use_atmos: wfo.loop_collection(atmos.add_atmos, PASSVALUE['iter'], (iop.atmosdir, sp.sample_time, atmp.model), spatial_zoom=True, plane_name='atmosphere') #TODO rotate atmos not yet implementid in 2.0 # if tp.rotate_atmos: # wfo.loop_collection(aber.rotate_atmos, *(PASSVALUE['iter'])) # Both offsets and scales the companion wavefront if wfo.wf_collection.shape[1] > 1: wfo.loop_collection(opx.offset_companion, step=PASSVALUE['iter']) wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2 }) # clear inside, dark outside # TODO rotate atmos not yet implementid in 2.0 # if tp.rotate_sky: # wfo.loop_collection(opx.rotate_sky, *PASSVALUE['iter']) ######################################## # Telescope Primary-ish Aberrations ####################################### # Abberations before AO wfo.loop_collection(aber.add_aber, iop.aberdir, PASSVALUE['iter'], lens_name='CPA') # wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # wfo.wf_collection = aber.abs_zeros(wfo.wf_collection) ####################################### # AO ####################################### if tp.use_ao: if sp.closed_loop: previous_output = ao.retro_wfs( PASSVALUE['AO_field'], wfo, plane_name='wfs') # unwrap a previous steps phase map wfo.loop_collection(ao.deformable_mirror, WFS_map=None, iter=PASSVALUE['iter'], previous_output=previous_output, plane_name='deformable mirror') elif sp.ao_delay > 0: WFS_map = ao.retro_wfs( PASSVALUE['WFS_field'], wfo, plane_name='wfs') # unwrap a previous steps phase map wfo.loop_collection(ao.deformable_mirror, WFS_map, iter=PASSVALUE['iter'], previous_output=None, plane_name='deformable mirror') else: WFS_map = ao.open_loop_wfs( wfo, plane_name='wfs') # just uwraps this steps measured phase_map wfo.loop_collection(ao.deformable_mirror, WFS_map, iter=PASSVALUE['iter'], previous_output=None, plane_name='deformable mirror') # Obscure Baffle if tp.obscure: wfo.loop_collection(opx.add_obscurations, M2_frac=1 / 8, d_primary=tp.entrance_d, legs_frac=tp.legs_frac) ######################################## # Post-AO Telescope Distortions # ####################################### # Abberations after the AO Loop wfo.loop_collection(aber.add_aber, iop.aberdir, PASSVALUE['iter'], lens_name='NCPA') wfo.loop_collection(proper.prop_circular_aperture, **{'radius': tp.entrance_d / 2}) # TODO does this need to be here? # wfo.loop_collection(opx.add_obscurations, tp.entrance_d/4, legs=False) # wfo.wf_collection = aber.abs_zeros(wfo.wf_collection) wfo.loop_collection(opx.prop_pass_lens, tp.lens_params[0]['focal_length'], tp.lens_params[0]['focal_length'], plane_name='pre_coron') ######################################## # Coronagraph ######################################## # there are additional un-aberated optics in the coronagraph module wfo.loop_collection(coronagraph, occulter_mode=tp.cg_type, plane_name='coronagraph') ######################################## # Focal Plane ######################################## cpx_planes, sampling = wfo.focal_plane() print(f"Finished datacube at timestep = {PASSVALUE['iter']}") return cpx_planes, wfo.plane_sampling