def test_returns_array_with_single_kernel_from_fov(self, waves, max_pixel): constpsf = FieldConstantPSF(filename="test_ConstPSF.fits") fov = _centre_fov(n=10, waverange=waves) kernel = constpsf.get_kernel(fov) assert np.sum(kernel) == approx(1) assert np.max(kernel) == approx(max_pixel)
def test_convolution_leaves_constant_background_intact(self): """FOV object with constant data must be unchanged by PSF convolution 1. Set up initial FOV object with constant data array 2. Convolve with PSF 3. Assert that convolved array is identical to initial array. """ centre_fov = _centre_fov(n=10, waverange=[1.1, 1.3]) nax1, nax2 = centre_fov.header["NAXIS1"], centre_fov.header["NAXIS2"] centre_fov.view() centre_fov.hdu.data = np.ones((nax2, nax1), dtype=np.float32) constpsf = FieldConstantPSF(filename="test_ConstPSF.fits") fov_returned = constpsf.apply_to(centre_fov) if PLOTS: fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(7, 3)) plot_A = ax1.imshow(centre_fov.hdu.data) ax1.set_title("before convolution") fig.colorbar(plot_A, ax=ax1) plot_B = ax2.imshow(fov_returned.hdu.data) ax2.set_title("after convolution") fig.colorbar(plot_B, ax=ax2) plt.show() assert np.all(np.equal(fov_returned.hdu.data, centre_fov.hdu.data))
def test_ADC_plot(self): atmo_params = { "airmass": 1.14, "temperature": 7, "humidity": 0.5, "pressure": 0.755, "latitude": -26, "altitude": 2400, "pupil_angle": 0, "pixel_scale": 1, "wave_min": 0.5, "wave_mid": 0.5, "wave_max": 2.5 } pixel_scale = 0.04 waves = (0.7, 0.8) adc = shifts.AtmosphericDispersionCorrection(**atmo_params) fov = _centre_fov(n=10, waverange=waves) fov.header["CDELT1"] = 1 / 3600 * pixel_scale fov.header["CDELT2"] = 1 / 3600 * pixel_scale old_crpix_d = np.array([fov.header["CRPIX1D"], fov.header["CRPIX2D"]]) adc.apply_to(fov) new_crpix_d = np.array([fov.header["CRPIX1D"], fov.header["CRPIX2D"]]) fov_shifts = new_crpix_d - old_crpix_d adc_x_shift = fov_shifts[0] * fov.header["CDELT1"] * 3600 adc_y_shift = fov_shifts[1] * fov.header["CDELT1"] * 3600 # Maybe create point sources and see them shift if PLOTS: print(fov_shifts)
def test_shifts_between_adc_and_ad_are_opposite(self, atmo_params, waves, angle, pixel_scale): fov_wave_mid = np.average(waves) atmo_params["pixel_scale"] = pixel_scale atmo_params["pupil_angle"] = angle atmo_params["sub_pixel_fraction"] = 0.001 fov = _centre_fov(n=10, waverange=waves) fov.hdu.header["CDELT1"] = 1 / 3600 * pixel_scale fov.hdu.header["CDELT2"] = 1 / 3600 * pixel_scale old_crpix_d = np.array([fov.header["CRPIX1D"], fov.header["CRPIX2D"]]) ad = AD(**atmo_params) adc = ADC(**atmo_params) ad_shifts = ad.fov_grid() ad_x_shift = np.interp(fov_wave_mid, ad_shifts[0], ad_shifts[1]) ad_y_shift = np.interp(fov_wave_mid, ad_shifts[0], ad_shifts[2]) adc.apply_to(fov) new_crpix_d = np.array([fov.header["CRPIX1D"], fov.header["CRPIX2D"]]) fov_shifts = new_crpix_d - old_crpix_d adc_x_shift = fov_shifts[0] * fov.header["CDELT1"] * 3600 adc_y_shift = fov_shifts[1] * fov.header["CDELT1"] * 3600 assert adc_x_shift == approx(ad_x_shift, rel=1e-3) assert adc_y_shift == approx(ad_y_shift, rel=1e-3)
def test_zero_shift_at_zenith(self, atmo_params): fov = _centre_fov(n=50, waverange=[1.5, 1.7]) old_crpix_d = fov.header["CRPIX1D"], fov.header["CRPIX2D"] atmo_params["airmass"] = 1. adc = ADC(**atmo_params) fov_new = adc.apply_to(fov) new_crpix_d = fov_new.header["CRPIX1D"], fov_new.header["CRPIX2D"] assert np.all(old_crpix_d == new_crpix_d)
def test_kernel_is_scale_properly_if_cdelts_differ(self, factor): fov = _centre_fov(n=10, waverange=[1.5, 1.7]) fov.header["CDELT1"] *= factor fov.header["CDELT2"] *= factor constpsf = FieldConstantPSF(filename="test_ConstPSF.fits") kernel = constpsf.get_kernel(fov) psf_shape = np.array(constpsf._file[2].data.shape) kernel_shape = kernel.shape assert np.all(kernel_shape == psf_shape / factor)
def test_kernel_is_scale_properly_if_cdelts_differ(self, factor): fov = _centre_fov(n=10) fov.header["CDELT1"] *= factor fov.header["CDELT2"] *= factor fvpsf = FieldVaryingPSF(filename="test_FVPSF.fits") kernels = fvpsf.get_kernel(fov) psf_shape = np.array(fvpsf._file[2].data[0].shape) kernel_shape = kernels[0][0].shape assert all(kernel_shape == psf_shape * factor)
def test_convolves_with_basic_fov_for_each_waveleng(self, waves, max_pixel): centre_fov = _centre_fov(n=10, waverange=waves) nax1, nax2 = centre_fov.header["NAXIS1"], centre_fov.header["NAXIS2"] centre_fov.hdu.data = np.zeros((nax2, nax1)) centre_fov.hdu.data[1::4, 1::4] = 1 constpsf = FieldConstantPSF(filename="test_ConstPSF.fits") fov_returned = constpsf.apply_to(centre_fov) if PLOTS: plt.imshow(fov_returned.hdu.data, origin="lower") plt.show() assert np.max(fov_returned.hdu.data) == approx(max_pixel)
def test_correct_test_shift_applied_to_image_plane_wcs( self, atmo_params, waves, offset): fov = _centre_fov(n=10, waverange=waves) old_crpix_d = fov.header["CRPIX1D"], fov.header["CRPIX2D"] adc = ADC(**atmo_params) fov_new = adc.apply_to(fov) new_crpix_d = fov_new.header["CRPIX1D"], fov_new.header["CRPIX2D"] abs_diff = np.sum( (np.array(new_crpix_d) - np.array(old_crpix_d))**2)**0.5 # this works because the pixel_scale is 1 arcsec assert abs_diff == approx(offset, rel=1e-3) assert new_crpix_d[1] == approx(old_crpix_d[1] - offset, rel=1e-3)
def test_returns_four_arrays_when_fov_on_intersection(self): fov = _centre_fov(n=20) fov.header["CRVAL1"] -= 15/3600. fov.header["CRVAL2"] -= 15/3600. fvpsf = FieldVaryingPSF(filename="test_FVPSF.fits") kernels = fvpsf.get_kernel(fov) assert len(kernels) == 4 if PLOTS: for ii, kernel_mask in enumerate(kernels): plt.subplot(2, 4, ii+1) plt.imshow(kernel_mask[0].T, origin="lower") plt.subplot(2, 4, ii+5) plt.imshow(kernel_mask[1].T, origin="lower") plt.show()
def test_returns_correct_section_of_strehl_map(self, scale): centre_fov = _centre_fov(10) centre_fov.header["CDELT1"] *= scale centre_fov.header["CDELT2"] *= scale centre_fov.header["CRVAL1"] -= 15/3600. centre_fov.header["CRVAL2"] -= 15/3600. fvpsf = FieldVaryingPSF(filename="test_FVPSF.fits") strehl_hdu = scopesim.effects.psf_utils.get_strehl_cutout(centre_fov.header, fvpsf.strehl_imagehdu) if PLOTS: plt.imshow(strehl_hdu.data, origin="lower") plt.colorbar() plt.show() assert all(np.unique(strehl_hdu.data).astype(int) == [0, 1, 3, 4])
def test_circular_fvpsf(self, basic_circular_fvpsf): centre_fov = _centre_fov(n=62) nax1, nax2 = centre_fov.header["NAXIS1"], centre_fov.header["NAXIS2"] centre_fov.hdu.data = np.zeros((nax2, nax1)) x, y = np.random.randint(6, nax1-6, (2, 150)) centre_fov.hdu.data[x, y] = 1 # centre_fov.hdu.data[6:nax1-6:10, 6:nax1-6:10] = 1 centre_fov.fields = [1] sum_orig = np.sum(centre_fov.hdu.data) fvpsf = FieldVaryingPSF(filename="test_circular_fvpsf.fits") fov_back = fvpsf.apply_to(centre_fov) if PLOTS: plt.imshow(fov_back.hdu.data, origin="lower", vmax=0.1) plt.show() # print(np.sum(fov_back.hdu.data), sum_orig) assert np.sum(fov_back.hdu.data) == approx(sum_orig, rel=1E-2)
def centre_fov(): return _centre_fov()
def test_returns_array_with_single_kernel_from_fov(self): fvpsf = FieldVaryingPSF(filename="test_FVPSF.fits") kernels = fvpsf.get_kernel(_centre_fov(n=10)) assert np.all(kernels[0][0] == fvpsf._file[2].data[4]) assert kernels[0][1] is None
def centre_fov(): fov = _centre_fov() fov.view() return fov