Esempio n. 1
0
def Transform(obj,
              jac=(1., 0., 0., 1.),
              offset=galsim.PositionD(0., 0.),
              flux_ratio=1.,
              gsparams=None):
    """A function for transforming either a GSObject or ChromaticObject.

    This function will inspect its input argument to decide if a Transformation object or a
    ChromaticTransformation object is required to represent the resulting transformed object.

    @param obj              The object to be transformed.
    @param jac              A list or tuple ( dudx, dudy, dvdx, dvdy ) describing the Jacobian
                            of the transformation. [default: (1,0,0,1)]
    @param offset           A galsim.PositionD giving the offset by which to shift the profile.
    @param flux_ratio       A factor by which to multiply the flux of the object. [default: 1]
    @param gsparams         An optional GSParams argument.  See the docstring for GSParams for
                            details. [default: None]

    @returns a Transformation or ChromaticTransformation instance as appropriate.
    """
    if not (isinstance(obj, galsim.GSObject)
            or isinstance(obj, galsim.ChromaticObject)):
        raise TypeError(
            "Argument to Transform must be either a GSObject or a ChromaticObject."
        )

    elif (hasattr(jac, '__call__') or hasattr(offset, '__call__')
          or hasattr(flux_ratio, '__call__')
          or isinstance(obj, galsim.ChromaticObject)):

        # Sometimes for Chromatic compound types, it is more efficient to apply the
        # transformation to the components rather than the whole.  In particular, this can
        # help preserve separability in many cases.

        # Don't transform ChromaticSum object, better to just transform the arguments.
        if isinstance(obj, galsim.ChromaticSum) or isinstance(obj, galsim.Sum):
            return galsim.ChromaticSum([
                Transform(o, jac, offset, flux_ratio, gsparams)
                for o in obj.objlist
            ])

        # If we are just flux scaling, then a Convolution can do that to the first element.
        # NB. Even better, if the flux scaling is chromatic, would be to find a component
        # that is already non-separable.  But we don't bother trying to do that currently.
        elif (isinstance(
                obj, galsim.ChromaticConvolution
                or isinstance(obj, galsim.Convolution))
              and np.array_equal(np.asarray(jac).ravel(), (1, 0, 0, 1))
              and offset == galsim.PositionD(0., 0.)):
            first = Transform(obj.objlist[0],
                              flux_ratio=flux_ratio,
                              gsparams=gsparams)
            return galsim.ChromaticConvolution([first] +
                                               [o for o in obj.objlist[1:]])

        else:
            return galsim.ChromaticTransformation(obj, jac, offset, flux_ratio,
                                                  gsparams)
    else:
        return Transformation(obj, jac, offset, flux_ratio, gsparams)
Esempio n. 2
0
def Add(*args, **kwargs):
    """A function for adding 2 or more GSObject or ChromaticObject instances.

    This function will inspect its input arguments to decide if a Sum object or a
    ChromaticSum object is required to represent the sum of surface brightness profiles.

    Typically, you do not need to call Add() explicitly.  Normally, you would just use the + 
    operator, which returns a Sum:

        >>> bulge = galsim.Sersic(n=3, half_light_radius=0.8)
        >>> disk = galsim.Exponential(half_light_radius=1.4)
        >>> gal = bulge + disk
        >>> psf = galsim.Gaussian(sigma=0.3, flux=0.3) + galsim.Gaussian(sigma=0.8, flux=0.7)

    If one of the items is chromatic, it will return a ChromaticSum

        >>> disk = galsim.Exponential(half_light_radius=1.4) * galsim.SED(sed_file)
        >>> gal = bulge + disk

    @param args             Unnamed args should be a list of objects to add.
    @param gsparams         An optional GSParams argument.  See the docstring for GSParams for
                            details. [default: None]

    @returns a Sum or ChromaticSum instance as appropriate.
    """
    if len(args) == 0:
        raise ValueError(
            "At least one ChromaticObject or GSObject must be provided.")
    elif len(args) == 1:
        # 1 argument.  Should be either a GSObject or a list of GSObjects
        if isinstance(args[0], (galsim.GSObject, galsim.ChromaticObject)):
            args = [args[0]]
        elif isinstance(args[0], list):
            args = args[0]
        else:
            raise TypeError(
                "Single input argument must be a GSObject, ChromaticObject or "
                + "a (possibly mixed) list of them.")
    # else args is already the list of objects

    if any([isinstance(a, galsim.ChromaticObject) for a in args]):
        return galsim.ChromaticSum(*args, **kwargs)
    else:
        return Sum(*args, **kwargs)