def Convolve(*args, **kwargs): """A function for convolving 2 or more GSObject or ChromaticObject instances. This function will inspect its input arguments to decide if a Convolution object or a ChromaticConvolution object is required to represent the convolution of surface brightness profiles. @param args Unnamed args should be a list of objects to convolve. @param real_space Whether to use real space convolution. [default: None, which means to automatically decide this according to whether the objects have hard edges.] @param gsparams An optional GSParams argument. See the docstring for GSParams for details. [default: None] @returns a Convolution or ChromaticConvolution instance as appropriate. """ # First check for number of arguments != 0 if len(args) == 0: raise TypeError("At least one ChromaticObject or GSObject must be provided.") elif len(args) == 1: if isinstance(args[0], (galsim.GSObject, galsim.ChromaticObject)): args = [args[0]] elif isinstance(args[0], list) or isinstance(args[0], tuple): 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.ChromaticConvolution(*args, **kwargs) else: return Convolution(*args, **kwargs)
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)