Commit a8e88b2e authored by Chen Yili's avatar Chen Yili
Browse files

Upload New File

No related merge requests found
Showing with 106 additions and 0 deletions
+106 -0
import numpy as np
from astropy.io import fits
from hcipy import Field, Wavefront, DeformableMirror, FraunhoferPropagator
from hcipy import SurfaceApodizer, SurfaceAberrationAtDistance
from hcipy import make_pupil_grid, make_circular_aperture, make_focal_grid
from hcipy import make_xinetics_influence_functions
from hcipy import read_fits
from .config import cpism_refdata, S
from .optics import filter_throughput
# initial psf simulation
apm, apm_header = fits.getdata(
f'{cpism_refdata}/optics/apm.fits', header=True)
actuator = read_fits(f'{cpism_refdata}/optics/actuator.fits')
surface_aberration = read_fits(
f'{cpism_refdata}/optics/initial_phase_aberration.fits')
wavelength = 625e-9 # m
pupil_diameter = 2 # m
focal_length = pupil_diameter * 83
pupil_grid = make_pupil_grid(apm.shape[0], apm.shape[0] * apm_header['PHRATE'])
aperture = make_circular_aperture(pupil_diameter)(pupil_grid)
aperture = aperture * Field(apm.flatten(), pupil_grid)
emccd_pixel_size = 13e-6 # m
arcsec2rad = np.radians(1 / 3600)
emccd_pixel_scale = emccd_pixel_size / \
(arcsec2rad * focal_length) # arcsec / pixel
spatial_resolution = focal_length * wavelength / \
pupil_diameter # meter per airy disk
q = spatial_resolution / emccd_pixel_size # pixels per airy disk
num_airy = 512 / q # airy disk per frame (2 * 512 = 1024 pix)
focal_full_frame = make_focal_grid(
q, num_airy, spatial_resolution=spatial_resolution)
prop_full_frame = FraunhoferPropagator(
pupil_grid, focal_full_frame, focal_length)
num_airy = 128 / q # make a small frame for the planets
focal_sub_frame = make_focal_grid(
q, num_airy, spatial_resolution=spatial_resolution)
prop_sub_frame = FraunhoferPropagator(
pupil_grid, focal_sub_frame, focal_length)
num_actuators_across = 32
# dm spacing is little smaller than pupil
actuator_spacing = 0.95 / 32 * pupil_diameter
influence_functions = make_xinetics_influence_functions(
pupil_grid, num_actuators_across, actuator_spacing)
deformable_mirror = DeformableMirror(influence_functions)
aberration = SurfaceApodizer(
surface_sag=surface_aberration.flatten(), refractive_index=-1)
# arbitrary distance for the aberration to propagate
aberration_distance = 80 * focal_length
aberration = SurfaceAberrationAtDistance(aberration, aberration_distance)
def simulate_psf(error_value, band, spectrum, nsample=5, cstar=True, aber_phase=None):
filter = filter_throughput(band)
wave = filter.wave
throughput = filter.throughput
min_wave = wave[0]
max_wave = wave[-1]
sed = []
sed_center_wavelength = []
for i_wave in range(nsample):
d_wave = (max_wave - min_wave) / nsample
wave0 = min_wave + i_wave * d_wave
wave1 = min_wave + (i_wave + 1) * d_wave
sed_center_wavelength.append((wave0 + wave1) / 2 * 1e-10)
i_throughput = throughput.copy()
i_throughput[(wave > wave1) | (wave < wave0)] = 0
i_band = S.ArrayBandpass(wave, i_throughput, waveunits='angstrom')
i_sed = (spectrum * i_band).integrate()
sed.append(i_sed)
error = np.random.normal(0, error_value*1e-9, actuator.shape)
imgs = []
deformable_mirror.actuators = actuator + error
prop = prop_full_frame
if not cstar:
prop = prop_sub_frame
for i_sample in range(nsample):
wf = Wavefront(aperture, sed_center_wavelength[i_sample])
wf = aberration(wf)
if aber_phase is not None:
other_error = SurfaceApodizer(
surface_sag=aber_phase.flatten(), refractive_index=-1)
wf = other_error(wf)
img = prop(deformable_mirror(wf)).intensity.shaped
imgs.append(img / img.sum() * sed[i_sample])
return np.array(imgs).sum(axis=0)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment