def test_compound_fitting_with_units(): x = np.linspace(-5, 5, 15) * u.Angstrom y = np.linspace(-5, 5, 15) * u.Angstrom fitter = fitting.LevMarLSQFitter() m = models.Gaussian2D(10*u.Hz, 3*u.Angstrom, 4*u.Angstrom, 1*u.Angstrom, 2*u.Angstrom) p = models.Planar2D(3*u.Hz/u.Angstrom, 4*u.Hz/u.Angstrom, 1*u.Hz) model = m + p z = model(x, y) res = fitter(model, x, y, z) assert isinstance(res(x, y), np.ndarray) assert all([res[i]._has_units for i in range(2)]) model = models.Gaussian2D() + models.Planar2D() res = fitter(model, x, y, z) assert isinstance(res(x, y), np.ndarray) assert all([res[i]._has_units for i in range(2)]) # A case of a mixture of models with and without units model = models.BlackBody(temperature=3000 * u.K) * models.Const1D(amplitude=1.0) x = np.linspace(1, 3, 10000) * u.micron with NumpyRNGContext(12345): n = np.random.normal(3) y = model(x) res = fitter(model, x, y * (1 + n)) # The large rtol here is due to different results on linux and macosx, likely # the model is ill-conditioned. np.testing.assert_allclose(res.parameters, [3000, 2.1433621e+00, 2.647347e+00], rtol=0.4)
def fit_background(image, model=models.Planar2D(), sigma=3.0): """ Fit sigma clipped background image using a user provided model. Parameters ---------- image : array 2D array to fit. model : `~astropy.modeling.FittableModel` AstroPy model to sample from. `Planar2D` is used by default. sigma : float or None The sigma value used to determine noise pixels. Once the pixels above this value are masked, the model provided is fit to determine the background. Returns ------- fitted_model, fitter * fitted_model : `~astropy.modeling.FittableModel` A copy of the input model with parameters set by the fitter. * fitter : LevMarLSQFitter Fitter used to estimate and set model parameters. """ fit_bg_image = image if sigma is not None: fit_bg_image = sigma_clip(image, sigma) return fit_model(fit_bg_image, model)
def test_compound_fitting_with_units(): x = np.linspace(-5, 5, 15) * u.Angstrom y = np.linspace(-5, 5, 15) * u.Angstrom fitter = fitting.LevMarLSQFitter() m = models.Gaussian2D(10 * u.Hz, 3 * u.Angstrom, 4 * u.Angstrom, 1 * u.Angstrom, 2 * u.Angstrom) p = models.Planar2D(3 * u.Hz / u.Angstrom, 4 * u.Hz / u.Angstrom, 1 * u.Hz) model = m + p z = model(x, y) res = fitter(model, x, y, z) assert isinstance(res(x, y), np.ndarray) assert all([res[i]._has_units for i in range(2)]) model = models.Gaussian2D() + models.Planar2D() res = fitter(model, x, y, z) assert isinstance(res(x, y), np.ndarray) assert all([res[i]._has_units for i in range(2)])
def test_render_model_out_dtype(): """Test different out.dtype for model.render.""" for model in [models.Gaussian2D(), models.Gaussian2D() + models.Planar2D()]: for dtype in [np.float64, np.float32, np.complex64]: im = np.zeros((40, 40), dtype=dtype) imout = model.render(out=im) assert imout is im assert imout.sum() != 0 with pytest.raises(TypeError): im = np.zeros((40, 40), dtype=np.int32) imout = model.render(out=im)
def fit_plane(image, maxiter=5000, epsilon=1e-10): model = models.Planar2D(slope_x=0., slope_y=0, intercept=0) + models.Const2D(0) # Make x and y grid to fit to y_arange, x_arange = np.where(~(np.isnan(image))) z = image[(y_arange, x_arange)] # Fit model to grid fit = fitting.LevMarLSQFitter() # fitting.LinearLSQFitter() fitted_line = fit(model, x_arange, y_arange, z, maxiter=5000, epsilon=1e-10) return fitted_line, fit
astmodels.Disk2D(amplitude=10., x_0=0.5, y_0=1.5, R_0=5.), astmodels.Ellipse2D(amplitude=10., x_0=0.5, y_0=1.5, a=2., b=4., theta=0.1), astmodels.Exponential1D(amplitude=10., tau=3.5), astmodels.Gaussian1D(amplitude=10., mean=5., stddev=3.), astmodels.Gaussian2D(amplitude=10., x_mean=5., y_mean=5., x_stddev=3., y_stddev=3.), astmodels.KingProjectedAnalytic1D(amplitude=10., r_core=5., r_tide=2.), astmodels.Logarithmic1D(amplitude=10., tau=3.5), astmodels.Lorentz1D(amplitude=10., x_0=0.5, fwhm=2.5), astmodels.Moffat1D(amplitude=10., x_0=0.5, gamma=1.2, alpha=2.5), astmodels.Moffat2D(amplitude=10., x_0=0.5, y_0=1.5, gamma=1.2, alpha=2.5), astmodels.Planar2D(slope_x=0.5, slope_y=1.2, intercept=2.5), astmodels.RedshiftScaleFactor(z=2.5), astmodels.RickerWavelet1D(amplitude=10., x_0=0.5, sigma=1.2), astmodels.RickerWavelet2D(amplitude=10., x_0=0.5, y_0=1.5, sigma=1.2), astmodels.Ring2D(amplitude=10., x_0=0.5, y_0=1.5, r_in=5., width=10.), astmodels.Sersic1D(amplitude=10., r_eff=1., n=4.), astmodels.Sersic2D(amplitude=10., r_eff=1., n=4., x_0=0.5, y_0=1.5, ellip=0.0, theta=0.0), astmodels.Sine1D(amplitude=10., frequency=0.5, phase=1.), astmodels.Cosine1D(amplitude=10., frequency=0.5, phase=1.), astmodels.Tangent1D(amplitude=10., frequency=0.5, phase=1.),
def autocorrelation_fit(im2, rough_sep = 44.93, rough_pa=0., cutout_sz=5, background_subtracted=False, plot_cutout=False, plot_resids=False): """ Fits to the distance of the second peak in the autocorrelation (i.e. the binary separation). This will perform a Levenberg-Marquardt fit over a small, fixed region around the peak. The model used for the fit will depend on the options set. rough_sep, rough_pa: Defaults 44.93 pixels and 0 degrees These define the position of the region used for the fit. cutout_sz: Default 5 pixels The radius of the box used for the fit. background_subtracted: Default False If True, the model used for the fit will be an Airy Disk + constant background. If False, the model will be a Gaussian + planar background. These seemed to work best. """ rough_pos = np.round([rough_sep*np.sin(rough_pa),rough_sep*np.cos(rough_pa)]).astype(int) calc_pos = [rough_sep*np.sin(rough_pa),rough_sep*np.cos(rough_pa)] cutout = np.copy(im2[im2.shape[0]//2+rough_pos[0]-cutout_sz:im2.shape[0]//2+rough_pos[0]+cutout_sz, im2.shape[1]//2+rough_pos[1]-cutout_sz:im2.shape[1]//2+rough_pos[1]+cutout_sz]) cutout /= np.max(cutout) if plot_cutout: plt.imshow(cutout) x,y = np.indices(cutout.shape) x = x + rough_pos[0] - cutout_sz y = y + rough_pos[1] - cutout_sz # Fit a Gaussian fit = fitting.LevMarLSQFitter() if background_subtracted: gauss = models.AiryDisk2D(amplitude=cutout.max(),x_0=calc_pos[0],y_0=calc_pos[1],radius=3.54) bckgd = models.Const2D(amplitude=0.6) else: gauss = models.Gaussian2D(amplitude = cutout.max(),x_stddev=1.36,y_stddev=1.36, x_mean=calc_pos[0],y_mean=calc_pos[1]) bckgd = models.Planar2D(slope_x = -0.00564816,slope_y=-0.02378304,intercept=1.01) gauss.fixed['theta']=True cutout_model = gauss + bckgd # fit the data with the fitter fitted_model = fit(cutout_model,x,y,cutout,maxiter=100000,acc=1e-7); # Rename the parameters so the output looks the same if background_subtracted: fitted_model.x_mean_0 = fitted_model.x_0_0 fitted_model.y_mean_0 = fitted_model.y_0_0 if plot_resids: test = fitted_model(x,y) plt.figure(figsize=(12,4)) plt.clf() plt.subplot(131) plt.imshow(cutout,origin='lowerleft',vmin=0.7,vmax=1);plt.colorbar() plt.subplot(132) plt.imshow(test,origin='lowerleft',vmin=0.7,vmax=1);plt.colorbar() plt.subplot(133) plt.imshow(cutout-test,origin='lowerleft',vmin=-0.05,vmax=0.05);plt.colorbar() return fitted_model