예제 #1
0
def run_moments(*, n_sims, wcs_g1, wcs_g2):
    """Run the moments fitter and check g1, g2.

    The resulting values are printed to STDOUT.

    Parameters
    ----------
    n_sims : int
        The number of objects to simulated.
    wcs_g1 : float
        The shear on the 1-axis of the WCS Jacobian.
    wcs_g2 : float
        The shear on the 2-axis of the WCS Jacobian.
    """
    jc = galsim.ShearWCS(0.263, galsim.Shear(g1=wcs_g1, g2=wcs_g2)).jacobian()

    jacobian_dict = {
        'dudx': jc.dudx,
        'dudy': jc.dudy,
        'dvdx': jc.dvdx,
        'dvdy': jc.dvdy
    }

    res = _run_moments(n_sims=n_sims,
                       rng=np.random.RandomState(seed=10),
                       **jacobian_dict)

    g1 = np.array([r['g'][0] for r in res])
    g2 = np.array([r['g'][1] for r in res])
    g1m, g1_err, g2m, g2_err = _jack_est(g1, g2)

    print("""\
# of sims: {n_sims}
wcs_g1   : {wcs_g1:f}
wcs_g2   : {wcs_g2:f}
dudx     : {dudx:f}
dudy     : {dudy:f}
dvdx     : {dvdx:f}
dvdy     : {dvdy:f}
g1 [1e-3] : {g1m:g} +/- {g1_err:g}
g2 [1e-3] : {g2m:g} +/- {g2_err:g}""".format(n_sims=len(g1),
                                             wcs_g1=wcs_g1,
                                             wcs_g2=wcs_g2,
                                             **jacobian_dict,
                                             g1m=g1m / 1e-3,
                                             g1_err=g1_err / 1e-3,
                                             g2m=g2m / 1e-3,
                                             g2_err=g2_err / 1e-3),
          flush=True)
예제 #2
0
def test_pixels_smoke(x, y, wcs_g1, wcs_g2, ignore_zero_weight):
    gs_wcs = galsim.ShearWCS(0.25, galsim.Shear(g1=wcs_g1,
                                                g2=wcs_g2)).jacobian()
    jac = Jacobian(y=y,
                   x=x,
                   dudx=gs_wcs.dudx,
                   dudy=gs_wcs.dudy,
                   dvdx=gs_wcs.dvdx,
                   dvdy=gs_wcs.dvdy)
    dims = (13, 15)

    rng = np.random.RandomState(seed=11)
    image = rng.normal(size=dims)
    weight = np.exp(rng.normal(size=dims))

    weight[10, 9] = 0
    weight[8, 7] = 0

    pixels = make_pixels(image,
                         weight,
                         jac,
                         ignore_zero_weight=ignore_zero_weight)

    assert np.allclose(pixels['area'], jac.area)

    found_zero = 0
    for i in range(len(pixels)):
        y, x = jac.get_rowcol(pixels['v'][i], pixels['u'][i])
        assert np.allclose(x, int(x + 0.5))
        assert np.allclose(y, int(y + 0.5))
        x = int(x + 0.5)
        y = int(y + 0.5)

        assert pixels['val'][i] == image[y, x]
        assert np.allclose(pixels['ierr'][i], np.sqrt(weight[y, x]))

        if x == 9 and y == 10:
            found_zero += 1
        if y == 8 and x == 7:
            found_zero += 1

    if ignore_zero_weight:
        assert found_zero == 0
    else:
        assert found_zero == 2
예제 #3
0
def test_coords_smoke(x, y, wcs_g1, wcs_g2):
    gs_wcs = galsim.ShearWCS(0.25, galsim.Shear(g1=wcs_g1,
                                                g2=wcs_g2)).jacobian()
    jac = Jacobian(y=y,
                   x=x,
                   dudx=gs_wcs.dudx,
                   dudy=gs_wcs.dudy,
                   dvdx=gs_wcs.dvdx,
                   dvdy=gs_wcs.dvdy)
    dims = (13, 15)

    coords = make_coords(dims, jac)
    loc = 0
    for y in range(dims[0]):
        for x in range(dims[1]):
            v, u = jac(y, x)
            assert u == coords['u'][loc]
            assert v == coords['v'][loc]
            loc += 1
예제 #4
0
def main(argv):
    """
    Getting reasonably close to including all the principle features of an image from a
    ground-based telescope:
      - Use a bulge plus disk model for the galaxy
      - Both galaxy components are Sersic profiles (n=3.5 and n=1.5 respectively)
      - Let the PSF have both atmospheric and optical components.
      - The atmospheric component is a Kolmogorov spectrum.
      - The optical component has some defocus, coma, and astigmatism.
      - Add both Poisson noise to the image and Gaussian read noise.
      - Let the pixels be slightly distorted relative to the sky.
    """
    # We do some fancier logging for demo3, just to demonstrate that we can:
    # - we log to both stdout and to a log file
    # - the log file has a lot more (mostly redundant) information
    logging.basicConfig(format="%(message)s", level=logging.INFO, stream=sys.stdout)
    if not os.path.isdir('output'):
        os.mkdir('output')
    logFile = logging.FileHandler(os.path.join("output", "script3.log"))
    logFile.setFormatter(logging.Formatter("%(name)s[%(levelname)s] %(asctime)s: %(message)s"))
    logging.getLogger("demo3").addHandler(logFile)
    logger = logging.getLogger("demo3")

    gal_flux = 1.e6        # ADU  ("Analog-to-digital units", the units of the numbers on a CCD)
    bulge_n = 3.5          #
    bulge_re = 2.3         # arcsec
    disk_n = 1.5           #
    disk_r0 = 0.85         # arcsec (corresponds to half_light_radius of ~3.7 arcsec)
    bulge_frac = 0.3       #
    gal_q = 0.73           # (axis ratio 0 < q < 1)
    gal_beta = 23          # degrees (position angle on the sky)
    atmos_fwhm=2.1         # arcsec
    atmos_e = 0.13         #
    atmos_beta = 0.81      # radians
    opt_defocus=0.53       # wavelengths
    opt_a1=-0.29           # wavelengths
    opt_a2=0.12            # wavelengths
    opt_c1=0.64            # wavelengths
    opt_c2=-0.33           # wavelengths
    opt_obscuration=0.3    # linear scale size of secondary mirror obscuration
    lam = 800              # nm    NB: don't use lambda - that's a reserved word.
    tel_diam = 4.          # meters
    pixel_scale = 0.23     # arcsec / pixel
    image_size = 64        # n x n pixels
    wcs_g1 = -0.02         #
    wcs_g2 = 0.01          #
    sky_level = 2.5e4      # ADU / arcsec^2
    gain = 1.7             # e- / ADU
                           # Note: here we assume 1 photon -> 1 e-, ignoring QE.  If you wanted,
                           # you could include the QE factor as part of the gain.
    read_noise = 0.3       # e- / pixel

    random_seed = 1314662

    logger.info('Starting demo script 3 using:')
    logger.info('    - Galaxy is bulge plus disk, flux = %.1e',gal_flux)
    logger.info('       - Bulge is Sersic (n = %.1f, re = %.2f), frac = %.1f',
                bulge_n,bulge_re,bulge_frac)
    logger.info('       - Disk is Sersic (n = %.1f, r0 = %.2f), frac = %.1f',
                disk_n,disk_r0,1-bulge_frac)
    logger.info('       - Shape is q,beta (%.2f,%.2f deg)', gal_q, gal_beta)
    logger.info('    - Atmospheric PSF is Kolmogorov with fwhm = %.2f',atmos_fwhm)
    logger.info('       - Shape is e,beta (%.2f,%.2f rad)', atmos_e, atmos_beta)
    logger.info('    - Optical PSF has defocus = %.2f, astigmatism = (%.2f,%.2f),',
                opt_defocus, opt_a1, opt_a2)
    logger.info('          coma = (%.2f,%.2f), lambda = %.0f nm, D = %.1f m',
                opt_c1, opt_c2, lam, tel_diam)
    logger.info('          obscuration linear size = %.1f',opt_obscuration)
    logger.info('    - pixel scale = %.2f,',pixel_scale)
    logger.info('    - WCS distortion = (%.2f,%.2f),',wcs_g1,wcs_g2)
    logger.info('    - Poisson noise (sky level = %.1e, gain = %.1f).',sky_level, gain)
    logger.info('    - Gaussian read noise (sigma = %.2f).',read_noise)

    # Initialize the (pseudo-)random number generator that we will be using below.
    rng = galsim.BaseDeviate(random_seed+1)

    # Define the galaxy profile.
    # Normally Sersic profiles are specified by half-light radius, the radius that
    # encloses half of the total flux.  However, for some purposes, it can be
    # preferable to instead specify the scale radius, where the surface brightness
    # drops to 1/e of the central peak value.
    bulge = galsim.Sersic(bulge_n, half_light_radius=bulge_re)
    disk = galsim.Sersic(disk_n, scale_radius=disk_r0)

    # Objects may be multiplied by a scalar (which means scaling the flux) and also
    # added to each other.
    gal = bulge_frac * bulge + (1-bulge_frac) * disk
    # Could also have written the following, which does the same thing:
    #   gal = galsim.Add([ bulge.withFlux(bulge_frac) , disk.withFlux(1-bulge_frac) ])
    # Both syntaxes work with more than two summands as well.

    # Set the overall flux of the combined object.
    gal = gal.withFlux(gal_flux)
    # Since the total flux of the components was 1, we could also have written:
    #   gal *= gal_flux
    # The withFlux method will always set the flux to the given value, while `gal *= flux`
    # will multiply whatever the current flux is by the given factor.

    # Set the shape of the galaxy according to axis ratio and position angle
    # Note: All angles in GalSim must have explicit units.  Options are:
    #       galsim.radians
    #       galsim.degrees
    #       galsim.arcmin
    #       galsim.arcsec
    #       galsim.hours
    gal_shape = galsim.Shear(q=gal_q, beta=gal_beta*galsim.degrees)
    gal = gal.shear(gal_shape)
    logger.debug('Made galaxy profile')

    # Define the atmospheric part of the PSF.
    # Note: the flux here is the default flux=1.
    atmos = galsim.Kolmogorov(fwhm=atmos_fwhm)
    # For the PSF shape here, we use ellipticity rather than axis ratio.
    # And the position angle can be either degrees or radians.  Here we chose radians.
    atmos = atmos.shear(e=atmos_e, beta=atmos_beta*galsim.radians)
    logger.debug('Made atmospheric PSF profile')

    # Define the optical part of the PSF:
    # The first argument of OpticalPSF below is lambda/diam (wavelength of light / telescope
    # diameter), which needs to be in the same units used to specify the image scale.  We are using
    # arcsec for that, so we have to self-consistently use arcsec here, using the following
    # calculation:
    lam_over_diam = lam * 1.e-9 / tel_diam # radians
    lam_over_diam *= 206265  # arcsec
    # Note that we could also have made GalSim do the conversion for us if we did not know the right
    # factor:
    # lam_over_diam = lam * 1.e-9 / tel_diam * galsim.radians
    # lam_over_diam = lam_over_diam / galsim.arcsec
    logger.debug('Calculated lambda over diam = %f arcsec', lam_over_diam)
    # The rest of the values should be given in units of the wavelength of the incident light.
    optics = galsim.OpticalPSF(lam_over_diam,
                               defocus = opt_defocus,
                               coma1 = opt_c1, coma2 = opt_c2,
                               astig1 = opt_a1, astig2 = opt_a2,
                               obscuration = opt_obscuration)
    logger.debug('Made optical PSF profile')

    # So far, our coordinate transformation between image and sky coordinates has been just a
    # scaling of the units between pixels and arcsec, which we have defined as the "pixel scale".
    # This is fine for many purposes, so we have made it easy to treat the coordinate systems
    # this way via the `scale` parameter to commands like drawImage.  However, in general, the
    # transformation between the two coordinate systems can be more complicated than that,
    # including distortions, rotations, variation in pixel size, and so forth.  GalSim can
    # model a number of different "World Coordinate System" (WCS) transformations.  See the
    # docstring for BaseWCS for more information.

    # In this case, we use a WCS that includes a distortion (specified as g1,g2 in this case),
    # which we call a ShearWCS.
    wcs = galsim.ShearWCS(scale=pixel_scale, shear=galsim.Shear(g1=wcs_g1, g2=wcs_g2))
    logger.debug('Made the WCS')

    # Next we will convolve the components in world coordinates.
    psf = galsim.Convolve([atmos, optics])
    final = galsim.Convolve([psf, gal])
    logger.debug('Convolved components into final profile')

    # This time we specify a particular size for the image rather than let GalSim
    # choose the size automatically.  GalSim has several kinds of images that it can use:
    #   ImageF uses 32-bit floats    (like a C float, aka numpy.float32)
    #   ImageD uses 64-bit floats    (like a C double, aka numpy.float64)
    #   ImageS uses 16-bit integers  (usually like a C short, aka numpy.int16)
    #   ImageI uses 32-bit integers  (usually like a C int, aka numpy.int32)
    # If you let the GalSim drawImage command create the image for you, it will create an ImageF.
    # However, you can make a different type if you prefer.  In this case, we still use
    # ImageF, since 32-bit floats are fine.  We just want to set the size explicitly.
    image = galsim.ImageF(image_size, image_size)
    # Draw the image with the given WCS.  Note that we use wcs rather than scale when the
    # WCS is more complicated than just a pixel scale.
    final.drawImage(image=image, wcs=wcs)

    # Also draw the effective PSF by itself and the optical PSF component alone.
    image_epsf = galsim.ImageF(image_size, image_size)
    psf.drawImage(image_epsf, wcs=wcs)

    # We also draw the optical part of the PSF at its own Nyquist-sampled pixel size
    # in order to better see the features of the (highly structured) profile.
    # In this case, we draw a "surface brightness image" using method='sb'.  Rather than
    # integrate the flux over the area of each pixel, this method just samples the surface
    # brightness value at the locations of the pixel centers.  We will encounter a few other
    # drawing methods as we go through this sequence of demos.  cf. demos 7, 8, 10, and 11.
    image_opticalpsf = optics.drawImage(method='sb')
    logger.debug('Made image of the profile')

    # Add a constant sky level to the image.
    image += sky_level * pixel_scale**2

    # This time, we use CCDNoise to model the real noise in a CCD image.  It takes a sky level,
    # gain, and read noise, so it can be a bit more realistic than the simpler GaussianNoise
    # or PoissonNoise that we used in demos 1 and 2.
    #
    # The gain is in units of e-/ADU.  Technically, one should also account for quantum efficiency
    # (QE) of the detector. An ideal CCD has one electron per incident photon, but real CCDs have
    # QE less than 1, so not every photon triggers an electron.  We are essentially folding
    # the quantum efficiency (and filter transmission and anything else like that) into the gain.
    # The read_noise value is given as e-/pixel.  This is modeled as a pure Gaussian noise
    # added to the image after applying the pure Poisson noise.
    image.addNoise(galsim.CCDNoise(rng, gain=gain, read_noise=read_noise))

    # Subtract off the sky.
    image -= sky_level * pixel_scale**2
    logger.debug('Added Gaussian and Poisson noise')

    # Write the images to files.
    file_name = os.path.join('output', 'demo3.fits')
    file_name_epsf = os.path.join('output','demo3_epsf.fits')
    file_name_opticalpsf = os.path.join('output','demo3_opticalpsf.fits')
    image.write(file_name)
    image_epsf.write(file_name_epsf)
    image_opticalpsf.write(file_name_opticalpsf)
    logger.info('Wrote image to %r', file_name)
    logger.info('Wrote effective PSF image to %r', file_name_epsf)
    logger.info('Wrote optics-only PSF image (Nyquist sampled) to %r', file_name_opticalpsf)

    # Check that the HSM package, which is bundled with GalSim, finds a good estimate
    # of the shear.
    results = galsim.hsm.EstimateShear(image, image_epsf)

    logger.info('HSM reports that the image has observed shape and size:')
    logger.info('    e1 = %.3f, e2 = %.3f, sigma = %.3f (pixels)', results.observed_shape.e1,
                results.observed_shape.e2, results.moments_sigma)
    logger.info('When carrying out Regaussianization PSF correction, HSM reports')
    logger.info('    e1, e2 = %.3f, %.3f',
                results.corrected_e1, results.corrected_e2)
    logger.info('Expected values in the limit that noise and non-Gaussianity are negligible:')
    # Convention for shear addition is to apply the second term initially followed by the first.
    # So this needs to be the WCS shear + the galaxy shape in that order.
    total_shape = galsim.Shear(g1=wcs_g1, g2=wcs_g2) + gal_shape
    logger.info('    e1, e2 = %.3f, %.3f', total_shape.e1, total_shape.e2)
예제 #5
0
def test_coadd_image_correct(crazy_wcs, crazy_obj):

    rng = np.random.RandomState(seed=42)

    n_coadd = 10
    psf_dim = 51
    coadd_dim = 53

    coadd_cen = (coadd_dim + 1) / 2

    se_dim = int(np.ceil(coadd_dim * np.sqrt(2)))
    if se_dim % 2 == 0:
        se_dim += 1

    se_cen = (se_dim + 1) / 2
    scale = 0.2
    noise_std = 0.1
    world_origin = galsim.CelestialCoord(0 * galsim.degrees,
                                         0 * galsim.degrees)

    aff = galsim.PixelScale(scale).affine()
    aff = aff.withOrigin(galsim.PositionD(coadd_cen, coadd_cen),
                         galsim.PositionD(0, 0))
    coadd_wcs = galsim.TanWCS(
        aff,
        world_origin,
    )

    def _gen_psf_func(wcs, fwhm):
        def _psf_func(*args, **kargs):
            return galsim.Gaussian(fwhm=fwhm).drawImage(
                nx=101, ny=101,
                wcs=wcs.local(world_pos=world_origin)), galsim.PositionD(0, 0)

        return _psf_func

    wgts = []
    objs = []
    psf_objs = []
    exps = []
    for _ in range(n_coadd):
        if crazy_obj:
            _fwhm = 2.9 * (1.0 + rng.normal() * 0.1)
            _g1 = rng.normal() * 0.3
            _g2 = rng.normal() * 0.3
            obj = galsim.Gaussian(fwhm=_fwhm).shear(g1=_g1, g2=_g2)
        else:
            obj = galsim.Gaussian(fwhm=2.9).shear(g1=-0.1, g2=0.3)

        objs.append(obj)

        if crazy_wcs:
            shear = galsim.Shear(g1=rng.normal() * 0.01,
                                 g2=rng.normal() * 0.01)
            aff = galsim.ShearWCS(scale, shear).affine()
            aff = aff.withOrigin(galsim.PositionD(se_cen, se_cen),
                                 galsim.PositionD(0, 0))
            wcs = galsim.TanWCS(
                aff,
                world_origin,
            )
        else:
            aff = galsim.PixelScale(scale).affine()
            aff = aff.withOrigin(galsim.PositionD(se_cen, se_cen),
                                 galsim.PositionD(0, 0))
            wcs = galsim.TanWCS(
                aff,
                world_origin,
            )

        _noise = noise_std * (1 + (rng.uniform() - 0.5) * 2 * 0.05)
        wgts.append(1.0 / _noise**2)

        bmsk = galsim.ImageI(np.zeros((se_dim, se_dim)))

        img = obj.drawImage(
            nx=se_dim,
            ny=se_dim,
            wcs=wcs.local(world_pos=world_origin),
        )

        if crazy_obj:
            _psf_fwhm = 1.0 * (1.0 + rng.normal() * 0.1)
        else:
            _psf_fwhm = 1.0

        psf = galsim.Gaussian(fwhm=_psf_fwhm)
        psf_objs.append(psf)

        exp = make_exp(
            gsimage=img,
            bmask=bmsk,
            noise=_noise,
            galsim_wcs=wcs,
            galsim_psf=psf,
            psf_dim=psf_dim,
        )
        exps.append(exp)

    coadd_bbox = geom.Box2I(
        geom.IntervalI(min=0, max=coadd_dim - 1),
        geom.IntervalI(min=0, max=coadd_dim - 1),
    )
    coadd, exp_info = make_coadd_obs(
        exps=exps,
        coadd_wcs=make_dm_wcs(coadd_wcs),
        coadd_bbox=coadd_bbox,
        psf_dims=(psf_dim, ) * 2,
        rng=rng,
        remove_poisson=False,
    )

    coadd_img = coadd.image
    coadd_psf = coadd.psf.image

    wgts = np.array(wgts) / np.sum(wgts)
    true_coadd_img = galsim.Sum([
        obj.withFlux(wgt) for obj, wgt in zip(objs, wgts)
    ]).drawImage(nx=coadd_dim,
                 ny=coadd_dim,
                 wcs=coadd_wcs.local(world_pos=world_origin)).array

    true_coadd_psf = galsim.Sum([
        obj.withFlux(wgt) for obj, wgt in zip(psf_objs, wgts)
    ]).drawImage(nx=psf_dim,
                 ny=psf_dim,
                 wcs=coadd_wcs.local(world_pos=world_origin)).array

    if not crazy_wcs:
        rtol = 0
        atol = 5e-7
    else:
        rtol = 0
        atol = 5e-5

    coadd_img_err = np.max(np.abs(coadd_img - true_coadd_img))
    coadd_psf_err = np.max(np.abs(coadd_psf - true_coadd_psf))
    print("image max abs error:", coadd_img_err)
    print("psf max abs error:", coadd_psf_err)

    if not np.allclose(coadd_img, true_coadd_img, rtol=rtol, atol=atol):
        _plot_cmp(coadd_img, true_coadd_img, rtol, atol, crazy_obj, crazy_wcs,
                  "img")

    if not np.allclose(coadd_psf, true_coadd_psf, rtol=rtol, atol=atol):
        _plot_cmp(coadd_psf, true_coadd_psf, rtol, atol, crazy_obj, crazy_wcs,
                  "psf")

    assert np.allclose(coadd_img, true_coadd_img, rtol=rtol, atol=atol)
    assert np.allclose(coadd_psf, true_coadd_psf, rtol=rtol, atol=atol)
    assert np.all(np.isfinite(coadd.noise))
예제 #6
0
파일: config.py 프로젝트: beckermr/misc
import galsim
import numpy as np

jc = galsim.ShearWCS(
    0.263,
    galsim.Shear(g1=np.random.uniform(low=-0.01, high=0.01),
                 g2=np.random.uniform(low=-0.01, high=0.01))).jacobian()

jacobian_dict = {
    'dudx': jc.dudx,
    'dudy': jc.dudy,
    'dvdx': jc.dvdx,
    'dvdy': jc.dvdy
}

gauss_psf = True
n_sims = 100
예제 #7
0
def test_admom_smoke(g1_true, g2_true, wcs_g1, wcs_g2):
    rng = np.random.RandomState(seed=100)

    fwhm = 0.9
    image_size = 107
    cen = (image_size - 1) / 2
    gs_wcs = galsim.ShearWCS(0.125, galsim.Shear(g1=wcs_g1,
                                                 g2=wcs_g2)).jacobian()

    obj = galsim.Gaussian(fwhm=fwhm).shear(g1=g1_true,
                                           g2=g2_true).withFlux(400)
    im = obj.drawImage(nx=image_size,
                       ny=image_size,
                       wcs=gs_wcs,
                       method='no_pixel').array
    noise = np.sqrt(np.sum(im**2)) / 1e18
    wgt = np.ones_like(im) / noise**2
    scale = np.sqrt(gs_wcs.pixelArea())

    g1arr = []
    g2arr = []
    Tarr = []
    for _ in range(50):
        shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        im = obj.shift(dx=shift[0], dy=shift[1]).drawImage(
            nx=image_size,
            ny=image_size,
            wcs=gs_wcs,
            method='no_pixel',
            dtype=np.float64,
        ).array

        jac = Jacobian(y=cen + xy.y,
                       x=cen + xy.x,
                       dudx=gs_wcs.dudx,
                       dudy=gs_wcs.dudy,
                       dvdx=gs_wcs.dvdx,
                       dvdy=gs_wcs.dvdy)

        _im = im + (rng.normal(size=im.shape) * noise)
        obs = Observation(image=_im, weight=wgt, jacobian=jac)

        Tguess = fwhm_to_T(fwhm) + rng.normal() * 0.01
        res = run_admom(obs=obs, guess=Tguess)

        if res['flags'] == 0:
            gm = res.get_gmix()
            _g1, _g2, _T = gm.get_g1g2T()

            g1arr.append(_g1)
            g2arr.append(_g2)
            Tarr.append(_T)

            fim = res.make_image()
            assert fim.shape == im.shape

        res['flags'] = 5
        with pytest.raises(RuntimeError):
            res.make_image()
        with pytest.raises(RuntimeError):
            res.get_gmix()

    g1 = np.mean(g1arr)
    g2 = np.mean(g2arr)
    gtol = 1.5e-6
    assert np.abs(g1 - g1_true) < gtol, (g1,
                                         np.std(g1arr) / np.sqrt(len(g1arr)))
    assert np.abs(g2 - g2_true) < gtol, (g2,
                                         np.std(g2arr) / np.sqrt(len(g2arr)))

    if g1_true == 0 and g2_true == 0:
        T = np.mean(Tarr)
        assert np.abs(T - fwhm_to_T(fwhm)) < 1e-6

    with pytest.raises(ValueError):
        _ = run_admom(None, None)

    # cover some branches
    tres = copy.deepcopy(res)

    tres['flags'] = 0
    tres['sums_cov'][:, :] = np.nan
    tres = ngmix.admom.admom.get_result(tres)
    assert tres['e1err'] == 9999.0

    tres = copy.deepcopy(res)
    tres['flags'] = 0
    tres['pars'][4] = -1
    tres = ngmix.admom.admom.get_result(tres)
    assert tres['flags'] == 0x8
예제 #8
0
파일: test_admom.py 프로젝트: emhuff/ngmix
def test_admom_smoke(g1_true, g2_true, wcs_g1, wcs_g2):
    rng = np.random.RandomState(seed=100)

    fwhm = 0.9
    image_size = 107
    cen = (image_size - 1) / 2
    gs_wcs = galsim.ShearWCS(0.125, galsim.Shear(g1=wcs_g1,
                                                 g2=wcs_g2)).jacobian()

    obj = galsim.Gaussian(fwhm=fwhm).shear(g1=g1_true,
                                           g2=g2_true).withFlux(400)
    im = obj.drawImage(nx=image_size,
                       ny=image_size,
                       wcs=gs_wcs,
                       method='no_pixel').array
    noise = np.sqrt(np.sum(im**2)) / 1e18
    wgt = np.ones_like(im) / noise**2
    scale = np.sqrt(gs_wcs.pixelArea())

    g1arr = []
    g2arr = []
    Tarr = []
    for _ in range(50):
        shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        im = obj.shift(dx=shift[0],
                       dy=shift[1]).drawImage(nx=image_size,
                                              ny=image_size,
                                              wcs=gs_wcs,
                                              method='no_pixel',
                                              dtype=np.float64).array

        jac = Jacobian(y=cen + xy.y,
                       x=cen + xy.x,
                       dudx=gs_wcs.dudx,
                       dudy=gs_wcs.dudy,
                       dvdx=gs_wcs.dvdx,
                       dvdy=gs_wcs.dvdy)

        _im = im + (rng.normal(size=im.shape) * noise)
        obs = Observation(image=_im, weight=wgt, jacobian=jac)
        fitter = Admom(obs, rng=rng)
        try:
            fitter.go(fwhm_to_T(fwhm) + rng.normal() * 0.01)
            res = fitter.get_result()
            if res['flags'] == 0:
                gm = fitter.get_gmix()
                _g1, _g2, _T = gm.get_g1g2T()

                g1arr.append(_g1)
                g2arr.append(_g2)
                Tarr.append(_T)
        except GMixRangeError:
            pass

    g1 = np.mean(g1arr)
    g2 = np.mean(g2arr)
    gtol = 1e-6
    assert np.abs(g1 - g1_true) < gtol, (g1,
                                         np.std(g1arr) / np.sqrt(len(g1arr)))
    assert np.abs(g2 - g2_true) < gtol, (g2,
                                         np.std(g2arr) / np.sqrt(len(g2arr)))

    if g1_true == 0 and g2_true == 0:
        T = np.mean(Tarr)
        assert np.abs(T - fwhm_to_T(fwhm)) < 1e-6
예제 #9
0
def test_ml_fitting_exp_obj_gauss_psf_smoke(g1_true, g2_true, wcs_g1, wcs_g2):
    rng = np.random.RandomState(seed=10)

    image_size = 33
    cen = (image_size - 1) / 2
    gs_wcs = galsim.ShearWCS(0.25, galsim.Shear(g1=wcs_g1,
                                                g2=wcs_g2)).jacobian()
    scale = np.sqrt(gs_wcs.pixelArea())

    g_prior = ngmix.priors.GPriorBA(0.1)
    cen_prior = ngmix.priors.CenPrior(0, 0, scale, scale)
    T_prior = ngmix.priors.FlatPrior(0.01, 2)
    F_prior = ngmix.priors.FlatPrior(1e-4, 1e9)
    prior = ngmix.joint_prior.PriorSimpleSep(cen_prior, g_prior, T_prior,
                                             F_prior)

    gal = galsim.Exponential(half_light_radius=0.5).shear(
        g1=g1_true, g2=g2_true).withFlux(400)
    obj = galsim.Convolve([gal, galsim.Gaussian(fwhm=0.5)])

    psf_im = galsim.Gaussian(fwhm=0.5).drawImage(nx=33,
                                                 ny=33,
                                                 wcs=gs_wcs,
                                                 method='no_pixel').array
    psf_gmix = ngmix.gmix.make_gmix_model(
        [0, 0, 0, 0, fwhm_to_T(0.5), 1], "gauss")
    psf_obs = Observation(image=psf_im, gmix=psf_gmix)

    im = obj.drawImage(nx=image_size,
                       ny=image_size,
                       wcs=gs_wcs,
                       method='no_pixel').array
    noise = np.sqrt(np.sum(im**2)) / 1e16

    wgt = np.ones_like(im) / noise**2

    guess = np.ones(6) * 0.1
    guess[0] = 0
    guess[1] = 0
    guess[2] = g1_true
    guess[3] = g2_true
    guess[4] = fwhm_to_T(0.5)
    guess[5] = 400

    g1arr = []
    g2arr = []
    farr = []
    xarr = []
    yarr = []
    for _ in range(50):
        shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        im = obj.shift(dx=shift[0],
                       dy=shift[1]).drawImage(nx=image_size,
                                              ny=image_size,
                                              wcs=gs_wcs,
                                              method='no_pixel',
                                              dtype=np.float64).array

        jac = Jacobian(y=cen + xy.y,
                       x=cen + xy.x,
                       dudx=gs_wcs.dudx,
                       dudy=gs_wcs.dudy,
                       dvdx=gs_wcs.dvdx,
                       dvdy=gs_wcs.dvdy)

        _im = im + (rng.normal(size=im.shape) * noise)
        obs = Observation(image=_im, weight=wgt, jacobian=jac, psf=psf_obs)
        fitter = LMSimple(obs, 'exp', prior=prior)
        fitter.go(guess + rng.normal(size=6) * 0.01)
        res = fitter.get_result()
        if res['flags'] == 0:
            _g1, _g2, _ = res['g'][0], res['g'][1], res['pars'][4]
            g1arr.append(_g1)
            g2arr.append(_g2)
            farr.append(res['pars'][5])
            xarr.append(res['pars'][1])
            yarr.append(res['pars'][0])

    g1 = np.mean(g1arr)
    g2 = np.mean(g2arr)
    gtol = 1e-5
    assert np.abs(g1 - g1_true) < gtol
    assert np.abs(g2 - g2_true) < gtol

    xerr = np.std(xarr) / np.sqrt(len(xarr))
    assert np.abs(np.mean(xarr)) < xerr * 5
    yerr = np.std(yarr) / np.sqrt(len(yarr))
    assert np.abs(np.mean(yarr)) < yerr * 5
예제 #10
0
def test_admom_smoke(g1_true, g2_true, wcs_g1, wcs_g2, weight_fac):
    rng = np.random.RandomState(seed=100)

    fwhm = 0.9
    image_size = 107
    cen = (image_size - 1) / 2
    gs_wcs = galsim.ShearWCS(0.125, galsim.Shear(g1=wcs_g1,
                                                 g2=wcs_g2)).jacobian()

    obj = galsim.Gaussian(fwhm=fwhm).shear(g1=g1_true,
                                           g2=g2_true).withFlux(400)
    im = obj.drawImage(nx=image_size,
                       ny=image_size,
                       wcs=gs_wcs,
                       method='no_pixel').array
    noise = np.sqrt(np.sum(im**2)) / 1e18
    wgt = np.ones_like(im) / noise**2
    scale = np.sqrt(gs_wcs.pixelArea())

    g1arr = []
    g2arr = []
    Tarr = []
    for _ in range(50):
        shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        im = obj.shift(dx=shift[0],
                       dy=shift[1]).drawImage(nx=image_size,
                                              ny=image_size,
                                              wcs=gs_wcs,
                                              method='no_pixel',
                                              dtype=np.float64).array

        jac = Jacobian(y=cen + xy.y,
                       x=cen + xy.x,
                       dudx=gs_wcs.dudx,
                       dudy=gs_wcs.dudy,
                       dvdx=gs_wcs.dvdx,
                       dvdy=gs_wcs.dvdy)

        _im = im + (rng.normal(size=im.shape) * noise)
        obs = Observation(image=_im, weight=wgt, jacobian=jac)
        # use a huge weight so that we get the raw moments back out
        fitter = GaussMom(obs, fwhm * weight_fac, rng=rng)
        try:
            fitter.go()
            res = fitter.get_result()
            if res['flags'] == 0:
                if weight_fac > 1:
                    _g1, _g2 = e1e2_to_g1g2(res['e'][0], res['e'][1])
                else:
                    _g1, _g2 = res['e'][0], res['e'][1]
                g1arr.append(_g1)
                g2arr.append(_g2)
                Tarr.append(res['pars'][4])
        except GMixRangeError:
            pass

    g1 = np.mean(g1arr)
    g2 = np.mean(g2arr)

    gtol = 1e-9
    assert np.abs(g1 - g1_true) < gtol, (g1,
                                         np.std(g1arr) / np.sqrt(len(g1arr)))
    assert np.abs(g2 - g2_true) < gtol, (g2,
                                         np.std(g2arr) / np.sqrt(len(g2arr)))

    # T test should only pass when the weight function is constant so
    # weight_fac needs to be rally big
    if g1_true == 0 and g2_true == 0 and weight_fac > 1:
        T = np.mean(Tarr)
        assert np.abs(T - fwhm_to_T(fwhm)) < 1e-6
예제 #11
0
def test_ml_fitting_exp_obj_gauss_psf_smoke(
        g1_true, g2_true, wcs_g1, wcs_g2, fit_model):

    rng = np.random.RandomState(seed=10)

    image_size = 33
    cen = (image_size - 1)/2
    gs_wcs = galsim.ShearWCS(
        0.25, galsim.Shear(g1=wcs_g1, g2=wcs_g2)).jacobian()
    scale = np.sqrt(gs_wcs.pixelArea())

    gal = galsim.Exponential(
        half_light_radius=0.5
    ).shear(
        g1=g1_true, g2=g2_true
    ).withFlux(
        400,
    )

    obj = galsim.Convolve([gal, galsim.Gaussian(fwhm=0.5)])

    psf_im = galsim.Gaussian(fwhm=0.5).drawImage(
        nx=33, ny=33, wcs=gs_wcs, method='no_pixel').array
    psf_gmix = ngmix.gmix.make_gmix_model(
        [0, 0, 0, 0, fwhm_to_T(0.5), 1], "gauss")
    psf_obs = Observation(
        image=psf_im,
        gmix=psf_gmix
    )

    im = obj.drawImage(
        nx=image_size,
        ny=image_size,
        wcs=gs_wcs,
        method='no_pixel',
    ).array
    noise = np.sqrt(np.sum(im**2)) / 1e16

    wgt = np.ones_like(im) / noise**2

    prior = get_prior(fit_model=fit_model, rng=rng, scale=scale)
    guess = prior.sample()
    guess[0] = 0
    guess[1] = 0
    guess[2] = g1_true
    guess[3] = g2_true
    guess[4] = fwhm_to_T(0.5)

    if fit_model == 'bd':
        guess[5] = 1.0
        guess[6] = 0.5
        guess[7] = 400
    elif fit_model == 'bdf':
        guess[6] = 400
    else:
        guess[5] = 400

    g1arr = []
    g2arr = []
    farr = []
    xarr = []
    yarr = []

    fitter = Fitter(model=fit_model, prior=prior)

    for _ in range(50):
        shift = rng.uniform(low=-scale/2, high=scale/2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        im = obj.shift(
            dx=shift[0], dy=shift[1]
        ).drawImage(
            nx=image_size,
            ny=image_size,
            wcs=gs_wcs,
            method='no_pixel',
            dtype=np.float64).array

        jac = Jacobian(
            y=cen + xy.y, x=cen + xy.x,
            dudx=gs_wcs.dudx, dudy=gs_wcs.dudy,
            dvdx=gs_wcs.dvdx, dvdy=gs_wcs.dvdy)

        _im = im + (rng.normal(size=im.shape) * noise)
        obs = Observation(
            image=_im,
            weight=wgt,
            jacobian=jac,
            psf=psf_obs)

        res = fitter.go(
            obs=obs, guess=guess + rng.normal(size=guess.size) * 0.01,
        )
        if res['flags'] == 0:
            _g1, _g2, _ = res['g'][0], res['g'][1], res['pars'][4]
            g1arr.append(_g1)
            g2arr.append(_g2)
            farr.append(res['pars'][5])
            xarr.append(res['pars'][1])
            yarr.append(res['pars'][0])

    g1 = np.mean(g1arr)
    g2 = np.mean(g2arr)

    if fit_model == 'bd':
        # bd fitting is highly degenerate, we don't recover the
        # ellipticity with as much accuracy
        gtol = 0.002
    else:
        gtol = 1.0e-5

    assert np.abs(g1 - g1_true) < gtol
    assert np.abs(g2 - g2_true) < gtol

    xerr = np.std(xarr) / np.sqrt(len(xarr))
    assert np.abs(np.mean(xarr)) < xerr * 5
    yerr = np.std(yarr) / np.sqrt(len(yarr))
    assert np.abs(np.mean(yarr)) < yerr * 5
예제 #12
0
def test_ml_fitting_galsim_spergel_smoke():

    rng = np.random.RandomState(seed=2312)
    scale = 0.263
    prior = get_prior_galsimfit(model='spergel', rng=rng, scale=scale)

    psf_fwhm = 0.9
    psf_image_size = 33
    image_size = 51

    noise = 0.001

    hlr = 0.1
    flux = 400

    gs_wcs = galsim.ShearWCS(
        scale,
        galsim.Shear(g1=0.01, g2=-0.01),
    ).jacobian()

    psf_im = galsim.Gaussian(fwhm=psf_fwhm).drawImage(
        nx=psf_image_size,
        ny=psf_image_size,
        wcs=gs_wcs,
    ).array

    psf_cen = (psf_image_size - 1.0) / 2.0
    psf_jac = ngmix.Jacobian(
        y=psf_cen,
        x=psf_cen,
        dudx=gs_wcs.dudx,
        dudy=gs_wcs.dudy,
        dvdx=gs_wcs.dvdx,
        dvdy=gs_wcs.dvdy,
    )

    psf_obs = ngmix.Observation(
        image=psf_im,
        jacobian=psf_jac,
    )

    guess = prior.sample()

    fitter = ngmix.fitting.GalsimSpergelFitter(prior=prior)

    shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
    xy = gs_wcs.toImage(galsim.PositionD(shift))

    g1_true, g2_true = prior.g_prior.sample2d()
    gal = galsim.Exponential(half_light_radius=hlr, ).shear(
        g1=g1_true, g2=g2_true).withFlux(flux, )

    obj = galsim.Convolve([gal, galsim.Gaussian(fwhm=psf_fwhm)])

    im = obj.shift(dx=shift[0], dy=shift[1]).drawImage(
        nx=image_size,
        ny=image_size,
        wcs=gs_wcs,
        dtype=np.float64,
    ).array
    wgt = np.ones_like(im) / noise**2

    cen = (np.array(im.shape) - 1) / 2
    jac = ngmix.Jacobian(
        y=cen[0] + xy.y,
        x=cen[1] + xy.x,
        dudx=gs_wcs.dudx,
        dudy=gs_wcs.dudy,
        dvdx=gs_wcs.dvdx,
        dvdy=gs_wcs.dvdy,
    )

    _im = im + (rng.normal(size=im.shape) * noise)
    obs = ngmix.Observation(
        image=_im,
        weight=wgt,
        jacobian=jac,
        psf=psf_obs,
    )

    guess[0] = rng.uniform(low=-0.1, high=0.1)
    guess[1] = rng.uniform(low=-0.1, high=0.1)
    guess[2] = rng.uniform(low=-0.1, high=0.1)
    guess[3] = rng.uniform(low=-0.1, high=0.1)
    guess[4] = hlr * rng.uniform(low=0.9, high=1.1)
    guess[5] = rng.uniform(low=0, high=2)
    guess[6] = flux * rng.uniform(low=0.9, high=1.1)

    res = fitter.go(obs=obs, guess=guess + rng.normal(size=guess.size) * 0.01)
    assert res['flags'] == 0
예제 #13
0
def test_ml_fitting_galsim(wcs_g1, wcs_g2, model, use_prior):

    rng = np.random.RandomState(seed=2312)
    scale = 0.263
    prior = get_prior_galsimfit(model=model, rng=rng, scale=scale)

    psf_fwhm = 0.9
    psf_image_size = 33
    image_size = 51

    noise = 0.001

    hlr = 0.1
    flux = 400
    gs_wcs = galsim.ShearWCS(
        scale,
        galsim.Shear(g1=wcs_g1, g2=wcs_g2),
    ).jacobian()

    psf_im = galsim.Gaussian(fwhm=psf_fwhm).drawImage(
        nx=psf_image_size,
        ny=psf_image_size,
        wcs=gs_wcs,
    ).array

    psf_cen = (psf_image_size - 1.0) / 2.0
    psf_jac = ngmix.Jacobian(
        y=psf_cen,
        x=psf_cen,
        dudx=gs_wcs.dudx,
        dudy=gs_wcs.dudy,
        dvdx=gs_wcs.dvdx,
        dvdy=gs_wcs.dvdy,
    )

    psf_obs = ngmix.Observation(
        image=psf_im,
        jacobian=psf_jac,
    )

    guess = prior.sample()
    g1arr = []
    g2arr = []
    farr = []
    xarr = []
    yarr = []

    if use_prior:
        send_prior = prior
    else:
        send_prior = None

    fitter = ngmix.fitting.GalsimFitter(model=model, prior=send_prior)

    if model == 'exp' and use_prior:
        ntrial = 50
    else:
        ntrial = 1

    for _ in range(ntrial):
        shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        g1_true, g2_true = prior.g_prior.sample2d()
        gal = galsim.Exponential(half_light_radius=hlr, ).shear(
            g1=g1_true, g2=g2_true).withFlux(flux, )

        obj = galsim.Convolve([gal, galsim.Gaussian(fwhm=psf_fwhm)])

        im = obj.shift(dx=shift[0], dy=shift[1]).drawImage(
            nx=image_size,
            ny=image_size,
            wcs=gs_wcs,
            dtype=np.float64,
        ).array
        wgt = np.ones_like(im) / noise**2

        cen = (np.array(im.shape) - 1) / 2
        jac = ngmix.Jacobian(
            y=cen[0] + xy.y,
            x=cen[1] + xy.x,
            dudx=gs_wcs.dudx,
            dudy=gs_wcs.dudy,
            dvdx=gs_wcs.dvdx,
            dvdy=gs_wcs.dvdy,
        )

        _im = im + (rng.normal(size=im.shape) * noise)
        obs = ngmix.Observation(
            image=_im,
            weight=wgt,
            jacobian=jac,
            psf=psf_obs,
        )

        guess[0] = rng.uniform(low=-0.1, high=0.1)
        guess[1] = rng.uniform(low=-0.1, high=0.1)
        guess[2] = rng.uniform(low=-0.1, high=0.1)
        guess[3] = rng.uniform(low=-0.1, high=0.1)
        guess[4] = hlr * rng.uniform(low=0.9, high=1.1)
        guess[5] = flux * rng.uniform(low=0.9, high=1.1)

        res = fitter.go(obs=obs,
                        guess=guess + rng.normal(size=guess.size) * 0.01)
        if res['flags'] == 0:
            _g1, _g2, _ = res['g'][0], res['g'][1], res['pars'][4]
            g1arr.append(_g1 - g1_true)
            g2arr.append(_g2 - g2_true)
            farr.append(res['pars'][5])
            xarr.append(res['pars'][1])
            yarr.append(res['pars'][0])

    if model == 'exp' and use_prior:
        g1diff = np.mean(g1arr)
        g2diff = np.mean(g2arr)

        print('g1vals')
        print(g1arr)
        print(g1diff)
        print('g2vals')
        print(g2arr)
        print(g2diff)

        gtol = 1.0e-5

        assert np.abs(g1diff) < gtol
        assert np.abs(g2diff) < gtol

        xerr = np.std(xarr) / np.sqrt(len(xarr))
        assert np.abs(np.mean(xarr)) < xerr * 5
        yerr = np.std(yarr) / np.sqrt(len(yarr))
        assert np.abs(np.mean(yarr)) < yerr * 5
예제 #14
0
def test_ml_max_fitting_gauss_smoke(g1_true, g2_true, wcs_g1, wcs_g2):
    rng = np.random.RandomState(seed=42)

    # allow some small relative bias due to approximate exp function
    tol = 1.0e-5

    flux = 400  # in galsim units
    image_size = 33
    cen = (image_size - 1) / 2
    gs_wcs = galsim.ShearWCS(0.25, galsim.Shear(g1=wcs_g1,
                                                g2=wcs_g2)).jacobian()
    scale = np.sqrt(gs_wcs.pixelArea())

    g_prior = ngmix.priors.GPriorBA(sigma=0.2, rng=rng)
    cen_prior = ngmix.priors.CenPrior(
        cen1=0,
        cen2=0,
        sigma1=scale,
        sigma2=scale,
        rng=rng,
    )
    T_prior = ngmix.priors.FlatPrior(minval=0.1, maxval=2, rng=rng)
    F_prior = ngmix.priors.FlatPrior(minval=1e-4, maxval=1e9, rng=rng)
    prior = ngmix.joint_prior.PriorSimpleSep(
        cen_prior=cen_prior,
        g_prior=g_prior,
        T_prior=T_prior,
        F_prior=F_prior,
    )

    obj = galsim.Gaussian(fwhm=0.9).shear(g1=g1_true,
                                          g2=g2_true).withFlux(flux, )
    im = obj.drawImage(nx=image_size,
                       ny=image_size,
                       wcs=gs_wcs,
                       method='no_pixel').array

    noise = np.sqrt(np.sum(im**2)) / 1.e6
    wgt = np.ones_like(im) / noise**2

    g1arr = []
    g2arr = []
    Tarr = []
    farr = []
    xarr = []
    yarr = []
    for _ in range(10):
        shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        im = obj.shift(dx=shift[0],
                       dy=shift[1]).drawImage(nx=image_size,
                                              ny=image_size,
                                              wcs=gs_wcs,
                                              method='no_pixel',
                                              dtype=np.float64).array

        jac = Jacobian(
            y=cen + xy.y,
            x=cen + xy.x,
            dudx=gs_wcs.dudx,
            dudy=gs_wcs.dudy,
            dvdx=gs_wcs.dvdx,
            dvdy=gs_wcs.dvdy,
        )

        _im = im + rng.normal(size=im.shape, scale=noise)
        obs = Observation(
            image=_im,
            weight=wgt,
            jacobian=jac,
        )

        prior = None
        fitter = Fitter(model='gauss', prior=prior)

        guess = np.zeros(6)
        guess[0:2] = rng.uniform(low=-0.1 * scale, high=0.1 * scale, size=2)
        guess[2] = g1_true + rng.uniform(low=-0.01, high=0.01)
        guess[3] = g2_true + rng.uniform(low=-0.01, high=0.01)
        guess[4] = fwhm_to_T(0.9) * rng.uniform(low=0.99, high=1.01)
        guess[5] = flux * rng.uniform(low=0.99, high=1.01)

        res = fitter.go(obs=obs, guess=guess)

        if res['flags'] == 0:
            _g1, _g2, _T = res['g'][0], res['g'][1], res['pars'][4]
            g1arr.append(_g1)
            g2arr.append(_g2)
            Tarr.append(_T)
            farr.append(res['pars'][5])
            xarr.append(res['pars'][1])
            yarr.append(res['pars'][0])

    assert len(g1arr) > 0
    g1 = np.mean(g1arr)
    g2 = np.mean(g2arr)
    assert np.abs(g1 - g1_true) < tol
    assert np.abs(g2 - g2_true) < tol

    if g1_true == 0 and g2_true == 0:
        T = np.mean(Tarr)
        Ttrue = fwhm_to_T(0.9)
        assert T / Ttrue - 1 < tol

    fmn = np.mean(farr)

    assert np.abs(fmn / flux - 1) < tol

    xerr = np.std(xarr) / np.sqrt(len(xarr))
    assert np.abs(np.mean(xarr)) < xerr * 5
    yerr = np.std(yarr) / np.sqrt(len(yarr))
    assert np.abs(np.mean(yarr)) < yerr * 5
예제 #15
0
def run_metacal(*, n_sims, wcs_g1, wcs_g2):
    """Run metacal and measure m and c.

    The resulting m and c are printed to STDOUT.

    Parameters
    ----------
    n_sims : int
        The number of objects to simulated.
    wcs_g1 : float
        The shear on the 1-axis of the WCS Jacobian.
    wcs_g2 : float
        The shear on the 2-axis of the WCS Jacobian.
    """
    jc = galsim.ShearWCS(0.263, galsim.Shear(g1=wcs_g1, g2=wcs_g2)).jacobian()

    jacobian_dict = {
        'dudx': jc.dudx,
        'dudy': jc.dudy,
        'dvdx': jc.dvdx,
        'dvdy': jc.dvdy
    }

    swap_g1g2 = False

    res = _run_metacal(n_sims=n_sims,
                       rng=np.random.RandomState(seed=10),
                       swap_g1g2=swap_g1g2,
                       **jacobian_dict)

    g1 = np.array([r['noshear']['g'][0] for r in res])
    g2 = np.array([r['noshear']['g'][1] for r in res])
    g1p = np.array([r['1p']['g'][0] for r in res])
    g1m = np.array([r['1m']['g'][0] for r in res])
    g2p = np.array([r['2p']['g'][1] for r in res])
    g2m = np.array([r['2m']['g'][1] for r in res])

    g_true = 0.02
    step = 0.01

    if swap_g1g2:
        R11 = (g1p - g1m) / 2 / step
        R22 = (g2p - g2m) / 2 / step * g_true

        m, merr, c, cerr = _jack_est(g2, R22, g1, R11)
    else:
        R11 = (g1p - g1m) / 2 / step * g_true
        R22 = (g2p - g2m) / 2 / step

        m, merr, c, cerr = _jack_est(g1, R11, g2, R22)

    print("""\
# of sims: {n_sims}
wcs_g1   : {wcs_g1:f}
wcs_g2   : {wcs_g2:f}
dudx     : {dudx:f}
dudy     : {dudy:f}
dvdx     : {dvdx:f}
dvdy     : {dvdy:f}
m [1e-3] : {m:f} +/- {msd:f}
c [1e-4] : {c:f} +/- {csd:f}""".format(n_sims=len(g1),
                                       wcs_g1=wcs_g1,
                                       wcs_g2=wcs_g2,
                                       **jacobian_dict,
                                       m=m / 1e-3,
                                       msd=merr / 1e-3,
                                       c=c / 1e-4,
                                       csd=cerr / 1e-4),
          flush=True)
예제 #16
0
def test_ml_fitting_gauss_smoke(g1_true, g2_true, wcs_g1, wcs_g2):
    rng = np.random.RandomState(seed=42)

    # allow some small relative bias due to approximate exp function
    tol = 1.0e-5

    image_size = 33
    cen = (image_size - 1) / 2
    gs_wcs = galsim.ShearWCS(0.25, galsim.Shear(g1=wcs_g1,
                                                g2=wcs_g2)).jacobian()
    scale = np.sqrt(gs_wcs.pixelArea())

    g_prior = ngmix.priors.GPriorBA(0.2)
    cen_prior = ngmix.priors.CenPrior(0, 0, scale, scale)
    T_prior = ngmix.priors.FlatPrior(0.1, 2)
    F_prior = ngmix.priors.FlatPrior(1e-4, 1e9)
    prior = ngmix.joint_prior.PriorSimpleSep(cen_prior, g_prior, T_prior,
                                             F_prior)

    obj = galsim.Gaussian(fwhm=0.9).shear(g1=g1_true, g2=g2_true).withFlux(400)
    im = obj.drawImage(nx=image_size,
                       ny=image_size,
                       wcs=gs_wcs,
                       method='no_pixel').array
    noise = np.sqrt(np.sum(im**2)) / 1e16
    wgt = np.ones_like(im) / noise**2

    g1arr = []
    g2arr = []
    Tarr = []
    farr = []
    xarr = []
    yarr = []
    for _ in range(100):
        shift = rng.uniform(low=-scale / 2, high=scale / 2, size=2)
        xy = gs_wcs.toImage(galsim.PositionD(shift))

        im = obj.shift(dx=shift[0],
                       dy=shift[1]).drawImage(nx=image_size,
                                              ny=image_size,
                                              wcs=gs_wcs,
                                              method='no_pixel',
                                              dtype=np.float64).array

        jac = Jacobian(y=cen + xy.y,
                       x=cen + xy.x,
                       dudx=gs_wcs.dudx,
                       dudy=gs_wcs.dudy,
                       dvdx=gs_wcs.dvdx,
                       dvdy=gs_wcs.dvdy)

        _im = im + (rng.normal(size=im.shape) * noise)
        obs = Observation(image=_im, weight=wgt, jacobian=jac)
        fitter = LMSimple(obs, 'gauss', prior=prior)

        guess = np.ones(6) * 0.1
        guess[0] = 0
        guess[1] = 0
        guess[2] = g1_true
        guess[3] = g2_true
        guess[4] = fwhm_to_T(0.9)
        guess[5] = 400 * scale * scale

        fitter.go(guess + rng.normal(size=6) * 0.01)
        res = fitter.get_result()

        if res['flags'] == 0:
            _g1, _g2, _T = res['g'][0], res['g'][1], res['pars'][4]
            g1arr.append(_g1)
            g2arr.append(_g2)
            Tarr.append(_T)
            farr.append(res['pars'][5])
            xarr.append(res['pars'][1])
            yarr.append(res['pars'][0])

    g1 = np.mean(g1arr)
    g2 = np.mean(g2arr)
    assert np.abs(g1 - g1_true) < tol
    assert np.abs(g2 - g2_true) < tol

    if g1_true == 0 and g2_true == 0:
        T = np.mean(Tarr)
        Ttrue = fwhm_to_T(0.9)
        assert T / Ttrue - 1 < tol

    fmn = np.mean(farr) / scale / scale

    assert np.abs(fmn / 400 - 1) < tol

    xerr = np.std(xarr) / np.sqrt(len(xarr))
    assert np.abs(np.mean(xarr)) < xerr * 5
    yerr = np.std(yarr) / np.sqrt(len(yarr))
    assert np.abs(np.mean(yarr)) < yerr * 5