def prep_scene(sourcepars, filters=["dummy"], splinedata=None, free_sersic=True): # --- Get Sources and a Scene ----- sources = [] for pars in sourcepars: flux, x, y, q, pa, n, rh = copy.deepcopy(pars) s = Galaxy(filters=filters, splinedata=splinedata, free_sersic=free_sersic) s.sersic = n s.rh = rh s.flux = flux #np.atleast_1d(flux) s.ra = x s.dec = y s.q = q s.pa = np.deg2rad(pa) sources.append(s) scene = Scene(sources) theta = scene.get_all_source_params() return scene, theta
def prep_scene(sourcepars, filters=["dummy"], splinedata=None): # --- Get Sources and a Scene ----- sources = [] for pars in sourcepars: flux, x, y, q, pa, n, rh = np.copy(pars) if splinedata is not None: s = Galaxy(filters=filters, splinedata=splinedata, free_sersic=False) s.sersic = n s.rh = rh else: s = SimpleGalaxy(filters=filters) s.flux = flux s.ra = x s.dec = y s.q = q s.pa = np.deg2rad(pa) sources.append(s) scene = Scene(sources) theta = scene.get_all_source_params() return scene, theta
def setup_scene(sourceparams=[(1.0, 5., 5., 0.7, 30., 1.0, 0.05)], splinedata=None, perturb=0, filters=['dummy'], add_noise=False, snr_max=100., stamp_kwargs=[]): # --- Get Sources and a Scene ----- sources = [] for (flux, x, y, q, pa, n, rh) in sourceparams: if splinedata is not None: s = Galaxy(filters=filters, splinedata=splinedata) s.sersic = n s.rh = rh else: s = SimpleGalaxy(filters=filters) s.flux = flux s.ra = x s.dec = y s.q = q s.pa = np.deg2rad(pa) sources.append(s) scene = Scene(sources) theta = scene.get_all_source_params() label = [] # get stamps stamps = [make_stamp(**sk) for sk in stamp_kwargs] if splinedata is not None: for stamp in stamps: stamp.scale = np.array([[32.0, 0.0], [0.0, 32.0]]) # --- Generate mock and add to stamp --- ptrue = theta * np.random.normal(1.0, perturb, size=theta.shape) for stamp in stamps: true_image, _ = make_image(scene, stamp, Theta=ptrue) stamp.pixel_values = true_image.copy() err = stamp.pixel_values.max() / snr_max #err = np.sqrt(err**2 + stamp.pixel_values.flatten()) err = np.ones(stamp.npix) * err stamp.ierr = np.ones(stamp.npix) / err if add_noise: noise = np.random.normal(0, err) stamp.pixel_values += noise.reshape(stamp.nx, stamp.ny) return scene, stamps, ptrue, label
def set_scene(sourcepars, fluxpars, filters, splinedata=None, free_sersic=True): """Build a scene from a set of source parameters and fluxes through a set of filters. Returns ------- scene: Scene object """ sourcepars = sourcepars.astype(np.float) # get all sources sources = [] for ii_gal in range(len(sourcepars)): gal_id, x, y, q, pa, n, rh = sourcepars[ii_gal] #print(x, y, type(pa), pa) s = Galaxy(filters=filters.tolist(), splinedata=splinedata, free_sersic=free_sersic) s.global_id = gal_id s.sersic = n s.rh = np.clip(rh, 0.05, 0.10) s.flux = fluxpars[ii_gal] s.ra = x s.dec = y s.q = np.clip(q, 0.2, 0.9) s.pa = np.deg2rad(pa) sources.append(s) # generate scene scene = Scene(sources) return (scene)
def set_inactive(scene, stamps, pad=5, nmax=0): # set outside sources to be fixed. for stamp in stamps: for source in scene.sources: x, y = stamp.sky_to_pix([source.ra, source.dec]) good = ((x < stamp.nx + pad) & (x > -pad) & (y < stamp.ny + pad) & (y > -pad)) if ~good: source.fixed = True insources = [s for s in scene.sources if not s.fixed] fluxes = np.array([s.flux for s in insources]) order = np.argsort(fluxes.max(axis=-1)) use = order[-nmax:] use_sources = [insources[i] for i in use] microscene = Scene(use_sources) try: microscene.npsf_per_source = scene.npsf_per_source except (AttributeError): pass return microscene
def setup_scene(galaxy=False, fwhm=1.0, offset=0.0, size=(30, 30), peak_snr=1e1, add_noise=False): stamp = make_stamp(size, fwhm, offset=offset) # --- Get a Source and Scene ----- if galaxy: ngauss = 1 source = SimpleGalaxy() source.radii = np.arange(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([source]) # --- Generate mock and add to stamp --- ptrue = np.array(theta) true_image, partials = make_image(scene, stamp, Theta=ptrue) stamp.pixel_values = true_image.copy() err = stamp.pixel_values.max() / peak_snr #err = np.sqrt(err**2 + stamp.pixel_values.flatten()) err = np.ones(stamp.npix) * err stamp.ierr = np.ones(stamp.npix) / err if add_noise: noise = np.random.normal(0, err) stamp.pixel_values += noise.reshape(stamp.nx, stamp.ny) return scene, stamp, ptrue, label
stamp.scale = np.eye(2) stamp.dpix_dsky = 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]) # override the psf to reflect in both directions 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 --- sources = [Star(filters=["F090W"])] label = ['flux', 'x', 'y'] scene = Scene(sources) plans = [WorkPlan(stamp)] nll = argfix(negative_lnlike_multi, scene=scene, plans=plans) nll_nograd = argfix(negative_lnlike_multi, scene=scene, plans=plans, grad=False) # --- Initialize --- theta_init = np.array([stamp.pixel_values.sum() * 1.0, ra_init, dec_init]) if inpixels: world = np.array([ra_init, dec_init, 0]) hdr = fits.getheader(imname) ast = apy_wcs.WCS(hdr) center = ast.wcs_world2pix(world[None, :], 0)[0, :2] - stamp.lo
def fit_source(ra=53.115295, dec=-27.803501, dofit=True, nlive=100): # --- Build the postage stamp ---- ra_init, dec_init = ra, dec pos_init = (ra_init, dec_init) stamps = [ make_stamp(im, pos_init, center_type='celestial', size=(50, 50), 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 --- source = Star(filters=["F090W"]) scene = Scene([source]) label = ['Counts', 'RA', 'Dec'] plans = [WorkPlan(stamp) for stamp in stamps] lnlike = argfix(lnlike_multi, scene=scene, plans=plans, grad=False) # --- Initialize --- theta_init = np.array( [stamps[0].pixel_values.sum() * 1.0, ra_init, dec_init]) # a rough measure of dcoordinate/dpix plate_scale, _ = np.linalg.eig(np.linalg.inv(stamps[0].dpix_dsky)) # make the prior ~10 pixels wide, and 50% of counts theta_width = np.array( [0.5 * theta_init[0], 10 * plate_scale[0], 10 * plate_scale[1]]) #print(theta_init, theta_width) # --- Nested sampling --- ndim = 3 def prior_transform(unit_coords): # convert to uniform -1 to 1 u = (2 * unit_coords - 1.) # now scale and shift theta = theta_init + theta_width * u return theta if dofit: import dynesty, time # "Standard" nested sampling. sampler = dynesty.NestedSampler(lnlike, prior_transform, ndim, nlive=nlive, bootstrap=0) t0 = time.time() sampler.run_nested() dur = time.time() - t0 results = sampler.results results['duration'] = dur indmax = results['logl'].argmax() theta_max = results['samples'][indmax, :] else: results = None theta_max = np.zeros(3) stamps = None return results, theta_max, stamps, scene
def fit_source(ra=53.115295, dec=-27.803501, mag=None, dofit='dynesty', nlive=100, nburn=600, niter=200): # --- Get the data --- stamps = prep_stamps(ra, dec) # --- Get the Scene --- source = Star(filters=filters) scene = Scene([source]) label = ['Counts', 'RA', 'Dec'] plans = [WorkPlan(stamp) for stamp in stamps] # --- Initialize and set scales --- if mag is None: counts = [ np.clip(stamp.pixel_values.sum(), 1, np.inf) for stamp in stamps ] else: counts = [ 10**(0.4 * (stamp.full_header["ABMAG"] - mag)) for stamp in stamps ] theta_init = np.array(counts + [ra, dec]) # a rough measure of dcoordinate/dpix - this doesn't work so great plate_scale = np.linalg.eigvals(np.linalg.inv(stamps[0].dpix_dsky)) plate_scale = np.abs(plate_scale) # make the prior ~5 pixels wide, and 100% of expected counts theta_width = np.array( [theta_init[0], 5 * plate_scale[0], 5 * plate_scale[1]]) print(theta_init, theta_width) # --- Sampling --- ndim = 3 p0 = theta_init.copy() upper = theta_init + theta_width / 2. lower = theta_init - theta_width / 2. scales = theta_width if dofit == 'dynesty': lnlike = argfix(lnlike_multi, scene=scene, plans=plans, grad=False) def prior_transform(unit_coords): # convert to uniform -1 to 1 u = (2 * unit_coords - 1.) # now scale and shift theta = theta_init + theta_width * u return theta import dynesty, time # "Standard" nested sampling. sampler = dynesty.NestedSampler(lnlike, prior_transform, ndim, bootstrap=0, nlive=nlive) t0 = time.time() sampler.run_nested() dur = time.time() - t0 results = sampler.results results['duration'] = dur indmax = results['logl'].argmax() theta_max = results['samples'][indmax, :] elif dofit == "hmc": from hmc import BasicHMC model = Posterior(scene, plans, upper=upper, lower=lower) hsampler = BasicHMC(model, verbose=False) hsampler.ndim = len(p0) hsampler.set_mass_matrix(1 / scales**2) eps = hsampler.find_reasonable_stepsize(p0) pos, prob, grad = hsampler.sample(p0, iterations=nburn, mass_matrix=1 / scales**2, epsilon=eps * 1.5, length=10, sigma_length=3, store_trajectories=False) pos, prob, grad = hsampler.sample(pos, iterations=niter, mass_matrix=1 / scales**2, epsilon=eps, length=20, sigma_length=5, store_trajectories=True) results = { "samples": sampler.chain.copy(), "lnprobability": sampler.lnp.copy() } theta_max = sampler.chain[np.argmax(sampler.lnprob), :] elif dofit == "hemcee": from hemcee import NoUTurnSampler from hemcee.metric import DiagonalMetric model = Posterior(scene, plans, upper=np.inf, lower=-np.inf) metric = DiagonalMetric(scales**2) usampler = NoUTurnSampler(model.lnprob, model.lnprob_grad, metric=metric) pos, lnp0 = usampler.run_warmup(p0, nburn) chain, lnp = usampler.run_mcmc(pos, niter) results = {"samples": chain, "lnprobability": lnp} theta_max = chain[np.argmax(lnp), :] else: results = None theta_max = np.zeros(3) return results, theta_max, stamps, scene
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() scene = Scene([source]) # FWHM in native pixels fwhm = 2.0 sigma = fwhm/2.355 ck = {"second_order": False} # native resolution native = get_stamp(10) native.psf.covariances = np.array([np.eye(2) * sigma**2]) native.crpix = np.array([5, 5]) # oversampled image oversample = 8 dx = 1./oversample oversampled = get_stamp(int(10 / dx), dx)