def setup_scene(galaxy=False, fudge=1.0, fwhm=1.0, offset=0.0, size=(30, 30), add_noise=False): stamp = make_stamp(size, fwhm, offset=offset) # --- Get a Source and Scene ----- if galaxy: source = Galaxy() source.ngauss = 1 source.radii = np.arange(source.ngauss) * 0.5 + 1.0 source.q = 0.5 source.pa = np.deg2rad(30.) theta = [100., 10., 10., 0.5, np.deg2rad(10.)] label = ['$\psi$', '$x$', '$y$', '$q$', '$\\varphi$'] bounds = [(0, 1e4), (0., 30), (0, 30), (0, 1), (0, np.pi / 2)] else: source = Star() theta = [100., 10., 10.] label = ['$\psi$', '$x$', '$y$'] bounds = [(-1e6, 1e6), (-1e5, 1e5), (-1e5, 1e5)] scene = Scene(galaxy=galaxy) scene.sources = [source] # --- Generate mock and add to stamp --- ptrue = np.array(theta) * fudge true_image, partials = make_image(ptrue, scene, stamp) stamp.pixel_values = true_image.copy() err = stamp.pixel_values.max() * 1e-2 #err = np.sqrt(stamp.pixel_values.flatten()) stamp.ierr = np.ones(stamp.npix) / err if add_noise: noise = np.random.normal(0, err, size=(stamp.nx, stamp.ny)) stamp.pixel_values += noise return scene, stamp, ptrue, label
def setup_scene(psfname='', size=(100, 100), fudge=1.0, add_noise=False): # --- Get a postage stamp ---- stamp = make_stamp(size, psfname=psfname) # --- get the Scene --- scene = Scene(galaxy=False) sources = [Star()] scene.sources = sources # --- Get the mock image ---- label = ['flux', 'x', 'y'] theta = np.array([100., stamp.nx / 2., stamp.ny / 2.]) ptrue = theta * fudge stamp.pixel_values = make_image(ptrue, scene, stamp)[0] err = stamp.pixel_values.max() * 1e-2 #err = np.sqrt(stamp.pixel_values.flatten()) stamp.ierr = np.ones(stamp.npix) / err if add_noise: noise = np.random.normal(0, err, size=(stamp.nx, stamp.ny)) stamp.pixel_values += noise return scene, stamp, ptrue, label
#ra_init, dec_init = 53.115299, -27.803508 # keep in mind 1pixel ~ 1e-5 degrees ra_init, dec_init = 53.115295, -27.803501 pos_init = (ra_init, dec_init) stamps = [make_stamp(im, pos_init, center_type='celestial', size=(100, 100), psfname=psfname) for im in imnames] # override the psf to reflect in both directions T = -1.0 * np.eye(2) for s in stamps: s.psf.covariances = np.matmul(T, np.matmul(s.psf.covariances, T.T)) s.psf.means = np.matmul(s.psf.means, T) # --- get the Scene --- scene = Scene() sources = [Star()] sources[0].id = 0 scene.sources = sources label = ['flux', 'alpha', 'delta'] nll = argfix(negative_lnlike_multistamp, scene=scene, stamps=stamps) # --- Initialize --- theta_init = np.array([ra_init, dec_init, stamps[0].pixel_values.sum() * 1.0]) # --- Optimization --- if True: def callback(x): #nf += 1 print(x, nll(x))
def fit_source(ra=53.115325, dec=-27.803518, imname='', psfname=None, stamp_size=(100, 100), use_grad=True, err_expand=1.0, jitter=0.0, gain=np.inf): """ """ # --- Build the postage stamp ---- stamp = make_stamp(imname, (ra, dec), stamp_size, psfname=psfname, center_type='celestial') stamp.snr = stamp.pixel_values * stamp.ierr stamp.ierr = stamp.ierr.flatten() / err_expand counts = stamp.pixel_values.flatten() - stamp.pixel_values.min() stamp.ierr = 1.0 / np.sqrt(1/stamp.ierr**2 + jitter**2 + counts/gain) # override the WCS so coordinates are in pixels # The scale matrix D stamp.scale = np.eye(2) # The sky coordinates of the reference pixel stamp.crval = np.zeros([2]) # The pixel coordinates of the reference pixel stamp.crpix = np.zeros([2]) # Rotate the PSF by 180 degrees T = -1.0 * np.eye(2) stamp.psf.covariances = np.matmul(T, np.matmul(stamp.psf.covariances, T.T)) stamp.psf.means = np.matmul(stamp.psf.means, T) # --- get the Scene --- scene = Scene(galaxy=False) sources = [Star()] scene.sources = sources # ---- Optimization ------ if use_grad: nll = argfix(negative_lnlike_stamp, scene=scene, stamp=stamp) else: nll = argfix(negative_lnlike_nograd, scene=scene, stamp=stamp) if False: nll = argfix(chi_vector, scene=scene, stamp=stamp) method = 'lm' use_grad = False if True: def callback(x): #nf += 1 print(x, nll(x)) callback = None # Initial and bounds p0 = np.array([stamp.pixel_values.sum(), stamp.nx/2, stamp.ny/2]) p0 += np.random.normal(0., [0.1 * p0[0], 0.5, 0.5]) bounds = [(1, 1e4), (0., stamp_size[0]), (0, stamp_size[1])] bounds = None # Optimize from scipy.optimize import minimize lbfgsb_opt = {'ftol': 1e-20, 'gtol': 1e-12, 'disp':True, 'iprint': -1, 'maxcor': 20} result = minimize(nll, p0, jac=use_grad, bounds=None, callback=callback, options=lbfgsb_opt) # plot results resid, partials = make_image(result.x, scene, stamp) dim = stamp.pixel_values mim = resid chi = (dim - mim) * stamp.ierr.reshape(stamp.nx, stamp.ny) fig, axes = pl.subplots(1, 4, sharex=True, sharey=True, figsize=(14.75, 3.25)) images = [dim, mim, dim-mim, chi] labels = ['Data', 'Model', 'Data-Model', '$\chi$'] for k, ax in enumerate(axes): c = ax.imshow(images[k].T, origin='lower') pl.colorbar(c, ax=ax) ax.set_title(labels[k]) return result, (fig, axes), nll(result.x), stamp, scene
if m < M: return a.reshape((m, M / m, n, N / n)).mean(3).mean(1) else: return np.repeat(np.repeat(a, m / M, axis=0), n / N, axis=1) def compare(x, y, source, native, oversampled): image = get_image(x, y, source, native) oimage = get_image(x, y, source, oversampled) rimage = rebin(oimage, image.shape) * oversample**2 if __name__ == "__main__": source = Star() use = slice(0, 3) # FWHM in native pixels fwhm = 1.0 sigma = fwhm / 2.355 # native resolution native = get_stamp(30) native.psf.covariances = np.array([np.eye(2) * sigma**2]) native.crpix = np.array([15, 15]) # oversampled image oversample = 8 dx = 1. / oversample oversampled = get_stamp(int(30 / dx), dx)