def test_fix_inputs_compound_bounding_box(): base_model = models.Gaussian2D(1, 2, 3, 4, 5) bbox = {2.5: (-1, 1), 3.14: (-7, 3)} model = fix_inputs(base_model, {'y': 2.5}, bounding_boxes=bbox) assert model.bounding_box == (-1, 1) model = fix_inputs(base_model, {'x': 2.5}, bounding_boxes=bbox) assert model.bounding_box == (-1, 1) model = fix_inputs(base_model, {'y': 2.5}, bounding_boxes=bbox, selector_args=(('y', True), )) assert model.bounding_box == (-1, 1) model = fix_inputs(base_model, {'x': 2.5}, bounding_boxes=bbox, selector_args=(('x', True), )) assert model.bounding_box == (-1, 1) model = fix_inputs(base_model, {'x': 2.5}, bounding_boxes=bbox, selector_args=((0, True), )) assert model.bounding_box == (-1, 1) base_model = models.Identity(4) bbox = {(2.5, 1.3): ((-1, 1), (-3, 3)), (2.5, 2.71): ((-3, 3), (-1, 1))} model = fix_inputs(base_model, {'x0': 2.5, 'x1': 1.3}, bounding_boxes=bbox) assert model.bounding_box == ((-1, 1), (-3, 3)) model = fix_inputs(base_model, { 'x0': 2.5, 'x1': 1.3 }, bounding_boxes=bbox, selector_args=(('x0', True), ('x1', True))) assert model.bounding_box == ((-1, 1), (-3, 3)) model = fix_inputs(base_model, { 'x0': 2.5, 'x1': 1.3 }, bounding_boxes=bbox, selector_args=((0, True), (1, True))) assert model.bounding_box == ((-1, 1), (-3, 3))
def test_with_fitters_and_sigma_clip(self): import scipy.stats as stats np.random.seed(0) c = stats.bernoulli.rvs(0.25, size=self.z.shape) self.z += (np.random.normal(0., 0.2, self.z.shape) + c * np.random.normal(self.z, 2.0, self.z.shape)) guess = self.initial_guess(self.z, np.array([self.y, self.x])) g2_init = models.Gaussian2D(amplitude=guess[0], x_mean=guess[1], y_mean=guess[2], x_stddev=0.75, y_stddev=1.25) # test with Levenberg-Marquardt Least Squares fitter fit = FittingWithOutlierRemoval(LevMarLSQFitter(), sigma_clip, niter=3, sigma=3.) fitted_model, _ = fit(g2_init, self.x, self.y, self.z) assert_allclose(fitted_model.parameters[0:5], self.model_params, atol=1e-1) # test with Sequential Least Squares Programming fitter fit = FittingWithOutlierRemoval(SLSQPLSQFitter(), sigma_clip, niter=3, sigma=3.) fitted_model, _ = fit(g2_init, self.x, self.y, self.z) assert_allclose(fitted_model.parameters[0:5], self.model_params, atol=1e-1) # test with Simplex LSQ fitter fit = FittingWithOutlierRemoval(SimplexLSQFitter(), sigma_clip, niter=3, sigma=3.) fitted_model, _ = fit(g2_init, self.x, self.y, self.z) assert_allclose(fitted_model.parameters[0:5], self.model_params, atol=1e-1)
def test_2d_model(): # 2D model with LevMarLSQFitter gauss2d = models.Gaussian2D(10.2, 4.3, 5, 2, 1.2, 1.4) fitter = fitting.LevMarLSQFitter() X = np.linspace(-1, 7, 200) Y = np.linspace(-1, 7, 200) x, y = np.meshgrid(X, Y) z = gauss2d(x, y) w = np.ones(x.size) w.shape = x.shape from astropy.utils import NumpyRNGContext with NumpyRNGContext(1234567890): n = np.random.randn(x.size) n.shape = x.shape m = fitter(gauss2d, x, y, z + 2 * n, weights=w) assert_allclose(m.parameters, gauss2d.parameters, rtol=0.05) m = fitter(gauss2d, x, y, z + 2 * n, weights=None) assert_allclose(m.parameters, gauss2d.parameters, rtol=0.05) # 2D model with LevMarLSQFitter, fixed constraint gauss2d.x_stddev.fixed = True m = fitter(gauss2d, x, y, z + 2 * n, weights=w) assert_allclose(m.parameters, gauss2d.parameters, rtol=0.05) m = fitter(gauss2d, x, y, z + 2 * n, weights=None) assert_allclose(m.parameters, gauss2d.parameters, rtol=0.05) # Polynomial2D, col_fit_deriv=False p2 = models.Polynomial2D(1, c0_0=1, c1_0=1.2, c0_1=3.2) z = p2(x, y) m = fitter(p2, x, y, z + 2 * n, weights=None) assert_allclose(m.parameters, p2.parameters, rtol=0.05) m = fitter(p2, x, y, z + 2 * n, weights=w) assert_allclose(m.parameters, p2.parameters, rtol=0.05) # Polynomial2D, col_fit_deriv=False, fixed constraint p2.c1_0.fixed = True m = fitter(p2, x, y, z + 2 * n, weights=w) assert_allclose(m.parameters, p2.parameters, rtol=0.05) m = fitter(p2, x, y, z + 2 * n, weights=None) assert_allclose(m.parameters, p2.parameters, rtol=0.05)
def corr_shift_determination(corr): #Measure shift between the check and master images by fitting a 2D gaussian to corr. This gives sub-pixel accuracy. y_max, x_max = np.unravel_index( np.argmax(corr), corr.shape ) #Find the pixel with highest correlation, then use this as estimate for gaussian fit. y, x = np.mgrid[y_max - 10:y_max + 10, x_max - 10:x_max + 10] try: corr_cut = corr[y, x] gaussian_init = models.Gaussian2D(np.max(corr_cut), x_max, y_max, 8 / 2.355, 8 / 2.355, 0) fit_gauss = fitting.LevMarLSQFitter() gaussian = fit_gauss(gaussian_init, x, y, corr_cut) fit_x = gaussian.x_mean.value fit_y = gaussian.y_mean.value x_shift = fit_x - 512 y_shift = 512 - fit_y return (x_shift, y_shift) except: print('Problem with corr indexing, returning 0 shifts.') return (0, 0)
def test_with_fitters_and_sigma_clip(self, fitter): import scipy.stats as stats fitter = fitter() np.random.seed(0) c = stats.bernoulli.rvs(0.25, size=self.z.shape) z = self.z + (np.random.normal(0., 0.2, self.z.shape) + c*np.random.normal(self.z, 2.0, self.z.shape)) guess = self.initial_guess(self.z, np.array([self.y, self.x])) g2_init = models.Gaussian2D(amplitude=guess[0], x_mean=guess[1], y_mean=guess[2], x_stddev=0.75, y_stddev=1.25) fit = FittingWithOutlierRemoval(fitter, sigma_clip, niter=3, sigma=3.) fitted_model, _ = fit(g2_init, self.x, self.y, z) assert_allclose(fitted_model.parameters[0:5], self.model_params, atol=1e-1)
def test_print_special_operator_CompoundModel(capsys): """ Test that issue #11310 has been fixed """ model = convolve_models(models.Sersic2D(), models.Gaussian2D()) with astropy.conf.set_temp('max_width', 80): assert str(model) == "Model: CompoundModel\n" +\ "Inputs: ('x', 'y')\n" +\ "Outputs: ('z',)\n" +\ "Model set size: 1\n" +\ "Expression: convolve_fft (([0]), ([1]))\n" +\ "Components: \n" +\ " [0]: <Sersic2D(amplitude=1., r_eff=1., n=4., x_0=0., y_0=0., ellip=0., theta=0.)>\n" +\ "\n" +\ " [1]: <Gaussian2D(amplitude=1., x_mean=0., y_mean=0., x_stddev=1., y_stddev=1., theta=0.)>\n" +\ "Parameters:\n" +\ " amplitude_0 r_eff_0 n_0 x_0_0 y_0_0 ... y_mean_1 x_stddev_1 y_stddev_1 theta_1\n" +\ " ----------- ------- --- ----- ----- ... -------- ---------- ---------- -------\n" +\ " 1.0 1.0 4.0 0.0 0.0 ... 0.0 1.0 1.0 0.0"
def lp(p,data,error,fixp,guess,pixsize,types): '''Log probability for 2D Gaussian models INPUT: p - parameter array of floats consisting of [amp, x, y, bmaj(fwhm), bmin(fwhm), bpa] (units mJy, pix, pix, arcsec, arcsec, deg) data - 2D fits image (array) error - 2D fits image variance (array) fixp - boolean array indicating which parameters are fixed in fit; same dimensions as p guess - array of floats of initial guesses for parameters; same dimensions as p pixsize - pixel size in the image in arcsec (float) types - 'toti' or 'pol' (str) OUTPUT: log probability ''' amp,xx,yy,bmaj,bmin,bpa=p[0],p[1],p[2],p[3],p[4],p[5] mod0=models.Gaussian2D(amp,xx,yy,bmaj/(2.*pixsize),bmin/(2.*pixsize),bpa) xval=np.arange(0,len(data[0,:])) yval=np.arange(0,len(data[:,0])) Xval, Yval = np.meshgrid(xval, yval) mod1=mod0(Xval,Yval) re=-0.5*np.nansum(np.log(2*np.pi*error**2))-np.nansum((mod1-data)**2/(2*error**2)) prior=prior_func(p,fixp,guess,types) return(re+prior)
def guess_2d_gaussian(x, y, z, ok=None): ''' Make a guess to initialize the baseline + 2D Gaussian model, based on medians and weighted moments of the image. ''' if ok == None: ok = np.ones_like(z).astype(np.bool) # estimate a baseline flux, from the median of the good pixels baseline_guess = np.median(z[ok]) # do a *veyr* coarse subtraction, to focus on just the blob crudelysubtracted = np.maximum((z-baseline_guess), 0) amplitude_guess = np.sum(crudelysubtracted) def moment(q): ''' Take the weighted moment of a quantity. ''' return np.sum(q[ok]*crudelysubtracted[ok])/np.sum(crudelysubtracted[ok]) # calculate flux-weighted centroids of the blob x_guess = moment(x) y_guess = moment(y) # calculate flux-weighted widths of the blob x_width_guess = np.sqrt(moment((x - x_guess)**2)) y_width_guess = np.sqrt(moment((y - y_guess)**2)) # create an initial model, with the initial guesses initial = ( models.Const2D(amplitude=baseline_guess) + models.Gaussian2D(amplitude=amplitude_guess, x_mean=x_guess, y_mean=y_guess, x_stddev=x_width_guess, y_stddev=y_width_guess, theta=0.0)) return initial
def fit_2dgaussian(data, uncertainty=None, mask=None): """ Fit a 2D Gaussian to a 2D image. Parameters ---------- data : array_like or `~astropy.nddata.NDData` The 2D array of the image. uncertainty : array_like, optional The 2D array of the 1-sigma errors of the input ``data``. mask : array_like, bool, optional (Not yet implemented). A boolean mask with the same shape as ``data``, where a `True` value indicates the corresponding element of ``data`` is invalid. If ``mask`` is input it will override ``data.mask`` for `~astropy.nddata.NDData` inputs. Returns ------- centroid : tuple (x, y) coordinates of the centroid. """ if uncertainty is None: weights = None else: weights = 1.0 / uncertainty init_param = shape_params(data, mask=mask) init_amplitude = np.ptp(data) g_init = models.Gaussian2D(init_amplitude, init_param['xcen'], init_param['ycen'], init_param['major_axis'], init_param['minor_axis'], theta=init_param['angle']) fitter = LevMarLSQFitter() y, x = np.indices(data.shape) gfit = fitter(g_init, x, y, data, weights=weights) return gfit
def test_gaussian_fwhm_after_convolution(self): """Convolve a Gaussian image with a Gaussian kernel, and measure the sigma of the final image. A Gaussian convolved with a Gaussian is a Gaussian with a variance that is the sum of the two: http://www.tina-vision.net/docs/memos/2003-003.pdf """ nx, ny = 31, 61 fwhmi = 7 fwhmk = 5 factor = 5 x, y = testimage.xy_data(nx, ny) m = guassian_convolved_with_gaussian(nx, ny, amplitude=1.0, x0=None, y0=None, fwhmi=fwhmi, fwhmk=fwhmk, factor=factor) x, y = testimage.xy_data(nx, ny) # fit Gaussian2D to the convolved model g_init = models.Gaussian2D(amplitude=m.max(), x_mean=(ny - 1) / 2, y_mean=(nx - 1) / 2, x_stddev=fwhmi, y_stddev=fwhmi) fit_g = fitting.LevMarLSQFitter() g = fit_g(g_init, x, y, m) # calculate the the theoretical standard deviation for convolution # of two Gaussians in 1D. stddevi, stddevk = fwhmi / 2.35, fwhmk / 2.35 stddevt = np.sqrt(stddevi**2 + stddevk**2) # make sure that it is within 10% rel_dev = (g.x_stddev.value - stddevt) / stddevt return self.assertTrue(np.abs(rel_dev) < 0.1)
def single_source_side(): # Large shape to allow for psf fitting # as beam needs to be much smaller than the map at some point.. shape = (27, 27) pixsize = 1 / 3 data = np.zeros(shape) wcs = WCS() wcs.wcs.crpix = np.asarray(shape) / 2 - 0.5 # Center of pixel wcs.wcs.cdelt = np.asarray([-1, 1]) * pixsize wcs.wcs.ctype = ("RA---TAN", "DEC--TAN") fake_sources = Table(masked=True) fake_sources["fake_id"] = [1] fake_sources["x_mean"] = [0] fake_sources["y_mean"] = [13] ra, dec = wcs.wcs_pix2world(fake_sources["x_mean"], fake_sources["y_mean"], 0) fake_sources["ra"] = ra * u.deg fake_sources["dec"] = dec * u.deg fake_sources["_ra"] = fake_sources["ra"] fake_sources["_dec"] = fake_sources["dec"] xx, yy = np.indices(shape) stddev = 1 / pixsize * gaussian_fwhm_to_sigma g = models.Gaussian2D(1, fake_sources["y_mean"], fake_sources["x_mean"], stddev, stddev) data += g(xx, yy) nm = NikaMap(data, uncertainty=np.ones_like(data) / 4, wcs=wcs, unit=u.Jy / u.beam, fake_sources=fake_sources) nm.x = fake_sources["x_mean"] nm.y = fake_sources["y_mean"] return nm
def test_custom_bounding_box_1d(): """ Tests that the bounding_box setter works. """ # 1D models g1 = models.Gaussian1D() bb = g1.bounding_box expected = g1.render() # assign the same bounding_box, now through the bounding_box setter g1.bounding_box = bb assert_allclose(g1.render(), expected) # 2D models g2 = models.Gaussian2D() bb = g2.bounding_box expected = g2.render() # assign the same bounding_box, now through the bounding_box setter g2.bounding_box = bb assert_allclose(g2.render(), expected)
def fakeData(): """ Generate some fake data i.e. a 2D Gaussian with noise. """ #Create the coordinates x and y x = np.arange(0, 256) y = np.arange(0, 256) #Put the coordinates in a mesh xx, yy = np.meshgrid(x, y) #get Gaussian with fixed params model = models.Gaussian2D(50, 123, 135, 20, 35.5) zz = model.eval(xx, yy, 50, 123, 135, 20, 35.5, 0) #Flatten the arrays xx = xx.flatten() yy = yy.flatten() #add some noise to zz zz = zz.flatten() + np.random.normal(0.0, 2., len(xx)) sigma = np.ones(len(xx)) return xx, yy, zz, sigma
def hclean(dirtyim, psf, thresh, niter, lpgain, window=None): """ Hogbom CLEAN alogrithm :dirtyim: :psf: :thresh: :niter: :lpgain: :window: """ clmodel = np.zeros_like(dirtyim) res = np.copy(dirtyim) for n in range(niter): [mx, my] = np.unravel_index(np.fabs(res).argmax(), res.shape) clmodel[mx, my] += lpgain * res[mx, my] okxy, osxy = effregion(psf, res, mx, my) res[osxy[0]:osxy[1] + 1, osxy[2]:osxy[3] + 1] -= psf[okxy[0]:okxy[1] + 1, okxy[2]:okxy[3] + 1] * lpgain * res[mx, my] if (np.fabs(res).max() < thresh): break xg, yg = np.arange(-3, 4), np.arange(-3, 4) xpg, ypg = np.meshgrid(xg, yg) g_init = models.Gaussian2D(amplitude=1., x_mean=0, x_stddev=1., y_mean=0, y_stddev=1., theta=0) fitg = fitting.LevMarLSQFitter() g2d = fitg(g_init, xpg, ypg, psf) # Using 2-d Gaussian beam as clean beam to fit psf clbeam = g2d(xpg, ypg) clmap = signal.fftconvolve(clmodel, clbeam, 'same') return clmap, res
def astropy_Psf(N, FWHM): """Psf es una funcion que proporciona una matriz 2D con una gaussiana simétrica en ambos ejes. con N se especifica el tamaño en pixeles que necesitamos y con FWHM el ancho sigma de la gaussiana en pixeles %timeit simtools.astropy_Psf(128, 10) 1 loops, best of 3: 338 ms per loop """ psf = np.zeros((N, N)) mu = (N - 1) / 2. sigma = FWHM / 2.335 model = models.Gaussian2D(amplitude=1., x_mean=mu, y_mean=mu, x_stddev=sigma, y_stddev=sigma) tail_len = int(7 * sigma) mu_int = int(mu) i = range(mu_int - tail_len, mu_int + tail_len, 1) for ii, jj in cartesian_product([i, i]): psf[ii, jj] = model(ii, jj) return psf / np.sum(psf)
def test_render_model_2d(): imshape = (71, 141) image = np.zeros(imshape) coords = y, x = np.indices(imshape) model = models.Gaussian2D(x_stddev=6.1, y_stddev=3.9, theta=np.pi / 3) # test points for edges ye, xe = [0, 35, 70], [0, 70, 140] # test points for floating point positions yf, xf = [35.1, 35.5, 35.9], [70.1, 70.5, 70.9] test_pts = [(a, b) for a in xe for b in ye] test_pts += [(a, b) for a in xf for b in yf] for x0, y0 in test_pts: model.x_mean = x0 model.y_mean = y0 expected = model(x, y) for xy in [coords, None]: for im in [image.copy(), None]: if (im is None) & (xy is None): # this case is tested in Fittable2DModelTester continue actual = model.render(out=im, coords=xy) if im is None: assert_allclose(actual, model.render(coords=xy)) # assert images match assert_allclose(expected, actual, atol=3e-7) # assert model fully captured if (x0, y0) == (70, 35): boxed = model.render() flux = np.sum(expected) assert ((flux - np.sum(boxed)) / flux) < 1e-7 # test an error is raised when the bounding box is larger than the input array try: actual = model.render(out=np.zeros((1, 1))) except ValueError: pass
def measure_fwhm(array): """Fit a Gaussian2D model to a PSF and return the FWHM Parameters ---------- array : numpy.ndarray Array containing PSF Returns ------- x_fwhm : float FWHM in x direction in units of pixels y_fwhm : float FWHM in y direction in units of pixels """ yp, xp = array.shape y, x, = np.mgrid[:yp, :xp] p_init = models.Gaussian2D() fit_p = fitting.LevMarLSQFitter() fitted_psf = fit_p(p_init, x, y, array) return fitted_psf.x_fwhm, fitted_psf.y_fwhm
def log_likelihood(theta, x, y, data, var, size): """ Logarithm of the likelihood function. """ #unpack the parameters peak, center_x, center_y, radius, focus, width_x, width_y = theta #1)Generate a model Airy disc amplitude = _amplitudeFromPeak(peak, center_x, center_y, radius, x_0=int(size[0] / 2. - 0.5), y_0=int(size[1] / 2. - 0.5)) airy = models.AiryDisk2D(amplitude, center_x, center_y, radius) adata = airy.eval(x, y, amplitude, center_x, center_y, radius).reshape(size) #2)Apply Focus f = models.Gaussian2D(1., center_x, center_y, focus, focus, 0.) focusdata = f.eval(x, y, 1., center_x, center_y, focus, focus, 0.).reshape(size) model = signal.convolve2d(adata, focusdata, mode='same') #3)Apply CCD diffusion, approximated with a Gaussian CCDdata = np.array( [[0.0, width_y, 0.0], [width_x, (1. - width_y - width_y - width_x - width_x), width_x], [0.0, width_y, 0.0]]) model = signal.convolve2d(model, CCDdata, mode='same').flatten() #true for Gaussian errors #lnL = - 0.5 * np.sum((data - model)**2 / var) #Gary B. said that this should be from the model not data so recompute var (now contains rn**2) var += model.copy() lnL = -(np.size(var) * np.sum(np.log(var))) - (0.5 * np.sum( (data - model)**2 / var)) return lnL
def fit_2D_gaussian(xmat, ymat, z): ''' Return fitted model parameters ''' g = astropy_models.Gaussian2D(x_mean=[0], y_mean=[0], x_stddev=[1], y_stddev=[1], amplitude=z.max(), theta=[0], fixed={'amplitude': True, 'x_mean': True, 'y_mean': True}) + \ astropy_models.Const2D(amplitude=[np.percentile(z, 10)]) fit_g = fitting.LevMarLSQFitter() output = fit_g(g, xmat, ymat, z) cov = fit_g.fit_info['param_cov'] if cov is None: warn("Fitting failed.") cov = np.zeros((4, 4)) * np.NaN return output, cov
def test_Gaussian2D(): """ Test rotated elliptical Gaussian2D model. https://github.com/astropy/astropy/pull/2038 """ model = models.Gaussian2D(4.2, 1.7, 3.1, x_stddev=5.1, y_stddev=3.3, theta=np.pi / 6.) y, x = np.mgrid[0:5, 0:5] g = model(x, y) g_ref = [[3.01907812, 2.99051889, 2.81271552, 2.5119566, 2.13012709], [3.55982239, 3.6086023, 3.4734158, 3.17454575, 2.75494838], [3.88059142, 4.0257528, 3.96554926, 3.70908389, 3.29410187], [3.91095768, 4.15212857, 4.18567526, 4.00652015, 3.64146544], [3.6440466, 3.95922417, 4.08454159, 4.00113878, 3.72161094]] assert_allclose(g, g_ref, rtol=0, atol=1e-6) assert_allclose([model.x_fwhm, model.y_fwhm], [12.009582229657841, 7.7709061486021325])
def FitGaussian(img, amp, stddev, center, theta=0, FWHM=False): if FWHM: stddev[:] = [x / 1.17741 / 2 for x in stddev] xy = np.where(img > 0) # Fit the data using astropy.modeling p_init = models.Gaussian2D(amplitude=amp, x_mean=center[1], y_mean=center[0], x_stddev=stddev[0], y_stddev=stddev[1], theta=np.radians(theta)) fit_p = fitting.LevMarLSQFitter() with warnings.catch_warnings(): # Ignore model linearity warning from the fitter warnings.simplefilter('ignore') p = fit_p(p_init, xy[0], xy[1], img[xy]) return p
def setup(self): # create temporary directory self.tmpdir_in = tempfile.TemporaryDirectory() # Create image data in_array = np.zeros([1, 1, 100, 100]) # Add noise np.random.seed(10) in_array += np.random.normal(0.0, 1e-5, [1, 1, 100, 100]) # Add a gaussian source to fit (otherwise QA code will fail) y, x = np.mgrid[:100, :100] gaus_mod = models.Gaussian2D(0.001, 50, 50, 2.5, 6, 0.6) gaus_data = gaus_mod(y, x) # Leave in extra axes as QA code will try to drop extra axes # inferred from the header in_array += gaus_data[np.newaxis, np.newaxis, :, :] hdu = fits.PrimaryHDU(in_array, header=fits.Header(HDR_KEYS)) # QA code expects a frequency axis hdu.header['CTYPE3'] = 'FREQ ' # Construct 4 targets target_names = ['Gunther Lord of the Gibichungs', 'Gutrune', 'Hagen', 'Gutrune'] self.metadata = _create_test_metadata(target_names) # Create input images per target self.dir_base = [] for f, t in zip(self.metadata['FITSImageFilename'], self.metadata['Targets']): pipe_dirname = os.path.join(self.tmpdir_in.name, '1234') # Expected base name of new directories containing QA products outDirName = pipe_dirname + '_' + t + '_' + self.metadata['Run'] self.dir_base.append(outDirName) os.mkdir(outDirName + '_PB.writing') file_base = os.path.splitext(f)[0] inFileName = os.path.join(outDirName + '_PB.writing', file_base + '_PB' + FITS_EXT) hdu.writeto(inFileName)
def guide_star_seeing(subframe): # subframe = subframe - np.median(subframe) subframe = subframe - np.percentile(subframe, 5) sub_frame_l = int(np.shape(subframe)[0]) y, x = np.mgrid[:sub_frame_l, :sub_frame_l] # gaussian_init = models.Gaussian2D(subframe[int(sub_frame_l/2),int(sub_frame_l/2)],int(sub_frame_l/2),int(sub_frame_l/2),8/2.355,8/2.355,0) # fit_gauss = fitting.LevMarLSQFitter() # gaussian = fit_gauss(gaussian_init, x, y, subframe) # fwhm_x = 2.355*gaussian.x_stddev.value # fwhm_y = 2.355*gaussian.y_stddev.value # Fit with constant, bounds, tied x and y sigmas and outlier rejection: gaussian_init = models.Const2D(0.0) + models.Gaussian2D( subframe[int(sub_frame_l / 2), int(sub_frame_l / 2)], int(sub_frame_l / 2), int(sub_frame_l / 2), 8 / 2.355, 8 / 2.355, 0) gaussian_init.x_stddev_1.min = 1.0 / 2.355 gaussian_init.x_stddev_1.max = 20.0 / 2.355 gaussian_init.y_stddev_1.min = 1.0 / 2.355 gaussian_init.y_stddev_1.max = 20.0 / 2.355 gaussian_init.y_stddev_1.tied = tie_sigma gaussian_init.theta_1.fixed = True fit_gauss = fitting.FittingWithOutlierRemoval( fitting.LevMarLSQFitter(), sigma_clip, niter=3, sigma=3.0) # gaussian, mask = fit_gauss(gaussian_init, x, y, subframe) gain = 8.21 #e per ADU read_noise = 2.43 #ADU weights = gain / np.sqrt( np.absolute(subframe) * gain + (read_noise * gain)**2) #1/sigma for each pixel gaussian, mask = fit_gauss(gaussian_init, x, y, subframe, weights) fwhm_x = 2.355 * gaussian.x_stddev_1.value fwhm_y = 2.355 * gaussian.y_stddev_1.value x_seeing = fwhm_x * 0.579 y_seeing = fwhm_y * 0.579 return (x_seeing, y_seeing) diagnostic_plot = 0 #Set to true to plot master and check images with sources.
def GetFitsForSigma(x_c, y_c, factor, fo, sigma, plot_name, bmaj, bmin, bpa, fijo, pix_size): ancho = int(round(0.5 * (5.0 * bmaj / pix_size)) * 2) center = int(ancho / 2.0) z = fo[max(int(y_c) - center, 0):min(int(y_c) + center, len(fo)), max(int(x_c) - center, 0):min(int(x_c) + center, len(fo[0]))] y, x = np.mgrid[0:len(z), 0:len(z[0])] p_init = models.Gaussian2D(amplitude=np.nanmax(z.flatten()), x_mean=center, y_mean=center, x_stddev=(bmaj / 2.355) / pix_size, y_stddev=(bmin / 2.355) / pix_size, theta=(bpa * 2.0 * np.pi / 360.0) + np.pi / 2) if fijo: p_init.x_stddev.fixed = True p_init.y_stddev.fixed = True p_init.theta.fixed = True fit_p = fitting.LevMarLSQFitter() with warnings.catch_warnings(): warnings.simplefilter('ignore') p = fit_p(p_init, x, y, z) model_flat = p(x, y).flatten() model2 = model_flat[model_flat >= 0.135 * max(model_flat)] peak_model = np.max(model_flat) fo[max(int(y_c) - center, 0):min(int(y_c) + center, len(fo)), max(int(x_c) - center, 0):min(int(x_c) + center, len(fo[0]))] = fo[ max(int(y_c) - center, 0):min(int(y_c) + center, len(fo)), max(int(x_c) - center, 0):min(int(x_c) + center, len(fo[0]))] - np.nan_to_num( p(x, y)) # plt.imshow(fo[max(int(y_c)-center,0):min(int(y_c)+center,len(fo)),max(int(x_c)-center,0):min(int(x_c)+center,len(fo[0]))],origin='lower') # plt.contour(p(x, y),origin='lower') # plt.show() return np.sum(model_flat) * factor, np.sqrt( len(model2) * factor) * sigma, peak_model, np.std( z - p(x, y)), p.x_stddev.value, p.y_stddev.value, p.theta.value, fo
def ClassicalOptimization(): fit_LSQ = fitting.LevMarLSQFitter() ring1 = FFRing(i0=0.0036, i1=0.0036, sig0=1., sig1=0.1, gam=1.6, xc=0., yc=0., a=50., b=50., theta=0.) ring2 = GaussianRing(amplitude=0.0005, a=230., b=230., width=20.) ring3 = GaussianRing(amplitude=0.0004, a=270., b=270., width=20.) ring4 = GaussianRing(amplitude=0.0005, a=40., b=40., width=5.) centralgauss = models.Gaussian2D(amplitude=0.0035, x_mean=0., y_mean=0., x_stddev=5., y_stddev=5., theta=0.) ring1.theta.fixed = True ring2.theta.fixed = True ring3.theta.fixed = True ring4.theta.fixed = True centralgauss.theta.fixed = True model = centralgauss + ring1 + ring2 + ring3 + ring4 modelend = fit_LSQ(model, xx, yy, image) #showi(modelend(xx,yy)) modelend.theta_0.fixed = False modelend.theta_2.fixed = False modelend.theta_1.fixed = False modelend.theta_3.fixed = False modelend.theta_4.fixed = False modelend = fit_LSQ(modelend, xx, yy, image) modelend = fit_LSQ(modelend, xx, yy, image) #showi(modelend(xx,yy)) return (modelend.parameters)
def _initialize_model(self): """Initialize a model with first guesses for the parameters. The user can select between several astropy models, e.g., 'Gaussian2D', 'Moffat2D'. We will use the data to get the first estimates of the parameters of each model. Finally, a Constant2D model is added to account for the background or sky level around the star. """ max_value = self.data.max() if self.model_type == self._GAUSSIAN2D: model = models.Gaussian2D(x_mean=self.x, y_mean=self.y, x_stddev=1, y_stddev=1) model.amplitude = max_value # Establish reasonable bounds for the fitted parameters model.x_stddev.bounds = (0, self._box / 4) model.y_stddev.bounds = (0, self._box / 4) model.x_mean.bounds = (self.x - 5, self.x + 5) model.y_mean.bounds = (self.y - 5, self.y + 5) elif self.model_type == self._MOFFAT2D: model = models.Moffat2D() model.x_0 = self.x model.y_0 = self.y model.gamma = 2 model.alpha = 2 model.amplitude = max_value # Establish reasonable bounds for the fitted parameters model.alpha.bounds = (1, 6) model.gamma.bounds = (0, self._box / 4) model.x_0.bounds = (self.x - 5, self.x + 5) model.y_0.bounds = (self.y - 5, self.y + 5) model += models.Const2D(self.fit_sky()) model.amplitude_1.fixed = True return model
def centroid(data, coords, rad=30, returnFit=False): if isinstance(data, str): data = pyfits.getdata(data) # Transpose x and y b/c reasons center_y, center_x = coords dslice = data[center_x - rad:center_x + rad, center_y - rad:center_y + rad] x, y = np.mgrid[0:dslice.shape[0], 0:dslice.shape[1]] x -= dslice.shape[0] / 2. y -= dslice.shape[1] / 2. p_init = models.Gaussian2D(np.max(dslice), 0, 0, rad, rad) p = fitter(p_init, x, y, dslice) # Rescale coordinates to match data p.x_mean = center_y - p.x_mean p.y_mean = center_x - p.y_mean if returnFit: return p.x_mean.value, p.y_mean.value, p else: return p.x_mean.value, p.y_mean.value
def test_bounds_gauss2d_lsq(self): X, Y = np.meshgrid(np.arange(11), np.arange(11)) bounds = {"x_mean": [0., 11.], "y_mean": [0., 11.], "x_stddev": [1., 4], "y_stddev": [1., 4]} gauss = models.Gaussian2D(amplitude=10., x_mean=5., y_mean=5., x_stddev=4., y_stddev=4., theta=0.5, bounds=bounds) gauss_fit = fitting.LevMarLSQFitter() model = gauss_fit(gauss, X, Y, self.data) x_mean = model.x_mean.value y_mean = model.y_mean.value x_stddev = model.x_stddev.value y_stddev = model.y_stddev.value assert x_mean + 10 ** -5 >= bounds['x_mean'][0] assert x_mean - 10 ** -5 <= bounds['x_mean'][1] assert y_mean + 10 ** -5 >= bounds['y_mean'][0] assert y_mean - 10 ** -5 <= bounds['y_mean'][1] assert x_stddev + 10 ** -5 >= bounds['x_stddev'][0] assert x_stddev - 10 ** -5 <= bounds['x_stddev'][1] assert y_stddev + 10 ** -5 >= bounds['y_stddev'][0] assert y_stddev - 10 ** -5 <= bounds['y_stddev'][1]
def measure_psf_fwhm(psf, fwhm_guess): """ Fit a 2D Gaussian to observed psf to estimate the FWHM Parameters ---------- psf : ndarray Observed psf fwhm_guess : float Guess for fwhm in pixels Returns ------- mean_fwhm : float Mean x & y FWHM """ sigma = fwhm_guess * gaussian_fwhm_to_sigma g_init = models.Gaussian2D(psf.max() * 0.3, psf.shape[1] / 2, psf.shape[0] / 2, sigma) fit_g = fitting.LevMarLSQFitter() xx, yy = np.meshgrid(np.arange(psf.shape[1]), np.arange(psf.shape[0])) best_fit = fit_g(g_init, xx, yy, psf) mean_fwhm = np.mean([best_fit.x_fwhm, best_fit.y_fwhm]) return mean_fwhm
def fit_gauss(sci): from astropy.modeling import models, fitting sh = sci.shape gau = models.Gaussian2D(amplitude=sci.max(), x_mean=sh[0] / 2, y_mean=sh[0] / 2., x_stddev=None, y_stddev=None, theta=None, cov_matrix=None) lm = fitting.LevMarLSQFitter() yp, xp = np.indices(sh) fit = lm(gau, xp, yp, sci) q = (fit.x_stddev / fit.y_stddev)**2 theta = fit.theta.value if q > 1: q = 1. / q theta += np.pi / 2. return fit, q, theta