def make_standard_scao_constpsf(): waves = [1.2, 1.6, 2.15] nmRms = [310, 310, 310] # achieves the 40-18-6 Strehls for MAORY offset = [0, 0] psfs = [] for wave, rms in zip(waves, nmRms): psf = aniso.AnalyticalScaoPsf(pixelSize=0.004, N=256, wavelength=wave, nmRms=rms) psf.shift_off_axis(offset[0], offset[1]) psfs += [psf.hdu] keys = { "AUTHOR": "Kieran Leschinski", "DATE_CRE": "2019-07-30", "DATE_MOD": "2019-07-30", "SOURCE": "AnisoCADO", "STATUS": "Best guess for a MAORY ConstantPSF with AnisoCADO", "ETYPE": "CONSTPSF", "ECAT": (-1, "Field constant. No layer catalogue"), "EDATA": (1, "PSFs begin from EXT 1"), "XOFFSET": (offset[0], "[arcsec] offset from NGS"), "YOFFSET": (offset[1], "[arcsec] offset from NGS"), } pri = fits.PrimaryHDU() pri.header.update(keys) hdus = fits.HDUList([pri] + psfs) hdus.writeto("MCAO_ConstPSF_40_18_6.fits", clobber=True) for i in range(1, 4): print(hdus[i].header["WAVE0"], hdus[i].header["STREHL"]) print(hdus.info())
def generate_anisocado_strehl_map_for_micado(): # 310 nm --> 40 in Ks, 18 in H, 6 in J nmRms = np.linspace(0, 700, 36) waves = np.linspace(0.8, 2.4, 9) offset = [0, 0] psfs = [] srs = np.zeros((len(nmRms), len(waves))) for y, wave in enumerate(waves): sr = 1 for x, rms in enumerate(nmRms): if sr > 0.001: psf = aniso.AnalyticalScaoPsf(pixelSize=0.004, N=256, wavelength=wave, nmRms=rms) psf.shift_off_axis(offset[0], offset[1]) psfs += [psf.hdu] sr = psf.strehl_ratio srs[x, y] = sr print(wave, rms, srs[x, y]) hdu = fits.ImageHDU(data=srs) hdu.writeto("AnisoCADO_rms_map.fits", clobber=True) plt.imshow(srs) plt.colorbar() plt.show()
def get_kernel(self, fov): # called by .apply_to() from the base PSF class if self._kernel is None: if isinstance(fov, FieldOfViewBase): pixel_scale = fov.header["CDELT1"] * u.deg.to(u.arcsec) elif isinstance(fov, float): pixel_scale = fov n = self.meta["psf_side_length"] wave = self.wavelength self._psf_object = aniso.AnalyticalScaoPsf(pixelSize=pixel_scale, N=n, wavelength=wave, nmRms=self.nmRms) if np.any(self.meta["offset"]): self._psf_object.shift_off_axis(self.meta["offset"][0], self.meta["offset"][1]) self._kernel = self._psf_object.psf_latest self._kernel /= np.sum(self._kernel) if self.meta["rounded_edges"]: self._kernel = pu.round_kernel_edges(self._kernel) return self._kernel
def make_standard_scao_constpsf(): waves = [1.2, 1.6, 2.15] psfs = [] for wave in waves: psf = aniso.AnalyticalScaoPsf(pixelSize=0.004, N=256, wavelength=wave) psf.shift_off_axis(0, 5) psfs += [psf.hdu] keys = {"AUTHOR" : "Kieran Leschinski", "DATE_CRE" : "2019-07-30", "DATE_MOD" : "2019-07-30", "SOURCE" : "AnisoCADO", "STATUS" : "Best guess for a standard observations", "ETYPE" : "CONSTPSF", "ECAT" : (-1, "Field constant. No layer catalogue"), "EDATA" : (1, "PSFs begin from EXT 1"), "XOFFSET": (0, "[arcsec] offset from NGS"), "YOFFSET": (5, "[arcsec] offset from NGS"), } pri = fits.PrimaryHDU() pri.header.update(keys) hdus = fits.HDUList([pri] + psfs) hdus.writeto("SCAO_ConstPSF_5off.fits", clobber=True) print(hdus.info())
def make_psf( psf_wavelength: float = 2.15, shift: Tuple[int] = (0, 14), N: int = 511, transform: Callable[[np.ndarray], np.ndarray] = lambda x: x ) -> scopesim.effects.Effect: """ create a psf effect for scopesim to be as close as possible to how an anisocado PSF is used in simcado :param psf_wavelength: :param shift: :param N: ? Size of kernel? :param transform: function to apply to the psf array :return: effect object you can plug into OpticalTrain """ hdus = anisocado.misc.make_simcado_psf_file([shift], [psf_wavelength], pixelSize=pixel_scale.value, N=N) image = hdus[2] image.data = np.squeeze( image.data ) # remove leading dimension, we're only looking at a single picture, not a stack # re-sample to shift center actual_center = np.array(centroid_quadratic(image.data, fit_boxsize=5)) expected_center = np.array(center_of_image(image.data)) xshift, yshift = expected_center - actual_center resampled = upsample_image(image.data, xshift=xshift, yshift=yshift).real image.data = resampled image.data = transform(image.data) filename = tempfile.NamedTemporaryFile('w', suffix='.fits').name image.writeto(filename) # noinspection PyTypeChecker tmp_psf = anisocado.AnalyticalScaoPsf(N=N, wavelength=psf_wavelength) strehl = tmp_psf.strehl_ratio # Todo: passing a filename that does not end in .fits causes a weird parsing error return scopesim.effects.FieldConstantPSF( name=Config.instance().psf_name, filename=filename, wavelength=psf_wavelength, psf_side_length=N, strehl_ratio=strehl, )
model = make_anisocado_model() like = likelyhood(detections, model) y, x = np.indices(detections.shape) plt.figure() model.x_0 = 15 plt.imshow(like) # %% # %% # %% import anisocado psf = anisocado.AnalyticalScaoPsf() img = psf.psf_latest # %% # %% Ns = np.logspace(2, 8, 1000) plt.figure() plt.loglog(Ns, [psf_to_sigma(img, N, 10, 0) for N in Ns]) plt.loglog(Ns, [psf_to_sigma(img, N, 5, 0) for N in Ns]) plt.loglog(Ns, [psf_to_sigma(img, N, 2, 0) for N in Ns]) plt.loglog(Ns, [psf_to_sigma(img, N, 0, 0) for N in Ns]) plt.loglog(Ns, [psf_to_sigma_d(img, N, 10, 0) for N in Ns]) plt.loglog(Ns, [psf_to_sigma_d(img, N, 5, 0) for N in Ns]) plt.loglog(Ns, [psf_to_sigma_d(img, N, 2, 0) for N in Ns]) plt.loglog(Ns, [psf_to_sigma_d(img, N, 0, 0) for N in Ns])
pixelSize=pixel_scale, N=half_length) image = hdus[2] image.data = np.squeeze( image.data ) # remove leading dimension, we're only looking at a single picture, not a stack x, y = image.data.shape #TODO psf array is offset by one, hence need the -1 after coordinates? image.data = image.data * Gaussian2D(x_stddev=5, y_stddev=5)( *np.mgrid[-x / 2:x / 2:x * 1j, -y / 2:y / 2:y * 1j] - 1) filename = tempfile.NamedTemporaryFile('w', suffix='.fits').name image.writeto(filename) tmp_psf = anisocado.AnalyticalScaoPsf(N=half_length, wavelength=psf_wavelength) strehl = tmp_psf.strehl_ratio # Todo: passing a filename that does not end in .fits causes a weird parsing error psf_effect = scopesim.effects.FieldConstantPSF( name='mypsf.fits', filename=filename, wavelength=psf_wavelength, psf_side_length=half_length, strehl_ratio=strehl, ) N1d = 30 N = N1d**2 spectral_types = ['A0V'] * N border = 32