Example #1
0
    def setlocal(self, obj):
        """Get the pixel positions, local pixel scale, and local PSF."""

        xx, yy = self.wcs.positionToPixel(RaDecPos(obj['ra'], obj['dec']))
        self.pos = galsim.PositionD(xx, yy)
        self.xpos = int(self.pos.x)
        self.ypos = int(self.pos.y)
        self.offset = galsim.PositionD(self.pos.x - self.xpos,
                                       self.pos.y - self.ypos)

        # Get the local pixel scale [arcsec/pixel]
        cd = self.wcs.cdAtPixel(self.pos.x, self.pos.y)
        self.pixscale = np.sqrt(np.linalg.det(cd)) * 3600.0

        # Get the local PSF
        psfim = self.psf.getPointSourcePatch(self.xpos, self.ypos).getImage()
        #plt.imshow(psfim) ; plt.show()

        self.localpsf = galsim.InterpolatedImage(galsim.Image(psfim),
                                                 scale=self.pixscale)
Example #2
0
def generate_data(n_samples=100):
    # generate as Norm(0, 1) for all parameters
    np_rng = np.random.RandomState(1234)
    X = np_rng.normal(0, 1, size=(n_samples, len(keys)))
    y = np_rng.normal(0, 1, size=(n_samples, ntarget))

    star_list = []
    for Xi, yi in zip(X, y):
        wcs = galsim.JacobianWCS(0.26, 0.05, -0.08, -0.29)
        image = galsim.Image(64,64, wcs=wcs)
        properties = {k:v for k,v in zip(keys, Xi)}
        stardata = piff.StarData(image, image.true_center, properties=properties)

        # params = np.array([yi[ith] for ith in attr_target])
        params = yi
        starfit = piff.StarFit(params)
        star = piff.Star(stardata, starfit)
        star_list.append(star)

    return star_list
Example #3
0
 def check_noise(noise_image, noise, msg):
     # A helper function to check that the current noise in the image is properly described
     # by the given CorrelatedNoise object
     noise2 = galsim.CorrelatedNoise(noise_image)
     print('noise = ', noise)
     print('noise2 = ', noise2)
     np.testing.assert_almost_equal(noise.getVariance(),
                                    noise2.getVariance(),
                                    decimal=CHECKNOISE_NDECIMAL,
                                    err_msg=msg +
                                    ': variance does not match.')
     cf_im1 = galsim.Image(8, 8, wcs=noise_image.wcs)
     cf_im2 = cf_im1.copy()
     noise.drawImage(image=cf_im1)
     noise2.drawImage(image=cf_im2)
     np.testing.assert_almost_equal(cf_im1.array,
                                    cf_im2.array,
                                    decimal=CHECKNOISE_NDECIMAL,
                                    err_msg=msg +
                                    ': image of cf does not match.')
Example #4
0
    def add_background(self,
                       im,
                       thermal_backgrounds=None,
                       filter_='H158',
                       phot=False):
        sky_stamp = galsim.Image(bounds=self.b, scale=wfirst.pixel_scale)
        #local_wcs.makeSkyImage(sky_stamp, sky_level)

        # This image is in units of e-/pix. Finally we add the expected thermal backgrounds in this
        # band. These are provided in e-/pix/s, so we have to multiply by the exposure time.
        if thermal_backgrounds is None:
            sky_stamp += wfirst.thermal_backgrounds[filter_] * wfirst.exptime
        else:
            sky_stamp += thermal_backgrounds * wfirst.exptime

        # Adding sky level to the image.
        if not phot:
            im += sky_stamp

        return im, sky_stamp
Example #5
0
def test_airy_shoot():
    """Test Airy with photon shooting.  Particularly the flux of the final image.
    """
    # Airy patterns have *very* extended wings, so make this really small and the image really
    # big to make sure we capture all the photons.
    rng = galsim.BaseDeviate(1234)
    obj = galsim.Airy(lam_over_diam=0.01, flux=1.e4)
    im = galsim.Image(1000, 1000, scale=1)
    im.setCenter(0, 0)
    added_flux, photons = obj.drawPhot(im,
                                       poisson_flux=False,
                                       rng=rng.duplicate())
    print('obj.flux = ', obj.flux)
    print('added_flux = ', added_flux)
    print('photon fluxes = ', photons.flux.min(), '..', photons.flux.max())
    print('image flux = ', im.array.sum())
    assert np.isclose(added_flux, obj.flux)
    assert np.isclose(im.array.sum(), obj.flux)
    photons2 = obj.makePhot(poisson_flux=False, rng=rng)
    assert photons2 == photons, "Airy makePhot not equivalent to drawPhot"

    obj = galsim.Airy(lam_over_diam=0.01, flux=1.e4, obscuration=0.4)
    added_flux, photons = obj.drawPhot(im,
                                       poisson_flux=False,
                                       rng=rng.duplicate())
    print('obj.flux = ', obj.flux)
    print('added_flux = ', added_flux)
    print('photon fluxes = ', photons.flux.min(), '..', photons.flux.max())
    print('image flux = ', im.array.sum())
    assert np.isclose(added_flux, obj.flux)
    assert np.isclose(im.array.sum(), obj.flux)
    photons2 = obj.makePhot(poisson_flux=False, rng=rng.duplicate())
    assert photons2 == photons, "Airy makePhot not equivalent to drawPhot"

    # Can treat the profile as a convolution of a delta function and put it in a photon_ops list.
    delta = galsim.DeltaFunction(flux=1.e4)
    psf = galsim.Airy(lam_over_diam=0.01, obscuration=0.4)
    photons3 = delta.makePhot(poisson_flux=False,
                              rng=rng.duplicate(),
                              photon_ops=[psf])
    assert photons3 == photons, "Using Airy in photon_ops not equivalent to drawPhot"
Example #6
0
def test_strict():
    """Check that using strict=True results in the behavior we expect."""
    # Set up an image for which moments measurement should fail spectacularly.
    scale = 2.7
    size = 11
    pix = galsim.Pixel(scale)
    image = galsim.Image(size, size)
    im = pix.drawImage(image=image, scale=scale, method='no_pixel')

    # Try to measure moments with strict = False. Make sure there's an error message stored.
    res = im.FindAdaptiveMom(strict=False)
    if res.error_message == '':
        raise AssertionError(
            "Should have error message stored in case of FindAdaptiveMom failure!"
        )

    # Check that measuring moments with strict = True results in the expected exception, and that
    # it is the same one as is stored when running with strict = False.
    with assert_raises(galsim.GalSimError):
        galsim.hsm.FindAdaptiveMom(im)
    try:
        res2 = im.FindAdaptiveMom()
    except galsim.GalSimError as err:
        if str(err) != res.error_message:
            raise AssertionError(
                "Error messages do not match when running identical tests!")

    # Now redo the above for EstimateShear
    res = galsim.hsm.EstimateShear(im, im, strict=False)
    if res.error_message == '':
        raise AssertionError(
            "Should have error message stored in case of EstimateShear failure!"
        )
    with assert_raises(galsim.GalSimError):
        galsim.hsm.EstimateShear(im, im)
    try:
        res2 = galsim.hsm.EstimateShear(im, im)
    except galsim.GalSimError as err:
        if str(err) != res.error_message:
            raise AssertionError(
                "Error messages do not match when running identical tests!")
Example #7
0
    def test_round_trip(self):
        """
        Test writing out an image with an LsstWCS, reading it back in, and comparing
        the resulting pixel -> ra, dec mappings
        """

        start = time.clock()

        path, filename = os.path.split(__file__)

        im0 = galsim.Image(int(4000), int(4000), wcs=self.wcs)

        outputFile = os.path.join(path,'scratch_space','lsst_roundtrip_img.fits')
        if os.path.exists(outputFile):
            os.unlink(outputFile)
        im0.write(outputFile)

        im1 = galsim.fits.read(outputFile)

        xPix = []
        yPix = []
        pixPts = []
        for xx in range(0, 4000, 100):
            for yy in range(0, 4000, 100):
                xPix.append(xx)
                yPix.append(yy)
                pixPts.append(galsim.PositionI(xx, yy))

        xPix = np.array(xPix)
        yPix = np.array(yPix)

        ra_control, dec_control = self.wcs._radec(xPix, yPix)
        for rr, dd, pp in zip(ra_control, dec_control, pixPts):
            ra_dec_test = im1.wcs.toWorld(pp)
            self.assertAlmostEqual(rr, ra_dec_test.ra/galsim.radians, 12)
            self.assertAlmostEqual(dd, ra_dec_test.dec/galsim.radians, 12)

        if os.path.exists(outputFile):
            os.unlink(outputFile)

        print 'time to run %s = %e sec' % (funcname(), time.clock()-start)
Example #8
0
def setup():
    """Build an input image and catalog used by a few tests below.
    """
    wcs = galsim.TanWCS(
            galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024,1024)),
            #galsim.AffineTransform(0.26, 0., 0., 0.26, galsim.PositionD(1024,1024)),
            galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)
            )

    # Make the image (copied from test_single_image in test_simple.py)
    image = galsim.Image(2048, 2048, wcs=wcs)

    # Where to put the stars.
    x_list = [ 123.12, 345.98, 567.25, 1094.94, 924.15, 1532.74, 1743.11, 888.39, 1033.29, 1409.31 ]
    y_list = [ 345.43, 567.45, 1094.32, 924.29, 1532.92, 1743.83, 888.83, 1033.19, 1409.20, 123.11 ]

    # Draw a Gaussian PSF at each location on the image.
    sigma = 1.3
    g1 = 0.23
    g2 = -0.17
    du = 0.09  # in arcsec
    dv = -0.07
    flux = 123.45
    psf = galsim.Gaussian(sigma=sigma).shear(g1=g1, g2=g2).shift(du,dv) * flux
    for x, y in zip(x_list, y_list):
        bounds = galsim.BoundsI(int(x-31), int(x+32), int(y-31), int(y+32))
        offset = galsim.PositionD(x-int(x)-0.5, y-int(y)-0.5)
        psf.drawImage(image=image[bounds], method='no_pixel', offset=offset)
    image.addNoise(galsim.GaussianNoise(rng=galsim.BaseDeviate(1234), sigma=1e-6))

    # Write out the image to a file
    image_file = os.path.join('output','test_stats_image.fits')
    image.write(image_file)

    # Write out the catalog to a file
    dtype = [ ('x','f8'), ('y','f8') ]
    data = np.empty(len(x_list), dtype=dtype)
    data['x'] = x_list
    data['y'] = y_list
    cat_file = os.path.join('output','test_stats_cat.fits')
    fitsio.write(cat_file, data, clobber=True)
Example #9
0
def test_structure_function():
    """Test that AtmosphericScreen generates the right structure function.
    """
    if __name__ == '__main__':
        L0s = [10.0, 25.0, 100.0]
        screen_size = 300.0
    else:
        L0s = [10.0]
        screen_size = 100.0

    rng = galsim.BaseDeviate(4815162342)
    lam = 500.0
    r0_500 = 0.2
    screen_scale = 0.05

    for L0 in L0s:
        screen = galsim.AtmosphericScreen(screen_size=screen_size, screen_scale=screen_scale,
                                          r0_500=r0_500, L0=L0, rng=rng)
        screen.instantiate()
        vk = galsim.VonKarman(lam=lam, r0=r0_500*(lam/500.0)**1.2, L0=L0)
        phase = screen._tab2d.getVals()[:-1, :-1] * 2 * np.pi / 500.0  # nm -> radians

        var = np.var(phase)
        # Conan 2008 eq 16
        # 0.0863 ~= Gamma(11/6) Gamma(5/6) / (2 pi^(8/3)) (24/5 Gamma(6/5))^(5/6)
        expected_var = 0.0863 * (r0_500/L0)**(-5/3.)
        np.testing.assert_allclose(
            var, expected_var, rtol=0.025,
            err_msg="Simulated variance disagrees with expected variance.")

        im = galsim.Image(phase, scale=screen_scale)
        D_sim = galsim.utilities.structure_function(im)

        print("r     D_VK     D_sim")
        for r in [0.1, 1.0, 10.0]:
            analytic_SF = vk._structure_function(r)
            simulated_SF = D_sim(r)
            print(r, analytic_SF, simulated_SF)
            np.testing.assert_allclose(
                    analytic_SF, simulated_SF, rtol=0.05,
                    err_msg="Simulated structure function not close to prediction.")
Example #10
0
def test_forwardbackward():
    """Test invariance (to first order) under forward-backward transformation.
    """
    galflux = 3000.
    galsigma = 3.
    noise = 1.
    shiftcoeff = 1.e-7
    alpha = 0.3
    size = 50

    gal = galsim.Gaussian(flux=galflux, sigma=galsigma)
    maxflux = gal.xValue(0, 0)
    image = gal.drawImage(scale=1., dtype=np.float64)

    cimage = galsim.Image(image.bounds, dtype=np.float64)
    # used for normalization later, we expect residual to be of this order
    cimage.fill(1.e-3)
    cimage = cimage + image
    cimage = cimage * maxflux * maxflux * shiftcoeff * shiftcoeff

    # Define a consistent rng for repeatability
    urng = galsim.UniformDeviate(rseed)
    image.addNoise(galsim.GaussianNoise(sigma=noise, rng=urng))
    cd = galsim.cdmodel.PowerLawCD(2, shiftcoeff * 0.0234,
                                   shiftcoeff * 0.05234, shiftcoeff * 0.01312,
                                   shiftcoeff * 0.00823, shiftcoeff * 0.07216,
                                   shiftcoeff * 0.01934, alpha)

    imagecd = cd.applyForward(image)
    imagecddc = cd.applyBackward(imagecd)

    # residual after forward-backward should be of order a^2 q qmax^2
    imageres = (imagecddc - image) / cimage
    maxres = imageres.array.max()
    minres = imageres.array.min()
    assert maxres < 10, (
        "maximum positive residual of forward-backward transformation is too large"
    )
    assert minres > -10, (
        "maximum negative residual of forward-backward transformation is too large"
    )
Example #11
0
    def __init__(self, pixel_scale=None, nx=None, ny=None, stamp=None,
                 bounds=None, mask=None):

        self.pixel_scale = pixel_scale
        self.nx = nx
        self.ny = ny
        self.bounds = bounds
        self.mask = mask
        self.stamp = stamp

        if self.stamp is None:
            if self.nx is not None and self.ny is not None and self.pixel_scale is not None:
                self.stamp = galsim.Image(self.nx, self.ny, scale=self.pixel_scale)

        else:
            self.nx = self.stamp.array.shape[0]
            self.ny = self.stamp.array.shape[1]
            self.pixel_scale = self.stamp.scale

        if self.bounds is not None:
            self.stamp = self.stamp[bounds]
Example #12
0
def test_init():
    """Test generation of SecondKick profiles
    """
    obscuration = 0.5

    if __name__ == '__main__':
        lams = [300.0, 500.0, 1100.0]
        r0_500s = [0.1, 0.15, 0.3]
        kcrits = [0.1, 0.2, 0.4]
    else:
        lams = [500.0]
        r0_500s = [0.15]
        kcrits = [0.2]
    for lam in lams:
        for r0_500 in r0_500s:
            r0 = r0_500 * (lam / 500)**(6. / 5)
            for kcrit in kcrits:
                t0 = time.time()
                kwargs = {'lam': lam, 'r0': r0, 'kcrit': kcrit, 'diam': 4.0}
                print(kwargs)

                sk = galsim.SecondKick(flux=2.2, **kwargs)
                t1 = time.time()
                print('   stepk, maxk = ', sk.stepk, sk.maxk)
                np.testing.assert_almost_equal(sk.flux, 2.2)
                do_pickle(sk)
                t2 = time.time()

                # Raw sk objects are hard to draw due to a large maxk/stepk ratio.
                # Decrease maxk by convolving in a smallish Gaussian.
                obj = galsim.Convolve(sk, galsim.Gaussian(fwhm=0.2))
                print('   obj stepk, maxk = ', obj.stepk, obj.maxk)
                check_basic(obj, "SecondKick")
                t3 = time.time()
                img = galsim.Image(16, 16, scale=0.2)
                do_shoot(obj, img, "SecondKick")
                t4 = time.time()
                do_kvalue(obj, img, "SecondKick")
                t5 = time.time()
                print(' times = ', t1 - t0, t2 - t1, t3 - t2, t4 - t3, t5 - t4)
Example #13
0
def test_structure_function():
    """Test that AtmosphericScreen generates approximately the right structure function for infinite
    outer scale.
    """
    rng = galsim.BaseDeviate(4815162342)
    r0_500 = 0.2
    L0 = None
    screen_scale = 0.05
    screen_size = 100.0

    # Theoretical pure Kolmogorov structure function (at 500 nm!):
    D_kolm = lambda r: 6.8839 * (r / r0_500)**(5. / 3)

    atm = galsim.AtmosphericScreen(screen_size=screen_size,
                                   screen_scale=screen_scale,
                                   r0_500=r0_500,
                                   L0=L0,
                                   rng=rng)
    phase = atm._tab2d.table.getVals()[:-1, :-1].copy()
    phase *= 2 * np.pi / 500.0  # nm -> radians
    im = galsim.Image(phase, scale=screen_scale)
    D_sim = galsim.utilities.structure_function(im)

    print("r   D_kolm   D_sim")
    for r in [0.5, 2.0,
              5.0]:  # Only check values far from the screen size and scale.
        # We're only attempting to verify that we haven't missed a factor of 2 or pi or
        # something like that here, so set the rtol below to be *very* forgiving.  Since the
        # structure function varies quite quickly as r**(5./3), this is still a useful test.
        # For the parameters above (including the random seed), D_kolm(r) and D_sim(r) are actually
        # consistent at about the 15% level in the test below.  It's difficult to predict how
        # consistent they *should* be though, since the simulated structure function estimate is
        # sensitive to resolution and edge effects, as well as the particular realization of the
        # field.
        print(r, D_kolm(r), D_sim(r))
        np.testing.assert_allclose(
            D_kolm(r),
            D_sim(r),
            rtol=0.5,
            err_msg="Simulated structure function not close to prediction.")
Example #14
0
def test_moffat_shoot():
    """Test Moffat with photon shooting.  Particularly the flux of the final image.
    """
    rng = galsim.BaseDeviate(1234)
    obj = galsim.Moffat(fwhm=3.5, beta=4.7, flux=1.e4)
    im = galsim.Image(500, 500, scale=1)
    im.setCenter(0, 0)
    added_flux, photons = obj.drawPhot(im,
                                       poisson_flux=False,
                                       rng=rng.duplicate())
    print('obj.flux = ', obj.flux)
    print('added_flux = ', added_flux)
    print('photon fluxes = ', photons.flux.min(), '..', photons.flux.max())
    print('image flux = ', im.array.sum())
    assert np.isclose(added_flux, obj.flux)
    assert np.isclose(im.array.sum(), obj.flux)
    photons2 = obj.makePhot(poisson_flux=False, rng=rng)
    assert photons2 == photons, "Moffat makePhot not equivalent to drawPhot"

    # Note: low beta has large wings, so don't go too low.  Also, reduce fwhm a bit.
    obj = galsim.Moffat(fwhm=1.5, beta=1.9, flux=1.e4)
    added_flux, photons = obj.drawPhot(im,
                                       poisson_flux=False,
                                       rng=rng.duplicate())
    print('obj.flux = ', obj.flux)
    print('added_flux = ', added_flux)
    print('photon fluxes = ', photons.flux.min(), '..', photons.flux.max())
    print('image flux = ', im.array.sum())
    assert np.isclose(added_flux, obj.flux)
    assert np.isclose(im.array.sum(), obj.flux)
    photons2 = obj.makePhot(poisson_flux=False, rng=rng.duplicate())
    assert photons2 == photons, "Moffat makePhot not equivalent to drawPhot"

    # Can treat the profile as a convolution of a delta function and put it in a photon_ops list.
    delta = galsim.DeltaFunction(flux=1.e4)
    psf = galsim.Moffat(fwhm=1.5, beta=1.9)
    photons3 = delta.makePhot(poisson_flux=False,
                              rng=rng.duplicate(),
                              photon_ops=[psf])
    assert photons3 == photons, "Using Moffat in photon_ops not equivalent to drawPhot"
Example #15
0
def calculate_fiber_acceptance(fiber_diameter,
                               psf,
                               sampling=100,
                               max_offset=2):
    """
    Calculate the fiber acceptance fraction versus offset for a specified PSF.
    
    Args:
        fiber_diameter: Diameter of the fiber to use with explicit angular units.
        psf: PSF model to use, assumed to be specified in arcseconds.
        sampling: Sampling to use for the calculation. Higher samplings take longer
            but give more accurate results.
        max_offset: Maximum centroid offset to calculate, as a ratio of the
            fiber diameter.
    
    Returns:
        tuple: Tuple (offset,acceptance) where offset is given as a ratio of fiber
            diameter and acceptance is a fraction from 0-1.
    """
    # Render the PSF to an image with size fiber_diameter by (max_offset+1)*fiber_diameter.
    diam_arcsec = (fiber_diameter.to(u.arcsec)).value
    width = 2 * sampling + 1
    height = int(np.ceil((max_offset + 1) * width))
    image = galsim.Image(width, height, scale=diam_arcsec / width)
    psf.shift(dx=0., dy=-0.5 * diam_arcsec * max_offset).drawImage(image=image)
    # Prepare a boolean mask of pixels falling inside the fiber aperture.
    xy = np.arange(width) - 0.5 * (width - 1)
    x, y = np.meshgrid(xy, xy)
    mask = (x**2 + y**2 < (0.5 * width)**2)
    # Loop over centroid offsets.
    offset = np.arange(height - width + 1) / float(width)
    acceptance = np.empty_like(offset)
    for dy in range(height - width):
        acceptance[dy] = np.sum(image.array[dy:dy + width] * mask)
    #return offset,acceptance
    return scipy.interpolate.interp1d(offset,
                                      acceptance,
                                      kind='linear',
                                      copy=True,
                                      bounds_error=True)
Example #16
0
def test_fluxconservation():
    """Test flux conservation of charge deflection model for galaxy and flat image.
    """
    import time
    t1 = time.time()
    galflux = 3.e4
    galsigma = 3.
    noise = 10.
    shiftcoeff = 1.e-7
    alpha = 0.3
    size = 50

    # Define a consistent rng for repeatability
    urng = galsim.UniformDeviate(rseed)

    gal = galsim.Gaussian(flux=galflux, sigma=galsigma)
    image = gal.drawImage(scale=1., dtype=np.float64)
    image.addNoise(galsim.GaussianNoise(sigma=noise, rng=urng))

    flat = galsim.Image(size, size, dtype=np.float64, init_value=1.)
    cd = PowerLawCD(2, shiftcoeff, 0.94 * shiftcoeff, shiftcoeff / 2.4,
                    shiftcoeff / 5., shiftcoeff / 3.7, shiftcoeff / 1.8, alpha)
    imagecd = cd.applyForward(image)
    flatcd = cd.applyForward(flat)

    # Then test
    np.testing.assert_almost_equal(
        image.array.sum(), imagecd.array.sum(), 13 - int(np.log10(galflux)),
        "Galaxy image flux is not left invariant by charge deflection")
    np.testing.assert_almost_equal(
        flat.array.sum(), flatcd.array.sum(), 13 - int(np.log10(galflux)),
        "Flat image flux is not left invariant by charge deflection")

    # Check picklability
    do_pickle(cd, lambda x: x.applyForward(image))
    do_pickle(cd)

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Example #17
0
def get_psf_from_file(psf_dir, survey):
    """Generates a custom PSF galsim model from FITS file(s).

    Args:
        psf_dir (string): directory where the PSF FITS files are
        survey (btk Survey): BTK Survey object

    Returns:
        galsim PSF model
    """
    psf_files = os.listdir(psf_dir)
    if len(psf_files) > 1:
        psf_file = rd.choice(psf_files)
    elif len(psf_files) == 1:
        psf_file = psf_files[0]
    else:
        raise RuntimeError(f"No psf files found in '{psf_dir}'.")
    psf_array = fits.getdata(psf_dir + "/" + psf_file)
    psf_model = galsim.InterpolatedImage(
        galsim.Image(psf_array), scale=survey.pixel_scale).withFlux(1.0)

    return psf_model
    def blankImage(self, detector=None):
        """
        Draw a blank image associated with a specific detector.  The image will have the correct size
        for the given detector.

        param [in] detector is an instantiation of GalSimDetector
        """

        # in order to speed up the code (by a factor of ~2), this method
        # only draws a new blank image the first time it is called on a
        # given detector.  It then caches the blank images it has drawn and
        # uses GalSim's copy() method to return copies of cached blank images
        # whenever they are called for again.

        if detector.name in self.blankImageCache:
            return self.blankImageCache[detector.name].copy()
        else:
            image = galsim.Image(detector.xMaxPix-detector.xMinPix+1, detector.yMaxPix-detector.yMinPix+1,
                                 wcs=detector.wcs)

            self.blankImageCache[detector.name] = image
            return image.copy()
 def postage_stamp(self, image_data=None):
     if not self.is_within_image():
         raise ValueError("The postage stamp is outside the CCD boundary.")
     else:
         if image_data == None:
             f = pyfits.open(self.fname)
             image_data = f[0].data
             f.close()
         im = galsim.Image(image_data)
         boundDifference = (self.rightBound - self.leftBound) - (
             self.topBound - self.bottomBound)
         if boundDifference == 0:
             b = galsim.BoundsI(self.leftBound, self.rightBound,
                                self.bottomBound, self.topBound)
         if boundDifference == 1:
             b = galsim.BoundsI(self.leftBound, self.rightBound,
                                self.bottomBound, self.topBound + 1)
         if boundDifference == -1:
             b = galsim.BoundsI(self.leftBound, self.rightBound + 1,
                                self.bottomBound, self.topBound)
         stamp = im.subImage(b)
         return stamp
Example #20
0
    def _set_coadded_weight_map(self):
        """
        coadd the noise image realizations and take var

        also set the .noise attribute
        """
        coadd_obs = self.coadd_obs
        weights = self.weights

        weight_map = np.zeros((self.ny, self.nx))

        wcs = coadd_obs.jacobian.get_galsim_wcs()

        coadd_noise = galsim.Sum(
            [image * w for image, w in zip(self.noise_images, weights)])
        coadd_noise_image = galsim.Image(self.nx, self.ny, wcs=wcs)
        coadd_noise.drawImage(image=coadd_noise_image, method='no_pixel')

        weight_map[:, :] = 1. / np.var(coadd_noise_image.array)
        coadd_obs.set_weight(weight_map)

        coadd_obs.noise = coadd_noise_image.array
Example #21
0
def get_psf(Args):
    atmospheric_psf_fwhm = Args.zenith_psf_fwhm * Args.airmass**0.6
    if Args.atmospheric_psf_beta > 0:
        atmospheric_psf_model = galsim.Moffat(beta=Args.atmospheric_psf_beta,
                                              fwhm=atmospheric_psf_fwhm)
    else:
        atmospheric_psf_model = galsim.Kolmogorov(fwhm=atmospheric_psf_fwhm)
    lambda_over_diameter = 3600 * math.degrees(
        1e-10 * Args.central_wavelength / Args.mirror_diameter)
    area_ratio = Args.effective_area / (math.pi *
                                        (0.5 * Args.mirror_diameter)**2)
    obscuration_fraction = math.sqrt(1 - area_ratio)
    optical_psf_model = galsim.Airy(lam_over_diam=lambda_over_diameter,
                                    obscuration=obscuration_fraction)
    psf_model = galsim.Convolve(atmospheric_psf_model, optical_psf_model)
    psf_size_pixels = 2 * int(
        math.ceil(10 * atmospheric_psf_fwhm / Args.pixel_scale))
    psf_image = galsim.Image(psf_size_pixels,
                             psf_size_pixels,
                             scale=Args.pixel_scale)
    psf_model.drawImage(image=psf_image)
    return psf_image.array
Example #22
0
    def _set_coadded_image(self):
        """
        do the actual coadding, with appropriate weights

        wcs of final image is that of the *first*, since
        the coadd obs is a copy of that
        """
        coadd_obs = self.coadd_obs
        weights = self.weights

        wcs = coadd_obs.jacobian.get_galsim_wcs()

        coadd = galsim.Sum(
            [image * w for image, w in zip(self.images, weights)])

        coadd_image = galsim.Image(self.nx, self.ny, wcs=wcs)
        coadd.drawImage(
            image=coadd_image,
            method='no_pixel',
        )

        coadd_obs.set_image(coadd_image.array)
Example #23
0
def generateGaussianTrainingSet():
    img_size = 32
    destination = 'testImages/'
    #sizes = np.array([3.,3.5,4.,4.5,5.,5.5,6.])
    sizes = np.array([2.5, 3.75, 4.25, 5.35, 5.9, 6.2])
    N_sizes = len(sizes)
    N_shears = 4  #16
    N_angles = 10  #72
    N_train = N_sizes * N_shears * N_angles
    if N_train < img_size**2:
        print "Too few training images to generate an \
               overcomplete dictionary"

    pos_angles = np.linspace(0., 180., N_angles)
    shears = np.arange(0., 1., 1. / N_shears)

    print "No. of training images = ", N_train

    img = galsim.Image(img_size, img_size)
    print "Generating training images ... "

    gal_flux = 1.e5
    noise = 30

    for N_size in xrange(N_sizes):
        for N_shear in xrange(N_shears):
            for N_angle in xrange(N_angles):
                g = galsim.Gaussian(sigma=sizes[N_size], flux=gal_flux)
                theta = galsim.Angle(pos_angles[N_angle], galsim.degrees)
                g = g.shear(g=shears[N_shear], beta=theta)
                g.drawImage(image=img)
                img.addNoise(galsim.GaussianNoise(sigma=noise))
                fname = 'test_' + str(N_size).zfill(2) + '_' + str(
                    N_shear).zfill(2) + '_' + str(N_angle).zfill(2)
                img.write(fname + '.fits', dir=destination)

    print "Finished generating " + str(N_train) + " training images."
    print "Destination folder: " + str(destination)
    def buildNoisePadImage(self, noise_pad_size, noise_pad, rng):
        """A helper function that builds the `pad_image` from the given `noise_pad` specification.
        """
        import numpy as np

        # Make it with the same dtype as the image
        pad_image = galsim.Image(noise_pad_size,
                                 noise_pad_size,
                                 dtype=self.image.dtype)

        # Figure out what kind of noise to apply to the image
        if isinstance(noise_pad, float):
            noise = galsim.GaussianNoise(rng, sigma=np.sqrt(noise_pad))
        elif isinstance(noise_pad,
                        galsim.correlatednoise._BaseCorrelatedNoise):
            noise = noise_pad.copy()
            if rng:  # Let a user supplied RNG take precedence over that in user CN
                noise.setRNG(rng)
        elif isinstance(noise_pad, galsim.Image):
            noise = galsim.CorrelatedNoise(noise_pad, rng)
        elif self.use_cache and noise_pad in InterpolatedImage._cache_noise_pad:
            noise = InterpolatedImage._cache_noise_pad[noise_pad]
            if rng:
                # Make sure that we are using a specified RNG by resetting that in this cached
                # CorrelatedNoise instance, otherwise preserve the cached RNG
                noise.setRNG(rng)
        elif isinstance(noise_pad, str):
            noise = galsim.CorrelatedNoise(galsim.fits.read(noise_pad), rng)
            if self.use_cache:
                InterpolatedImage._cache_noise_pad[noise_pad] = noise
        else:
            raise ValueError(
                "Input noise_pad must be a float/int, a CorrelatedNoise, Image, or filename "
                + "containing an image to use to make a CorrelatedNoise!")
        # Add the noise
        pad_image.addNoise(noise)

        return pad_image
Example #25
0
    def getNoiseProperties(self, i):
        """Returns the components needed to make the noise correlation function at index `i`.
           Specifically, the noise image (or None), the pixel_scale, and the noise variance,
           as a tuple (im, scale, var).
        """

        if self.logger:
            self.logger.debug('RealGalaxyCatalog %d: Start getNoise',i)
        if self.noise_file_name is None:
            im = None
        else:
            if i >= len(self.noise_file_name):
                raise IndexError(
                    'index %d given to getNoise is out of range (0..%d)'%(
                        i,len(self.noise_file_name)-1))
            if self.noise_file_name[i] in self.saved_noise_im:
                im = self.saved_noise_im[self.noise_file_name[i]]
                if self.logger:
                    self.logger.debug('RealGalaxyCatalog %d: Got saved noise im',i)
            else:
                self.noise_lock.acquire()
                # Again, a second check in case two processes get here at the same time.
                if self.noise_file_name[i] in self.saved_noise_im:
                    im = self.saved_noise_im[self.noise_file_name[i]]
                    if self.logger:
                        self.logger.debug('RealGalaxyCatalog %d: Got saved noise im',i)
                else:
                    from galsim._pyfits import pyfits
                    with pyfits.open(self.noise_file_name[i]) as fits:
                        array = fits[0].data
                    im = galsim.Image(np.ascontiguousarray(array.astype(np.float64)),
                                      scale=self.pixel_scale[i])
                    self.saved_noise_im[self.noise_file_name[i]] = im
                    if self.logger:
                        self.logger.debug('RealGalaxyCatalog %d: Built noise im',i)
                self.noise_lock.release()

        return im, self.pixel_scale[i], self.variance[i]
Example #26
0
def flux_function(index):
    lam, mag = index_dict[index]
    f = filters[lam]
    b = galsim.sed.SED(f)
    c = b.withMagnitude(mag, f)
    gal_flux = c.calculateFlux(f)
    gal = galsim.Convolve(
        wfirst.getPSF(SCAs=18,
                      approximate_struts=False,
                      wavelength=filters[lam])[18].withFlux(gal_flux),
        galsim.Pixel(pixel_scale),
        gsparams=big_fft_params)
    im = gal.drawImage(image=galsim.Image(base_size,
                                          base_size,
                                          dtype=np.float64),
                       scale=pixel_scale,
                       method='no_pixel')
    max_val = np.max(im.array)
    #print "bounds: ", im.bounds
    #print "center: ", im.center
    central_flux = im(im.center())
    #print "bandpass: %s, mag: %g, total_flux: %g, max_val: %g, cenral flux: %g " % (lam, mag, gal_flux, central_flux, max_val)
    return lam, mag, gal_flux, central_flux, max_val
Example #27
0
    def getPSF(self, image_pos, gsparams=None):
        """Returns the PSF at position image_pos

        @param image_pos    The position in image coordinates at which to build the PSF.
        @param gsparams     (Optional) A GSParams instance to pass to the constructed GSObject.

        @returns the PSF as a GSObject
        """
        # Build an image version of the numpy array
        im = galsim.Image(self.getPSFArray(image_pos))

        # Build the PSF profile in the image coordinate system.
        psf = galsim.InterpolatedImage(im,
                                       scale=self.sample_scale,
                                       flux=1,
                                       x_interpolant=galsim.Lanczos(3),
                                       gsparams=gsparams)

        # This brings if from image coordinates to world coordinates.
        if self.wcs:
            psf = self.wcs.toWorld(psf, image_pos=image_pos)

        return psf
Example #28
0
def test_surface_ops():

    # Based on test_sensor.py:test_wavelengths_and_angles, but massively simplified.

    rng = galsim.BaseDeviate(1234)

    fratio = 1.2
    obscuration = 0.2
    assigner = check_dep(galsim.FRatioAngles, fratio, obscuration, rng=rng)

    sed = galsim.SED('CWW_E_ext.sed', 'nm', 'flambda').thin()
    bandpass = galsim.Bandpass('LSST_i.dat', 'nm').thin()
    sampler = check_dep(galsim.WavelengthSampler, sed, bandpass, rng=rng)

    obj = galsim.Gaussian(flux=353, sigma=0.3)
    im = galsim.Image(63, 63, scale=1)
    check_dep(obj.drawImage,
              im,
              method='phot',
              surface_ops=[sampler, assigner],
              rng=rng,
              save_photons=True)

    rng.reset(1234)
    assigner.rng.reset(rng)
    sampler.rng.reset(rng)
    photons = check_dep(obj.makePhot, surface_ops=[sampler, assigner], rng=rng)
    assert photons == im.photons

    rng.reset(1234)
    assigner.rng.reset(rng)
    sampler.rng.reset(rng)
    _, photons2 = check_dep(obj.drawPhot,
                            image=im.copy(),
                            surface_ops=[sampler, assigner],
                            rng=rng)
    assert photons2 == im.photons
Example #29
0
def BuildDES_PSFEx(config, base, ignore, gsparams, logger):
    """@brief Build a RealGalaxy type GSObject from user input.
    """
    des_psfex = galsim.config.GetInputObj('des_psfex', config, base, 'DES_PSFEx')

    opt = { 'flux' : float , 'num' : int, 'image_pos' : galsim.PositionD }
    params, safe = galsim.config.GetAllParams(config, base, opt=opt, ignore=ignore)

    if 'image_pos' in params:
        image_pos = params['image_pos']
    elif 'image_pos' in base:
        image_pos = base['image_pos']
    else:
        raise galsim.GalSimConfigError("DES_PSFEx requested, but no image_pos defined in base.")

    # Convert gsparams from a dict to an actual GSParams object
    if gsparams: gsparams = galsim.GSParams(**gsparams)
    else: gsparams = None

    #psf = des_psfex.getPSF(image_pos, gsparams=gsparams)
    # Because of serialization issues, the above call doesn't work.  So we need to
    # repeat the internals of getPSF here.
    # Also, this is why we have getSampleScale and getLocalWCS.  The multiprocessing.managers
    # stuff only makes available methods of classes that are proxied, not all the attributes.
    # So this is the only way to access these attributes.
    im = galsim.Image(des_psfex.getPSFArray(image_pos))
    psf = galsim.InterpolatedImage(im, scale=des_psfex.getSampleScale(), flux=1,
                                   x_interpolant=galsim.Lanczos(3), gsparams=gsparams)
    psf = des_psfex.getLocalWCS(image_pos).toWorld(psf)

    if 'flux' in params:
        psf = psf.withFlux(params['flux'])

    # The second item here is "safe", a boolean that declares whether the returned value is
    # safe to save and use again for later objects.  In this case, we wouldn't want to do
    # that, since they will be at different positions, so the interpolated PSF will be different.
    return psf, False
Example #30
0
def GetSky(config, base):
    """Parse the sky information and return either a float value for the sky level per pixel
    or an image, as needed.

    If an image is required (because wcs is not uniform) then it will use the presence of
    base['image_pos'] to determine what size image to return (stamp or full).  If there is
    a current image_pos, then we are doing a stamp.  Otherwise a full image.
    """
    if 'sky_level' in config:
        if 'sky_level_pixel' in config:
            raise AttributeError(
                "Cannot specify both sky_level and sky_level_pixel")
        sky_level = galsim.config.ParseValue(config, 'sky_level', base,
                                             float)[0]
        wcs = base['wcs']
        if wcs.isUniform():
            return sky_level * wcs.pixelArea()
        elif 'image_pos' in base:
            return sky_level * wcs.pixelArea(base['image_pos'])
        else:
            # This calculation is non-trivial, so store this in case we need it again.
            tag = (id(base), base['file_num'], base['image_num'])
            if config.get('current_sky_tag', None) == tag:
                return config['current_sky']
            else:
                bounds = base['current_image'].bounds
                sky = galsim.Image(bounds, wcs=wcs)
                wcs.makeSkyImage(sky, sky_level)
                config['current_sky_tag'] = tag
                config['current_sky'] = sky
                return sky
    elif 'sky_level_pixel' in config:
        sky_level_pixel = galsim.config.ParseValue(config, 'sky_level_pixel',
                                                   base, float)[0]
        return sky_level_pixel
    else:
        return 0.