def test_anisocado_model_centered(anisocado_model): data = anisocado_model.render() actual = centroid_quadratic(data) expected = center_of_image(data) assert np.all(np.abs(np.array(actual) - np.array(expected)) < 1e-8)
def test_anisocado_psf_even(psf_effect_even): data = psf_effect_even.data actual = centroid_quadratic(data, fit_boxsize=6) expected = center_of_image(data) # TODO ideally this should be a lot tighter, but honestly even arrays are probably bad anyway # TODO does this work wih <0.001 on different computer? assert np.all(np.abs(np.array(actual) - np.array(expected)) < 0.05)
def test_single_star_image(single_star): img, table = single_star xcenter, ycenter = center_of_image(img) xcentroid, ycentroid = centroid_quadratic(img, fit_boxsize=5) xref, yref = table[INPUT_TABLE_NAMES[X]][0], table[INPUT_TABLE_NAMES[Y]][0] assert np.abs(xref-xcentroid) < 0.005 assert np.abs(yref-ycentroid) < 0.005
def cumulative_flux(img, oversampling=1): extent = np.min(img.shape)/2 rs = np.linspace(1, extent, int(extent*oversampling)) xcenter, ycenter = centroid_quadratic(img) apertures = [CircularAperture((xcenter, ycenter), r=r) for r in rs] tab = aperture_photometry(img, apertures, method='exact') # every aperture has it's own column; exclude first three (id,x,y) cumulative_flux = rf.structured_to_unstructured(tab.as_array()).ravel()[3:] return rs, cumulative_flux
def make_anisocado_model(*, oversampling=2, degree=5, seed=0, offaxis=(0, 14), lowpass=0): img = AnalyticalScaoPsf(pixelSize=0.004 / oversampling, N=400 * oversampling + 1, seed=seed).shift_off_axis(*offaxis) if lowpass != 0: y, x = np.indices(img.shape) # find center of PSF image x_mean, y_mean = centroid_quadratic(img, fit_boxsize=5) img = img * Gaussian2D(x_mean=x_mean, y_mean=y_mean, x_stddev=lowpass * oversampling, y_stddev=lowpass * oversampling)(x, y) img /= np.sum(img) origin = centroid_quadratic(img, fit_boxsize=5) return AnisocadoModel(img, oversampling=oversampling, degree=degree, origin=origin)
def psf_radial_reduce(img, reduction: Callable[[np.ndarray], float] = np.mean): # get center of image. xcenter, ycenter = centroid_quadratic(img) # last radius in pixel where ring is fully in image extent = np.min(img.shape)/2 radii = np.linspace(0.1, extent, int(extent)) values = [] for r_in, r_out in zip(radii, radii[1:]): aper = CircularAnnulus([xcenter, ycenter], r_in, r_out) mask = aper.to_mask('center') values.append(reduction(mask.get_values(img))) return radii[:-1], np.array(values)/np.max(img)
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, )
fitshape = 41 epsf_stars = extract_stars(NDData(img_grid), epsf_sources[:100], size=(fitshape + 2, fitshape + 2)) builder = EPSFBuilder(oversampling=4, smoothing_kernel=make_gauss_kernel(2.3, N=21), maxiters=5) pre_epsf, _ = cached(lambda: builder.build_epsf(epsf_stars), cache_dir / 'epsf_synthetic', rerun=False) data = pre_epsf.data[9:-9, 9:-9].copy() data /= np.sum(data) / np.sum(pre_epsf.oversampling) epsf = FittableImageModel(data=data, oversampling=pre_epsf.oversampling) epsf.origin = centroid_quadratic(epsf.data) def grid_photometry_epsf(): fit_stages_grid = [ FitStage(5, 1e-10, 1e-11, np.inf, all_individual), # first stage: get flux approximately right FitStage(5, 0.6, 0.6, 10, all_individual), FitStage(5, 0.3, 0.3, 500_000, all_individual), #FitStage(30, 0.1, 0.1, 5_000, all_simultaneous) ] photometry_grid = IncrementalFitPhotometry(SExtractorBackground(), anisocado_psf, max_group_size=1, group_extension_radius=10,
def test_anisocado_psf_odd(psf_effect_odd): data = psf_effect_odd.data actual = centroid_quadratic(data) expected = center_of_image(data) assert np.all(np.abs(np.array(actual) - np.array(expected)) < 1e-8)
plot_dev_vs_mag(flux, eucdev) save_plot(out_dir, 'naco_noisefloor') plot_dev_vs_mag(flux_unpert, eucdev_unpert) save_plot(out_dir, 'naco_noisefloor_unpert') # %% [markdown] # # Just debugging below # %% from photutils.centroids import centroid_quadratic from thesis_lib.util import center_of_index initial_epsf_adapted = FittableImageModel( initial_epsf.data, oversampling=initial_epsf.oversampling) print(centroid_quadratic(initial_epsf_adapted.data)) interp = initial_epsf_adapted.interpolator(np.arange(initial_epsf_adapted.nx), np.arange(initial_epsf_adapted.ny)) print(centroid_quadratic(interp)) print(center_of_index((initial_epsf_adapted.data.shape))) np.max(initial_epsf_adapted.data - interp) # %% y, x = [i.flatten() for i in np.mgrid[-10:10:100j, -10:10:100j]] y, x = np.random.uniform(-2, 2, (2, 250, 250)) y = y.flatten() x = x.flatten() plt.figure() plt.plot(*log_squish(x, y, exp=3), 'x') # %%