def create_pupil_masks(self, spaxel_scale, N_waves, wave0, waveN, wave_ref): """ Creates a dictionary of pupil masks for a set of wavelengths The pupil masks change in size to account for the variation of PSF size with wavelength We set the spaxel_scale for the first wavelength [wave0] :param spaxel_scale: spaxel_scale [mas] for wave0 :param N_waves: number of wavelengths to consider in the interval [wave0, waveN] :param wave0: nominal wavelength in [microns] :param waveN: maximum wavelength in [microns] :param wave_ref: reference wavelength at which we have self.spaxel_scale :return: """ self.wave_range = np.linspace(wave0, waveN, N_waves, endpoint=True) self.wave_ref = wave_ref self.waves_ratio = self.wave_range / wave_ref rho_aper = utils.rho_spaxel_scale(spaxel_scale, wavelength=wave0) self.diameters = 1 / rho_aper # check_spaxel_scale(rho_aper=rho_aper, wavelength=wave0) rho_obsc = CENTRAL_OBS * rho_aper self.rho_aper = rho_aper self.rho_obsc = rho_obsc self.pupil_masks, self.pupil_masks_fft = {}, {} x0 = np.linspace(-1., 1., self.N_PIX, endpoint=True) xx, yy = np.meshgrid(x0, x0) print("\nCreating Pupil Masks:") for i, wave in enumerate(self.waves_ratio): wavelength = self.wave_range[i] print("Wavelength: %.2f microns" % wavelength) # pupil = (rho <= rho_aper / wave) & (rho >= rho_obsc / wave) _pupil = pupil_mask(xx, yy, rho_aper / wave, rho_obsc / wave, self.anamorphic) mask = np.array(_pupil).astype(np.float32) self.pupil_masks[wavelength] = mask self.pupil_masks_fft[wavelength] = np.stack( mask * self.N_slices) # For the GPU calculations return
import matplotlib.pyplot as plt import matplotlib.cm as cm import psf import utils import calibration import noise ### PARAMETERS ### # PSF bits N_PIX = 256 # pixels for the Fourier arrays pix = 30 # pixels to crop the PSF images WAVE = 1.5 # microns | reference wavelength SPAX = 4.0 # mas | spaxel scale RHO_APER = utils.rho_spaxel_scale(spaxel_scale=SPAX, wavelength=WAVE) RHO_OBSC = 0.30 * RHO_APER # ELT central obscuration utils.check_spaxel_scale(rho_aper=RHO_APER, wavelength=WAVE) N_actuators = 16 # Number of actuators in [-1, 1] line alpha_pc = 20 # Height [percent] at the neighbour actuator (Gaussian Model) # Machine Learning bits N_train, N_test = 5000, 500 # Samples for the training of the models coef_strength = 1.75 / (2 * np.pi) # Strength of the actuator coefficients rescale = 0.35 # Rescale the coefficients to cover a wide range of RMS layer_filters = [16, 8] # How many filters per layer kernel_size = 3 input_shape = ( pix, pix, 2,
### PARAMETERS ### # Change any of these before running the code pix = 150 # Pixels to crop the PSF N_PIX = 512 # Pixels for the Fourier arrays # WATCH OUT: # We want the spaxel scale to be 4 mas at 1.5 um # But that means that it won't be 4 mas at whatever other wavelength # SPAXEL SCALE wave0 = 1.5 # Nominal wavelength at which to force a given spaxel scale SPAXEL_MAS = 0.5 # [mas] spaxel scale at wave0 RHO_MAS = utils.rho_spaxel_scale(spaxel_scale=SPAXEL_MAS, wavelength=wave0) # Rescale the aperture radius to mimic the wavelength scaling of the PSF wave = 1.0 # 1 micron RHO_APER = wave0 / wave * RHO_MAS RHO_OBSC = 0.3 * RHO_APER # Central obscuration (30% of ELT) # Decide whether you want to use Zernike polynomials # "up to a certain row" row_by_row == False # or whether you want it row_by_row == True # This is because low order and high order aberrations behave differently wrt EE row_by_row = True min_Zernike = 3 # Row number max_Zernike = 7 zernike_triangle = zernike.triangular_numbers(N_levels=max_Zernike)