def _get_gals(self, mode, dx, dy):
        #        mode = self['Mode']
        #Cen = galsim.Gaussian(half_light_radius=self['Cen']['hlr'],flux=self['Cen']['Flux'])
        #Neigh = galsim.Exponential(half_light_radius=self['Neigh']['hlr'],flux=self['Neigh']['Flux'])

        n = rng.uniform(low=0.5, high=4)
        Cen = galsim.Sersic(n,
                            half_light_radius=self['Cen']['hlr'],
                            flux=self['Cen']['Flux'])
        n = rng.uniform(low=0.5, high=4)
        Neigh = galsim.Sersic(n,
                              half_light_radius=self['Neigh']['hlr'],
                              flux=self['Neigh']['Flux'])

        Cen = Cen.shear(g1=np.random.normal(scale=0.02),
                        g2=np.random.normal(scale=0.02))
        Neigh = Neigh.shear(g1=np.random.normal(scale=0.02),
                            g2=np.random.normal(scale=0.02))

        #cen position
        if self['Cen']['Pos'] == 'Fixed':
            dx1, dy1 = self['Cen']['dx'], self['Cen']['dy']

        elif self['Cen']['Pos'] == 'Rand_Circle':
            r = self['Cen']['r']
            theta = 2. * np.pi * np.random.random()
            dx1, dy1 = r * np.cos(theta), r * np.sin(theta)

        #neigh position
        if self['Neigh']['Pos'] == 'Fixed':
            dx2, dy2 = self['Neigh']['dx'], self['Neigh']['dy']

        elif self['Neigh']['Pos'] == 'Rand_circle':
            r = self['Neigh']['r']
            theta = 2. * np.pi * np.random.random()
            dx2, dy2 = r * np.cos(theta), r * np.sin(theta)

        dx1 += np.random.uniform(low=-0.5, high=0.5)
        dy1 += np.random.uniform(low=-0.5, high=0.5)
        dx2 += np.random.uniform(low=-0.5, high=0.5)
        dy2 += np.random.uniform(low=-0.5, high=0.5)

        #Cen = Cen.shift(dx=dx1, dy=dy1)
        #Neigh = Neigh.shift(dx=dx2, dy=dy2)

        if mode == 'scarlet' or mode == 'minimof':
            Cen = Cen.shift(dx=dx1, dy=dy1)
            Neigh = Neigh.shift(dx=dx2, dy=dy2)
            gals = [Cen, Neigh]
            objs = galsim.Add(gals)
        elif mode == 'control':
            Cen = Cen.shift(dx=dx, dy=dy)
            gals = [Cen]
            objs = galsim.Add(gals)
            dx1, dy1 = dx, dy

        shear1, shear2 = self['Shear']['Shear1'], self['Shear']['Shear2']
        #objs = objs.shear(g1=shear1, g2=shear2)

        return objs, dx1, dy1, dx2, dy2
Example #2
0
def test_add_flux_scaling():
    """Test flux scaling for Add.
    """
    import time
    t1 = time.time()

    # decimal point to go to for parameter value comparisons
    param_decimal = 12

    # init with Gaussian and Exponential only (should be ok given last tests)
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj *= 2.
    np.testing.assert_almost_equal(
        obj.getFlux(), test_flux * 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __imul__.")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj /= 2.
    np.testing.assert_almost_equal(
        obj.getFlux(), test_flux / 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __idiv__.")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj2 = obj * 2.
    # First test that original obj is unharmed... (also tests that .copy() is working)
    np.testing.assert_almost_equal(
        obj.getFlux(), test_flux, decimal=param_decimal,
        err_msg="Flux param inconsistent after __rmul__ (original).")
    # Then test new obj2 flux
    np.testing.assert_almost_equal(
        obj2.getFlux(), test_flux * 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __rmul__ (result).")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj2 = 2. * obj
    # First test that original obj is unharmed... (also tests that .copy() is working)
    np.testing.assert_almost_equal(
        obj.getFlux(), test_flux, decimal=param_decimal,
        err_msg="Flux param inconsistent after __mul__ (original).")
    # Then test new obj2 flux
    np.testing.assert_almost_equal(
        obj2.getFlux(), test_flux * 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __mul__ (result).")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj2 = obj / 2.
    # First test that original obj is unharmed... (also tests that .copy() is working)
    np.testing.assert_almost_equal(
        obj.getFlux(), test_flux, decimal=param_decimal,
        err_msg="Flux param inconsistent after __div__ (original).")
    # Then test new obj2 flux
    np.testing.assert_almost_equal(
        obj2.getFlux(), test_flux / 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __div__ (result).")
    t2 = time.time()
    print 'time for %s = %.2f'%(funcname(),t2-t1)
Example #3
0
def test_autocorrelate():
    """Test that auto-correlation works the same as convolution with the mirror image of itself.

    (See the Signal processing Section of http://en.wikipedia.org/wiki/Autocorrelation)
    """
    import time
    t1 = time.time()
    # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians
    myGauss1 = galsim.SBGaussian(sigma=3., flux=4)
    myGauss1.applyShift(-0.2, -0.4)
    myGauss2 = (galsim.SBGaussian(sigma=6., flux=1.3))
    myGauss2.applyShift(0.3, 0.3)
    mySBP1 = galsim.SBAdd([myGauss1, myGauss2])
    mySBP2 = galsim.SBAdd([myGauss1, myGauss2])
    # Here we rotate by 180 degrees to create mirror image
    mySBP2.applyRotation(180. * galsim.degrees)
    myConv = galsim.SBConvolve([mySBP1, mySBP2])
    myImg1 = galsim.ImageF(80, 80, scale=0.7)
    myConv.draw(myImg1.view())
    myAutoCorr = galsim.SBAutoCorrelate(mySBP1)
    myImg2 = galsim.ImageF(80, 80, scale=0.7)
    myAutoCorr.draw(myImg2.view())
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Asymmetric sum of Gaussians convolved with mirror of self disagrees with "
        + "SBAutoCorrelate result")

    # Repeat with the GSObject version of this:
    obj1 = galsim.Gaussian(sigma=3., flux=4)
    obj1.applyShift(-0.2, -0.4)
    obj2 = galsim.Gaussian(sigma=6., flux=1.3)
    obj2.applyShift(0.3, 0.3)
    add1 = galsim.Add(obj1, obj2)
    add2 = (galsim.Add(obj1, obj2)).createRotated(180. * galsim.degrees)
    conv = galsim.Convolve([add1, add2])
    conv.draw(myImg1)
    corr = galsim.AutoCorrelate(add1)
    corr.draw(myImg2)
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Asymmetric sum of Gaussians convolved with mirror of self disagrees with "
        + "AutoCorrelate result")

    # Test photon shooting.
    do_shoot(corr, myImg2, "AutoCorrelate")

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Example #4
0
def test_add_flux_scaling():
    """Test flux scaling for Add.
    """
    # decimal point to go to for parameter value comparisons
    param_decimal = 12
    test_flux = 17.9
    test_sigma = 1.8
    test_scale = 1.9

    # init with Gaussian and Exponential only (should be ok given last tests)
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj *= 2.
    np.testing.assert_almost_equal(
        obj.flux, test_flux * 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __imul__.")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj /= 2.
    np.testing.assert_almost_equal(
        obj.flux, test_flux / 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __idiv__.")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj2 = obj * 2.
    # First test that original obj is unharmed...
    np.testing.assert_almost_equal(
        obj.flux, test_flux, decimal=param_decimal,
        err_msg="Flux param inconsistent after __rmul__ (original).")
    # Then test new obj2 flux
    np.testing.assert_almost_equal(
        obj2.flux, test_flux * 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __rmul__ (result).")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj2 = 2. * obj
    # First test that original obj is unharmed...
    np.testing.assert_almost_equal(
        obj.flux, test_flux, decimal=param_decimal,
        err_msg="Flux param inconsistent after __mul__ (original).")
    # Then test new obj2 flux
    np.testing.assert_almost_equal(
        obj2.flux, test_flux * 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __mul__ (result).")
    obj = galsim.Add([galsim.Gaussian(sigma=test_sigma, flux=test_flux * .5),
                      galsim.Exponential(scale_radius=test_scale, flux=test_flux * .5)])
    obj2 = obj / 2.
    # First test that original obj is unharmed...
    np.testing.assert_almost_equal(
        obj.flux, test_flux, decimal=param_decimal,
        err_msg="Flux param inconsistent after __div__ (original).")
    # Then test new obj2 flux
    np.testing.assert_almost_equal(
        obj2.flux, test_flux / 2., decimal=param_decimal,
        err_msg="Flux param inconsistent after __div__ (result).")
Example #5
0
 def _get_band_obj(self, Cen, Neigh, cen_sed, neigh_sed):
     mode = self['Mode']
     if mode == 'scarlet' or mode == 'mof':
         Cen = Cen * cen_sed
         Neigh = Neigh * neigh_sed
         gals = [Cen, Neigh]
         objs = galsim.Add(gals)
     elif mode == 'control':
         Cen = Cen * cen_sed
         gals = [Cen]
         objs = galsim.Add(gals)
     return objs
    def _get_gals(self):
        mode = self['Mode']
        rng = self.rng

        Cen = self._get_cen_model()
        Neigh = self._get_nbr_model()

        #cen position
        if self['Cen']['Pos'] == 'Fixed':
            dx1, dy1 = self['Cen']['dx'], self['Cen']['dy']

        elif self['Cen']['Pos'] == 'Rand_Circle':
            r = self['Cen']['r']
            theta = 2. * np.pi * np.random.random()
            dx1, dy1 = r * np.cos(theta), r * np.sin(theta)

        #neigh position
        if self['Neigh']['Pos'] == 'Fixed':
            dx2, dy2 = self['Neigh']['dx'], self['Neigh']['dy']

        elif self['Neigh']['Pos'] == 'Rand_circle':
            r = self['Neigh']['r']
            theta = 2. * np.pi * np.random.random()
            dx2, dy2 = r * np.cos(theta), r * np.sin(theta)

        dx1 += np.random.uniform(low=-0.5, high=0.5)
        dy1 += np.random.uniform(low=-0.5, high=0.5)
        dx2 += np.random.uniform(low=-0.5, high=0.5)
        dy2 += np.random.uniform(low=-0.5, high=0.5)

        Cen = Cen.shift(dx=dx1, dy=dy1)
        Neigh = Neigh.shift(dx=dx2, dy=dy2)

        if mode == 'scarlet' or mode == 'mof':
            gals = [Cen, Neigh]
            objs = galsim.Add(gals)
        elif mode == 'control':
            gals = [Cen]
            objs = galsim.Add(gals)

        shear_spec = self['Shear']
        shear1, shear2 = shear_spec['Shear1'], shear_spec['Shear2']
        objs = objs.shear(g1=shear1, g2=shear2)

        if 'Extra_Shear' in shear_spec:
            if 'shear+' in shear_spec['Extra_Shear']:
                objs = objs.shear(g1=shear_spec['Extra_Shear']['shear+'],
                                  g2=0.0)
            elif 'shear-' in shear_spec['Extra_Shear']:
                objs = objs.shear(g1=shear_spec['Extra_Shear']['shear-'],
                                  g2=0.0)

        return objs, dx1, dy1, dx2, dy2
Example #7
0
def main():
    for profile, exactGal, nComponents, maxRadius in PROFILES:
        exactGal.applyShear(e1=E1, e2=E2)
        psf = galsim.Gaussian(sigma=PSF_SIGMA)
        exactObj = galsim.Convolve([exactGal, psf])
        exactImage = exactObj.draw(dx=1.0)
        exactImage.write(profile + "-exact.fits")
        amplitudes, variances = lsst.shapelet.tractor.loadParameters(
            profile, nComponents, maxRadius)
        componentGals = []
        for n, (amplitude, variance) in enumerate(zip(amplitudes, variances)):
            componentGal = galsim.Gaussian(flux=amplitude,
                                           sigma=GALAXY_RADIUS * variance**0.5)
            componentGal.applyShear(e1=E1, e2=E2)
            componentGals.append(componentGal)
            if MAKE_COMPONENT_IMAGES:
                componentObj = galsim.Convolve([componentGal, psf])
                componentImage = galsim.ImageD(exactImage.bounds)
                componentObj.draw(componentImage, dx=1.0)
                componentImage.write("%s-approx-%0d.fits" % (profile, n))
        approxGal = galsim.Add(componentGals)
        approxObj = galsim.Convolve([approxGal, psf])
        approxImage = galsim.ImageD(exactImage.bounds)
        approxObj.draw(approxImage, dx=1.0)
        approxImage.write(profile + "-approx.fits")

    f1 = galsim.Add([
        makeGaussian(flux=0.600000,
                     e1=0.09090909,
                     e2=0.36363636,
                     sigma=2.25810086),
        makeGaussian(flux=0.400000,
                     e1=-0.11111111,
                     e2=-0.11111111,
                     sigma=2.98130750),
    ])
    f2 = galsim.Add([
        makeGaussian(flux=0.350000,
                     e1=-0.26315789,
                     e2=-0.21052632,
                     sigma=2.99069756),
        makeGaussian(flux=0.650000,
                     e1=-0.12500000,
                     e2=0.12500000,
                     sigma=2.80606626),
    ])
    f3 = galsim.Convolve([f1, f2])
    image = galsim.ImageD(galsim.BoundsI(-20, 20, -20, 20))
    f3.draw(image, dx=1.0)
    image.write("gaussians.fits")
Example #8
0
def test_autocorrelate():
    """Test that auto-correlation works the same as convolution with the mirror image of itself.

    (See the Signal processing Section of http://en.wikipedia.org/wiki/Autocorrelation)
    """
    dx = 0.7
    myImg1 = galsim.ImageF(80, 80, scale=dx)
    myImg1.setCenter(0, 0)
    myImg2 = galsim.ImageF(80, 80, scale=dx)
    myImg2.setCenter(0, 0)

    # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians
    obj1 = galsim.Gaussian(sigma=3., flux=4).shift(-0.2, -0.4)
    obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3)
    add1 = galsim.Add(obj1, obj2)
    # Here we rotate by 180 degrees to create mirror image
    add2 = (galsim.Add(obj1, obj2)).rotate(180. * galsim.degrees)
    conv = galsim.Convolve([add1, add2])
    conv.drawImage(myImg1, method='no_pixel')
    corr = galsim.AutoCorrelate(add1)
    corr.drawImage(myImg2, method='no_pixel')
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Asymmetric sum of Gaussians convolved with mirror of self disagrees with "
        + "AutoCorrelate result")

    check_basic(conv, "AutoCorrelate")

    # Test photon shooting.
    do_shoot(corr, myImg2, "AutoCorrelate")

    # Check picklability
    do_pickle(corr, lambda x: x.drawImage(method='no_pixel'))
    do_pickle(corr)

    # Should raise an exception for invalid arguments
    assert_raises(TypeError, galsim.AutoCorrelate)
    assert_raises(TypeError, galsim.AutoCorrelate, myImg1)
    assert_raises(TypeError, galsim.AutoCorrelate, [obj1])
    assert_raises(TypeError, galsim.AutoCorrelate, obj1, obj2)
    assert_raises(TypeError, galsim.AutoCorrelate, obj1, realspace=False)
    assert_raises(TypeError, galsim.AutoCorrelation)
    assert_raises(TypeError, galsim.AutoCorrelation, myImg1)
    assert_raises(TypeError, galsim.AutoCorrelation, [obj1])
    assert_raises(TypeError, galsim.AutoCorrelation, obj1, obj2)
    assert_raises(TypeError, galsim.AutoCorrelation, obj1, realspace=False)
Example #9
0
def _BuildAdd(config, key, base, ignore, gsparams, logger):
    """@brief  Build a Sum object.
    """
    req = {'items': list}
    opt = {'flux': float}
    # Only Check, not Get.  We need to handle items a bit differently, since it's a list.
    galsim.config.CheckAllParams(config, key, req=req, opt=opt, ignore=ignore)

    gsobjects = []
    items = config['items']
    if not isinstance(items, list):
        raise AttributeError("items entry for config.%s entry is not a list." %
                             type)
    safe = True

    for i in range(len(items)):
        gsobject, safe1 = BuildGSObject(items, i, base, gsparams, logger)
        # Skip items with flux=0
        if 'flux' in items[i] and galsim.config.value.GetCurrentValue(
                items[i], 'flux') == 0.:
            if logger:
                logger.debug('obj %d: Not including component with flux == 0',
                             base['obj_num'])
            continue
        safe = safe and safe1
        gsobjects.append(gsobject)

    if len(gsobjects) == 0:
        raise ValueError("No valid items for %s" % key)
    elif len(gsobjects) == 1:
        gsobject = gsobjects[0]
    else:
        # Special: if the last item in a Sum doesn't specify a flux, we scale it
        # to bring the total flux up to 1.
        if ('flux' not in items[-1]) and all('flux' in item
                                             for item in items[0:-1]):
            sum = 0
            for item in items[0:-1]:
                sum += galsim.config.value.GetCurrentValue(item, 'flux')
            f = 1. - sum
            if (f < 0):
                import warnings
                warnings.warn(
                    "Automatically scaling the last item in Sum to make the total flux\n"
                    +
                    "equal 1 requires the last item to have negative flux = %f"
                    % f)
            gsobjects[-1] = gsobjects[-1].withFlux(f)
        if gsparams: gsparams = galsim.GSParams(**gsparams)
        else: gsparams = None
        gsobject = galsim.Add(gsobjects, gsparams=gsparams)

    if 'flux' in config:
        flux, safe1 = galsim.config.ParseValue(config, 'flux', base, float)
        if logger:
            logger.debug('obj %d: flux == %f', base['obj_num'], flux)
        gsobject = gsobject.withFlux(flux)
        safe = safe and safe1

    return gsobject, safe
Example #10
0
def _generate_bd(
    hlr,
    flux,
    vary=False,
    rng=None,
    max_bulge_shift_frac=0.1,  # fraction of hlr
    max_bulge_rot=np.pi / 4,
):

    if vary:
        bulge_frac = _generate_bulge_frac(rng)
    else:
        bulge_frac = 0.5

    disk_frac = (1.0 - bulge_frac)

    bulge = DeVaucouleurs(half_light_radius=hlr, flux=flux * bulge_frac)
    disk = Exponential(half_light_radius=hlr, flux=flux * disk_frac)

    if vary:
        bulge = _shift_bulge(rng, bulge, hlr, max_bulge_shift_frac)

    if vary:
        g1disk, g2disk = _generate_g1g2(rng)

        g1bulge, g2bulge = g1disk, g2disk
        if vary:
            g1bulge, g2bulge = _rotate_bulge(rng, max_bulge_rot, g1bulge,
                                             g2bulge)

        bulge = bulge.shear(g1=g1bulge, g2=g2bulge)
        disk = disk.shear(g1=g1disk, g2=g2disk)

    return galsim.Add(bulge, disk)
Example #11
0
    def create_source(self, fractions, half_light_radius,
                      minor_major_axis_ratio, position_angle):
        """Create a model for the on-sky profile of a single source.

        Size and shape parameter values for any component that is not
        present (because its fraction is zero) are ignored.

        Parameters
        ----------
        fractions : array
            Array of length 2 giving the disk and bulge fractions, respectively,
            which must be in the range [0,1] (but this is not checked). If
            their sum is less than one, the remainder is modeled as a point-like
            component.
        half_light_radius : array
            Array of length 2 giving the disk and bulge half-light radii in
            arcseconds, respectively.
        minor_major_axis_ratio : array
            Array of length 2 giving the dimensionless on-sky ellipse
            minor / major axis ratio for the disk and bulge components,
            respectively.
        position_angle : array
            Array of length 2 giving the position angle in degrees of the on-sky
            disk and bluge ellipses, respectively.  Angles are measured counter
            clockwise relative to the +x axis.

        Returns
        -------
        galsim.GSObject
            A object representing the sum of all requested components with its
            total flux normalized to one.
        """
        # This is a no-op but still required to define the namespace.
        import galsim

        components = []
        if fractions[0] > 0:
            # Disk component
            components.append(
                galsim.Exponential(
                    flux=fractions[0],
                    half_light_radius=half_light_radius[0]).shear(
                        q=minor_major_axis_ratio[0],
                        beta=position_angle[0] * galsim.degrees))
        if fractions[1] > 0:
            components.append(
                galsim.DeVaucouleurs(
                    flux=fractions[1],
                    half_light_radius=half_light_radius[1]).shear(
                        q=minor_major_axis_ratio[1],
                        beta=position_angle[1] * galsim.degrees))
        star_fraction = 1 - fractions.sum()
        if star_fraction > 0:
            # Model a point-like source with a tiny (0.001 arcsec) Gaussian.
            # TODO: sigma should be in arcsec here, not microns!
            components.append(
                galsim.Gaussian(flux=star_fraction,
                                sigma=1e-3 * self.image.scale))
        # Combine the components and transform to focal-plane microns.
        return galsim.Add(components, gsparams=self.gsparams)
Example #12
0
 def createSource(self, galaxyIndex, shifted=False, lensed=False):
     """
     Returns a GalSim model of the source for the specified galaxy index with
     optional centroid shifts and weak lensing distortion.
     """
     params = self.getTruthCatalog()[galaxyIndex]
     # Create the bulge component.
     bulge = galsim.Sersic(flux=params['bulge_flux'],
                           half_light_radius=params['bulge_hlr'],
                           n=params['bulge_n'],
                           gsparams=Observation.getGSParams())
     bulge.applyShear(q=params['bulge_q'],
                      beta=params['bulge_beta_radians'] * galsim.radians)
     # Is there a disk component?
     if params['disk_flux'] > 0:
         disk = galsim.Exponential(flux=params['disk_flux'],
                                   half_light_radius=params['disk_hlr'],
                                   gsparams=Observation.getGSParams())
         disk.applyShear(q=params['disk_q'],
                         beta=params['disk_beta_radians'] * galsim.radians)
         source = galsim.Add(bulge, disk)
     else:
         source = bulge
     # Apply optional lensing.
     if lensed:
         source = source.lens(g1=params['g1'],
                              g2=params['g2'],
                              mu=params['mu'])
     # Apply optional centroid shift.
     if shifted:
         source = source.shift(dx=params['xshift'] * self.pixelScale,
                               dy=params['yshift'] * self.pixelScale)
     return source
Example #13
0
 def whiten(self, profiles, image, config, base, logger):
     """
     Whiten the noise on the stamp according to the existing noise in all the profiles.
     """
     total = galsim.Add(profiles)
     return super(BlendBuilder, self).whiten(total, image, config, base,
                                             logger)
Example #14
0
def _BuildAdd(config, base, ignore, gsparams, logger):
    """@brief  Build a Sum object.
    """
    req = {'items': list}
    opt = {'flux': float}
    # Only Check, not Get.  We need to handle items a bit differently, since it's a list.
    galsim.config.CheckAllParams(config, req=req, opt=opt, ignore=ignore)

    gsobjects = []
    items = config['items']
    if not isinstance(items, list):
        raise AttributeError("items entry for type=Add is not a list.")
    safe = True

    for i in range(len(items)):
        gsobject, safe1 = BuildGSObject(items, i, base, gsparams, logger)
        # Skip items with flux=0
        if 'flux' in items[i] and galsim.config.GetCurrentValue(
                'flux', items[i], float, base) == 0.:
            logger.debug('obj %d: Not including component with flux == 0',
                         base.get('obj_num', 0))
            continue
        safe = safe and safe1
        gsobjects.append(gsobject)

    if len(gsobjects) == 0:
        raise ValueError("No valid items for type=Add")
    elif len(gsobjects) == 1:
        gsobject = gsobjects[0]
    else:
        # Special: if the last item in a Sum doesn't specify a flux, we scale it
        # to bring the total flux up to 1.
        if ('flux' not in items[-1]) and all('flux' in item
                                             for item in items[0:-1]):
            sum_flux = 0
            for item in items[0:-1]:
                sum_flux += galsim.config.GetCurrentValue(
                    'flux', item, float, base)
            f = 1. - sum_flux
            if (f < 0):
                logger.warning(
                    "Warning: Automatic flux for the last item in Sum (to make the total flux=1) "
                    "resulted in negative flux = %f for that item" % f)
            logger.debug(
                'obj %d: Rescaling final object in sum to have flux = %f',
                base.get('obj_num', 0), f)
            gsobjects[-1] = gsobjects[-1].withFlux(f)
        if gsparams: gsparams = galsim.GSParams(**gsparams)
        else: gsparams = None
        gsobject = galsim.Add(gsobjects, gsparams=gsparams)

    if 'flux' in config:
        flux, safe1 = galsim.config.ParseValue(config, 'flux', base, float)
        logger.debug('obj %d: flux == %f', base.get('obj_num', 0), flux)
        gsobject = gsobject.withFlux(flux)
        safe = safe and safe1

    return gsobject, safe
Example #15
0
def _generate_bdk(
    hlr,
    flux,
    vary=False,
    rng=None,
    gsrng=None,
    knots_hlr_frac=0.25,
    max_knots_disk_frac=0.1,  # fraction of disk light
    max_bulge_shift_frac=0.1,  # fraction of hlr
    max_bulge_rot=np.pi / 4,
):

    if vary:
        bulge_frac = _generate_bulge_frac(rng)
    else:
        bulge_frac = 0.5

    all_disk_frac = (1.0 - bulge_frac)

    knots_hlr = knots_hlr_frac * hlr
    if vary:
        knots_sub_frac = _generate_knots_sub_frac(rng, max_knots_disk_frac)
    else:
        knots_sub_frac = max_knots_disk_frac

    disk_frac = (1 - knots_sub_frac) * all_disk_frac
    knots_frac = knots_sub_frac * all_disk_frac

    bulge = DeVaucouleurs(half_light_radius=hlr, flux=flux * bulge_frac)
    disk = Exponential(half_light_radius=hlr, flux=flux * disk_frac)

    if gsrng is None:
        # fixed galaxy, so fix the rng
        gsrng = galsim.BaseDeviate(123)

    knots = galsim.RandomKnots(
        npoints=10,
        half_light_radius=knots_hlr,
        flux=flux * knots_frac,
        rng=gsrng,
    )

    if vary:
        bulge = _shift_bulge(rng, bulge, hlr, max_bulge_shift_frac)

    if vary:
        g1disk, g2disk = _generate_g1g2(rng)

        g1bulge, g2bulge = g1disk, g2disk
        if vary:
            g1bulge, g2bulge = _rotate_bulge(rng, max_bulge_rot, g1bulge,
                                             g2bulge)

        bulge = bulge.shear(g1=g1bulge, g2=g2bulge)
        disk = disk.shear(g1=g1disk, g2=g2disk)
        knots = knots.shear(g1=g1disk, g2=g2disk)

    return galsim.Add(bulge, disk, knots)
Example #16
0
def test_autocorrelate():
    """Test that auto-correlation works the same as convolution with the mirror image of itself.

    (See the Signal processing Section of http://en.wikipedia.org/wiki/Autocorrelation)
    """
    import time
    t1 = time.time()

    dx = 0.7
    myImg1 = galsim.ImageF(80, 80, scale=dx)
    myImg1.setCenter(0, 0)
    myImg2 = galsim.ImageF(80, 80, scale=dx)
    myImg2.setCenter(0, 0)

    # Use a function that is NOT two-fold rotationally symmetric, e.g. two different flux Gaussians
    obj1 = galsim.Gaussian(sigma=3., flux=4).shift(-0.2, -0.4)
    obj2 = galsim.Gaussian(sigma=6., flux=1.3).shift(0.3, 0.3)
    add1 = galsim.Add(obj1, obj2)
    # Here we rotate by 180 degrees to create mirror image
    add2 = (galsim.Add(obj1, obj2)).rotate(180. * galsim.degrees)
    conv = galsim.Convolve([add1, add2])
    conv.drawImage(myImg1, method='no_pixel')
    corr = galsim.AutoCorrelate(add1)
    corr.drawImage(myImg2, method='no_pixel')
    printval(myImg1, myImg2)
    np.testing.assert_array_almost_equal(
        myImg1.array,
        myImg2.array,
        4,
        err_msg=
        "Asymmetric sum of Gaussians convolved with mirror of self disagrees with "
        + "AutoCorrelate result")

    # Test photon shooting.
    do_shoot(corr, myImg2, "AutoCorrelate")

    # Check picklability
    do_pickle(corr.SBProfile, lambda x:
              (repr(x.getObj()), x.isRealSpace(), x.getGSParams()))
    do_pickle(corr, lambda x: x.drawImage(method='no_pixel'))
    do_pickle(corr)
    do_pickle(corr.SBProfile)

    t2 = time.time()
    print 'time for %s = %.2f' % (funcname(), t2 - t1)
Example #17
0
    def make_image(self, iobj, band=0, obsnum=0, include_nbrs=False):
        """
        make an image for the given band and observation number

        including nbrs is causing some trouble, probably due to
        the object being way off the stamp (why does it work for
        the fitter?)
        """
        import galsim

        res = self.get_result()
        pars = res['pars']

        obs = self.list_of_obs[iobj][band][obsnum]
        meta = obs.meta
        psf_meta = obs.psf.meta

        band_pars = self.get_object_band_pars(
            pars,
            iobj,
            band,
        )

        central_model = self._make_fully_shifted_model(band_pars, obs)

        if include_nbrs:
            maxrad = self._get_maxrad(obs)
            nbr_models = self._get_nbr_models(
                iobj,
                pars,
                meta,
                band,
                maxrad,
                obs,
            )
        else:
            nbr_models = []

        if len(nbr_models) > 0:
            all_models = [central_model] + nbr_models

            total_model = galsim.Add(
                all_models,
                gsparams=self._gsp,
            )
        else:
            total_model = central_model

        total_model = galsim.Convolve(
            total_model,
            psf_meta['ii'],
            gsparams=self._gsp,
        )

        image = meta['model'].copy()
        self._do_draw(obs, total_model, image)
        return image.array
Example #18
0
def make_bdf(half_light_radius=None,
             flux=None,
             fracdev=None,
             trunc=0.0,
             gsparams=None):
    """
    a bulge+disk maker for equal hlr for bulge and disk

    Parameters
    ----------
    half_light_radius: float
        hlr
    flux: float
        Total flux in the profile
    fracdev: float
        fraction of light in the bulge
    """
    import galsim

    assert half_light_radius is not None, 'send half_light_ratio'
    assert flux is not None, 'send flux'
    assert fracdev is not None, 'send fracdev'

    if trunc > 0:
        flux_untruncated = True
    else:
        flux_untruncated = False
    """
    bulge = galsim.DeVaucouleurs(
        half_light_radius=half_light_radius,
        flux=fracdev,
        flux_untruncated=flux_untruncated ,
        trunc=trunc,
        gsparams=gsparams,
    )
    """
    bulge = galsim.Sersic(
        n=2,
        half_light_radius=half_light_radius,
        flux=fracdev,
        flux_untruncated=flux_untruncated,
        trunc=trunc,
        gsparams=gsparams,
    )

    disk = galsim.Exponential(
        half_light_radius=half_light_radius,
        flux=(1 - fracdev),
        gsparams=gsparams,
    )

    return galsim.Add(
        bulge,
        disk,
        gsparams=gsparams,
    ).withFlux(flux)
Example #19
0
    def star2gs(self, index, gsparams):

        # Convert from dict to actual GsParams object
        # TODO: Currently fails if gsparams isn't passed!
        if gsparams: gsp = galsim.GSParams(**gsparams)
        else: gsp = None

        # List of individual band GSObjects
        gsobjects = []

        # Iterate over all desired bands
        for band in self.bands:
            if self.data_version == 'y3v02':

                # Needed for all mag calculations
                gmag = self.catalog['g_Corr'][index]

                # Grab current band magnitude
                if band == 'g':
                    mag = gmag
                elif band == 'r':
                    mag = gmag - self.catalog['gr_Corr'][index]
                elif band == 'i':
                    mag = gmag - self.catalog['gr_Corr'][index] - self.catalog[
                        'ri_Corr'][index]
                elif band == 'z':
                    mag = gmag - self.catalog['gr_Corr'][index] - self.catalog['ri_Corr'][index] \
                               - self.catalog['iz_Corr'][index]
                else:
                    raise ValueError(
                        'Band {} is not an allowed band input '.format(band) +
                        'for data_version of {}!'.format(self.data_version))

                # Now convert to flux
                flux = np.power(10.0, 0.4 * (self.zeropoint - mag))

                # (star cats calibrated at zp=30)
                # NOTE: Will just use `scale_flux` parameter in galsim config for now
                # flux_factor = ...

                # Stars are treated as a delta function, to be convolved w/ set PSF
                star = galsim.DeltaFunction(flux)

            else:
                # Should already be checked by this point, but just to be safe:
                raise ValueError(
                    'There is no implementation for `star2gs` for data_version '
                    + 'of {}'.format(self.data_version))

            # Add galaxy in given band to list
            gsobjects.append(star)

        # NOTE: If multiple bands were passed, the fluxes are simply added together.
        gs_star = galsim.Add(gsobjects)

        return gs_star
Example #20
0
def test_gsparams():
    """Test withGSParams with some non-default gsparams
    """
    obj1 = galsim.Exponential(half_light_radius=1.7)
    obj2 = galsim.Pixel(scale=0.2)
    gsp = galsim.GSParams(folding_threshold=1.e-4,
                          maxk_threshold=1.e-4,
                          maximum_fft_size=1.e4)
    gsp2 = galsim.GSParams(folding_threshold=1.e-2, maxk_threshold=1.e-2)

    sum = galsim.Sum(obj1, obj2)
    sum1 = sum.withGSParams(gsp)
    assert sum.gsparams == galsim.GSParams()
    assert sum1.gsparams == gsp
    assert sum1.obj_list[0].gsparams == gsp
    assert sum1.obj_list[1].gsparams == gsp

    sum2 = galsim.Sum(obj1.withGSParams(gsp), obj2.withGSParams(gsp))
    sum3 = galsim.Sum(galsim.Exponential(half_light_radius=1.7, gsparams=gsp),
                      galsim.Pixel(scale=0.2))
    sum4 = galsim.Add(obj1, obj2, gsparams=gsp)
    assert sum != sum1
    assert sum1 == sum2
    assert sum1 == sum3
    assert sum1 == sum4
    print('stepk = ', sum.stepk, sum1.stepk)
    assert sum1.stepk < sum.stepk
    print('maxk = ', sum.maxk, sum1.maxk)
    assert sum1.maxk > sum.maxk

    sum5 = galsim.Add(obj1, obj2, gsparams=gsp, propagate_gsparams=False)
    assert sum5 != sum4
    assert sum5.gsparams == gsp
    assert sum5.obj_list[0].gsparams == galsim.GSParams()
    assert sum5.obj_list[1].gsparams == galsim.GSParams()

    sum6 = sum5.withGSParams(gsp2)
    assert sum6 != sum5
    assert sum6.gsparams == gsp2
    assert sum6.obj_list[0].gsparams == galsim.GSParams()
    assert sum6.obj_list[1].gsparams == galsim.GSParams()
Example #21
0
    def make_galsim_object(self, gsparams=None):
        '''
        Make a galsim representation for the gaussian mixture.
        NOTE: The only difference from Erin's original code is the type checking and passing
        of gsparams. This is especially useful for increasing fft sizes.
        '''

        # Accept optional gsparams for GSObject construction
        if gsparams and (type(gsparams) is not galsim._galsim.GSParams):
            if type(gsparams) is dict:
                # Convert to actual gsparams object
                gsparams = galsim.GSParams(**gsparams)
            else:
                raise TypeError(
                    'Only `dict` and `galsim.GSParam` types allowed for'
                    'gsparams; input has {} type.'.format(type(gsparams)))

        data = self._get_gmix_data()

        row, col = self.get_cen()

        gsobjects = []
        for i in xrange(len(self)):
            flux = data['p'][i]
            T = data['irr'][i] + data['icc'][i]
            # assert(T!=0.0)
            if T == 0:
                # TODO: Explore this issue more! T is being stored as nonzero -
                #       what is causing this?
                continue
            e1 = (data['icc'][i] - data['irr'][i]) / T
            e2 = 2.0 * data['irc'][i] / T

            rowshift = data['row'][i] - row
            colshift = data['col'][i] - col

            g1, g2 = ngmix.shape.e1e2_to_g1g2(e1, e2)

            Tround = ngmix.moments.get_Tround(T, g1, g2)
            sigma_round = np.sqrt(Tround / 2.0)

            gsobj = galsim.Gaussian(flux=flux,
                                    sigma=sigma_round,
                                    gsparams=gsparams)

            gsobj = gsobj.shear(g1=g1, g2=g2)
            gsobj = gsobj.shift(colshift, rowshift)

            gsobjects.append(gsobj)

        gs_obj = galsim.Add(gsobjects)

        return gs_obj
Example #22
0
    def _get_bd_model(self, spec):
        rng = self.rng

        flux = spec['Flux']

        fracdev = rng.uniform(low=0.0, high=1.0)

        bulge_flux = fracdev * flux
        disk_flux = (1.0 - fracdev) * flux

        disk_hlr = spec['hlr']
        if 'bulge_size_factor' in spec:
            frange = spec['bulge_size_factor']['range']
            bulge_hlr = disk_hlr * rng.uniform(
                low=frange[0],
                high=frange[1],
            )
        else:
            bulge_hlr = disk_hlr

        if 'knots' in spec:
            disk_flux, knot_flux = self._split_flux_with_knots(spec, disk_flux)

        disk = galsim.Exponential(
            half_light_radius=disk_hlr,
            flux=disk_flux,
        )
        bulge = galsim.DeVaucouleurs(
            half_light_radius=bulge_hlr,
            flux=bulge_flux,
        )

        if 'knots' in spec:
            knots = self._get_knots(spec, disk_hlr, knot_flux)
            disk = galsim.Add([disk, knots])

        disk = self._add_ellipticity(disk, spec)
        bulge = self._add_ellipticity(bulge, spec)

        return galsim.Add([disk, bulge])
Example #23
0
def doubleSersic(xcen1,
                 ycen1,
                 flux1,
                 reff1,
                 nser1,
                 q1,
                 pa1,
                 xcen2,
                 ycen2,
                 flux2,
                 reff2,
                 nser2,
                 q2,
                 pa2,
                 nx,
                 ny,
                 psf=None,
                 scale=1.0,
                 exptime=1.0,
                 trunc=0,
                 max_fft=None):
    """Generate image for double Sersic component."""
    ser = galsim.Add([
        galsim.Sersic(
            n=nser1,
            half_light_radius=reff1,
            flux=(flux1 * exptime),
            trunc=trunc).shear(q=q1, beta=(0.0 * galsim.degrees)).rotate(
                (90.0 - pa1) * galsim.degrees).shift((xcen1 - (nx / 2.0)),
                                                     (ycen1 - (ny / 2.0))),
        galsim.Sersic(
            n=nser2,
            half_light_radius=reff2,
            flux=(flux2 * exptime),
            trunc=trunc).shear(q=q2, beta=(0.0 * galsim.degrees)).rotate(
                (90.0 - pa2) * galsim.degrees).shift((xcen2 - (nx / 2.0)),
                                                     (ycen2 - (ny / 2.0)))
    ])

    if psf is not None:
        if max_fft is not None:
            gsparams = galsim.GSParams(maximum_fft_size=max_fft)
            return (galsim.Convolve([ser, psf], gsparams=gsparams).drawImage(
                nx=nx, ny=ny, method='no_pixel', scale=scale)).array
        else:
            return (galsim.Convolve([ser, psf]).drawImage(nx=nx,
                                                          ny=ny,
                                                          method='no_pixel',
                                                          scale=scale)).array
    else:
        return (ser.drawImage(nx=nx, ny=ny, method='no_pixel',
                              scale=scale)).array
Example #24
0
    def __init__(self, identifier, redshift, ab_magnitude, ri_color,
                 cosmic_shear_g1, cosmic_shear_g2, dx_arcsecs, dy_arcsecs,
                 beta_radians, disk_flux, disk_hlr_arcsecs, disk_q, bulge_flux,
                 bulge_hlr_arcsecs, bulge_q, agn_flux):
        self.identifier = identifier
        self.redshift = redshift
        self.ab_magnitude = ab_magnitude
        self.ri_color = ri_color
        self.dx_arcsecs = dx_arcsecs
        self.dy_arcsecs = dy_arcsecs
        self.cosmic_shear_g1 = cosmic_shear_g1
        self.cosmic_shear_g2 = cosmic_shear_g2
        components = []
        # Initialize second-moments tensor. Note that we can only add the tensors for the
        # n = 1,4 components, as we do below, since they have the same centroid.
        self.second_moments = np.zeros((2, 2))
        total_flux = disk_flux + bulge_flux + agn_flux
        self.disk_fraction = disk_flux / total_flux
        self.bulge_fraction = bulge_flux / total_flux
        if disk_flux > 0:
            disk = galsim.Exponential(
                flux=disk_flux, half_light_radius=disk_hlr_arcsecs).shear(
                    q=disk_q, beta=beta_radians * galsim.radians)
            components.append(disk)
            self.second_moments += self.disk_fraction * sersic_second_moments(
                n=1, hlr=disk_hlr_arcsecs, q=disk_q, beta=beta_radians)

        if bulge_flux > 0:
            bulge = galsim.DeVaucouleurs(
                flux=bulge_flux, half_light_radius=bulge_hlr_arcsecs).shear(
                    q=bulge_q, beta=beta_radians * galsim.radians)
            components.append(bulge)
            self.second_moments += self.bulge_fraction * sersic_second_moments(
                n=1, hlr=bulge_hlr_arcsecs, q=bulge_q, beta=beta_radians)
        # GalSim does not currently provide a "delta-function" component to model the AGN
        # so we use a very narrow Gaussian. See this GalSim issue for details:
        # https://github.com/GalSim-developers/GalSim/issues/533
        if agn_flux > 0:
            agn = galsim.Gaussian(flux=agn_flux, sigma=1e-8)
            components.append(agn)

        # Combine the components into our final profile.
        self.profile = galsim.Add(components)
        # Apply transforms to build the final model.

        self.model = self.get_transformed_model()

        # Shear the second moments, if necessary.
        if self.cosmic_shear_g1 != 0 or self.cosmic_shear_g2 != 0:
            self.second_moments = sheared_second_moments(
                self.second_moments, self.cosmic_shear_g1,
                self.cosmic_shear_g2)
Example #25
0
    def _get_images(self):
        """
        get images without noise for each band
        """
        import galsim

        gmodels = []
        rmodels = []
        imodels = []
        odlist = []
        for i in range(self['objects']['nobj']):
            band_models, odata = self._get_convolved_models()
            gmodels.append(band_models[0])
            rmodels.append(band_models[1])
            imodels.append(band_models[2])

            odlist.append(odata)

        band_models = [
            galsim.Add(gmodels),
            galsim.Add(rmodels),
            galsim.Add(imodels),
        ]

        iconf = self['image']
        ny, nx = [iconf['dim_pixels']] * 2

        band_images = []
        for model in band_models:
            image = model.drawImage(
                nx=nx,
                ny=ny,
                scale=iconf['pixel_scale'],
            ).array

            band_images.append(image)

        obj_data = eu.numpy_util.combine_arrlist(odlist)
        return band_images, obj_data
Example #26
0
def galSimAdd(galObjList, size=0, scale=1.0, method="auto", returnArr=False):
    """
    Just add a list of GSObjs together using GalSim
    Make sure all elements in the input list are GSObjs
    """
    if len(galObjList) < 2:
        raise Exception("Should be more than one GSObjs to add !")

    outObj = galsim.Add(galObjList)

    if returnArr:
        outArr = galSimDrawImage(outObj, size=size, scale=scale, method=method)
        return outArr
    else:
        return outObj
Example #27
0
def _BuildAdd(config, key, base, ignore, gsparams):
    """@brief  Build an Add object
    """
    req = {'items': list}
    opt = {'flux': float}
    # Only Check, not Get.  We need to handle items a bit differently, since it's a list.
    galsim.config.CheckAllParams(config, key, req=req, opt=opt, ignore=ignore)

    gsobjects = []
    items = config['items']
    if not isinstance(items, list):
        raise AttributeError("items entry for config.%s entry is not a list." %
                             type)
    safe = True
    for i in range(len(items)):
        gsobject, safe1 = BuildGSObject(items, i, base, gsparams)
        safe = safe and safe1
        gsobjects.append(gsobject)
    #print 'After built component items for ',type,' safe = ',safe

    # Special: if the last item in a Sum doesn't specify a flux, we scale it
    # to bring the total flux up to 1.
    if ('flux' not in items[-1]) and all('flux' in item
                                         for item in items[0:-1]):
        sum = 0
        for item in items[0:-1]:
            sum += galsim.config.value.GetCurrentValue(item, 'flux')
        #print 'sum = ',sum
        f = 1. - sum
        #print 'f = ',f
        if (f < 0):
            import warnings
            warnings.warn(
                "Automatically scaling the last item in Sum to make the total flux\n"
                + "equal 1 requires the last item to have negative flux = %f" %
                f)
        gsobjects[-1].setFlux(f)
    if gsparams: gsparams = galsim.GSParams(**gsparams)
    else: gsparams = None
    gsobject = galsim.Add(gsobjects, gsparams=gsparams)

    if 'flux' in config:
        flux, safe1 = galsim.config.ParseValue(config, 'flux', base, float)
        #print 'flux = ',flux
        gsobject.setFlux(flux)
        safe = safe and safe1

    return gsobject, safe
Example #28
0
    def add_lumps(self, n_regions, frac_gal_flux=0.05, frac_r_e=1.0, 
                  **kwargs):

        flux = self.gal.flux * frac_gal_flux
        r_e = self.pars.r_e.to('arcsec') * frac_r_e
        PA = self.pars.PA.value
        ell = self.pars.ell
        n = self.pars.n

        lumps = HIIRegions(
            n_regions=n_regions, flux=flux, PA=PA, r_e=r_e, ell=ell, 
            sersic_n=n, **kwargs)

        self.gal = self.gal.withFlux(self.gal.flux * (1-frac_gal_flux))
        self.gal = galsim.Add([self.gal, lumps])
        self._original_gal = self.gal
Example #29
0
    def add_point_sources(self, n_points, frac_gal_flux=0.05, frac_r_e=1.0, 
                         total_flux=None, point_fwhm=None):

        r_e = self.pars.r_e.to('arcsec').value * frac_r_e
        flux = total_flux if total_flux else self.gal.flux * frac_gal_flux
        points = galsim.RandomWalk(n_points, half_light_radius=r_e, flux=flux)
        points = points.shear(q=self.pars.b_a, beta=(0.0 * galsim.degrees))
        points = points.rotate(
            self.pars.PA.to('degree').value * galsim.degrees)
        if total_flux is None:
            self.gal = self.gal.withFlux(self.gal.flux * (1-frac_gal_flux))
        if point_fwhm is not None:
            point_psf = galsim.Gaussian(
                flux=1.0, fwhm=point_fwhm.to('arcsec').value)
            points = galsim.Convolve([points, point_psf])
        self.gal = galsim.Add([self.gal, points])
        self._original_gal = self.gal
Example #30
0
    def render_galaxy(
        self,
        galaxy_params: Tensor,
        psf: galsim.GSObject,
        slen: int,
        offset: Optional[Tensor] = None,
    ) -> Tensor:
        assert offset is None or offset.shape == (2, )
        if isinstance(galaxy_params, Tensor):
            galaxy_params = galaxy_params.cpu().detach()
        total_flux, disk_frac, beta_radians, disk_q, a_d, bulge_q, a_b = galaxy_params
        bulge_frac = 1 - disk_frac

        disk_flux = total_flux * disk_frac
        bulge_flux = total_flux * bulge_frac

        components = []
        if disk_flux > 0:
            b_d = a_d * disk_q
            disk_hlr_arcsecs = np.sqrt(a_d * b_d)
            disk = galsim.Exponential(
                flux=disk_flux, half_light_radius=disk_hlr_arcsecs).shear(
                    q=disk_q,
                    beta=beta_radians * galsim.radians,
                )
            components.append(disk)
        if bulge_flux > 0:
            b_b = bulge_q * a_b
            bulge_hlr_arcsecs = np.sqrt(a_b * b_b)
            bulge = galsim.DeVaucouleurs(
                flux=bulge_flux, half_light_radius=bulge_hlr_arcsecs).shear(
                    q=bulge_q, beta=beta_radians * galsim.radians)
            components.append(bulge)
        galaxy = galsim.Add(components)
        gal_conv = galsim.Convolution(galaxy, psf)
        offset = offset if offset is None else offset.numpy()
        image = gal_conv.drawImage(nx=slen,
                                   ny=slen,
                                   method="auto",
                                   scale=self.pixel_scale,
                                   offset=offset)
        return torch.from_numpy(image.array).reshape(1, slen, slen)