def __getitem__(cls, t): """A deprecated syntax that treats Image as a dict indexed by type""" from galsim.deprecated import depr depr("Image[type]", 1.1, "Image(..., dtype=type)") Image_dict = {numpy.int16: ImageS, numpy.int32: ImageI, numpy.float32: ImageF, numpy.float64: ImageD} return Image_dict[t]
def CN_applyLensing(self, g1, g2, mu): """A deprecated method that is roughly equivalent to obj = obj.lens(g1,g2,mu)""" depr('applyLensing', 1.1, 'obj = obj.lens(g1,g2,mu)') new_obj = self.copy().lens(g1, g2, mu) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def ConstImageViewD(*args, **kwargs): """A deprecated alias for galsim.Image(..., dtype=numpy.float64, make_const=True) """ depr('ConstImageView[type] or ConstImageViewD', 1.1, 'ImageD(..., make_const=True)') kwargs['dtype'] = numpy.float64 kwargs['make_const'] = True return galsim.Image(*args, **kwargs)
def CN_applyMagnification(self, mu): """A deprecated method that is roughly equivalent to obj = obj.magnify(mu)""" depr('applyMagnification', 1.1, 'obj = obj.magnify(mu)') new_obj = self.copy().magnify(mu) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def CN_applyShear(self, *args, **kwargs): """A deprecated method that is roughly equivalent to obj = obj.shear(shear)""" depr('applyShear', 1.1, 'obj = obj.shear(shear)') new_obj = self.copy().shear(*args, **kwargs) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def GSObject_applyShear(self, *args, **kwargs): """A deprecated method that is roughly equivalent to obj = obj.shear(shear)""" depr('applyShear', 1.1, 'obj = obj.shear(shear)') new_obj = self.shear(*args, **kwargs) self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def GSObject_applyTransformation(self, dudx, dudy, dvdx, dvdy): """A deprecated method that is roughly equivalent to obj = obj.transform(...)""" depr('applyTransformation', 1.1, 'obj = obj.transform(dudx,dudy,dvdx,dvdy)') new_obj = self.copy().transform(dudx, dudy, dvdx, dvdy) self.__class__ = new_obj.__class__ self.__setstate__(new_obj.__getstate__())
def GSObject_applyDilation(self, scale): """A deprecated method that is roughly equivalent to obj = obj.dilate(scale).""" depr('applyDilation', 1.1, 'obj = obj.dilate(scale)') new_obj = self.dilate(scale) self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def GSObject_applyMagnification(self, mu): """A deprecated method that is roughly equivalent to obj = obj.magnify(mu)""" depr('applyMagnification', 1.1, 'obj = obj.magnify(mu)') new_obj = self.magnify(mu) self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def GSObject_setFlux(self, flux): """A deprecated method that is roughly equivalent to obj = obj.withFlux(flux)""" depr('setFlux', 1.1, 'obj = obj.withFlux(flux)') new_obj = self.withFlux(flux) self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def GSObject_scaleFlux(self, flux_ratio): """A deprecated method that is roughly equivalent to obj = obj * flux_ratio""" depr('scaleFlux', 1.1, 'obj = obj * flux_ratio') new_obj = self * flux_ratio self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def GSObject_drawShoot(self, *args, **kwargs): """A deprecated synonym for obj.drawImage(method='phot') """ depr('drawShoot', 1.1, "drawImage(..., method='phot')", 'Note: drawImage has different args than draw did. '+ 'Read the docs for the method keywords carefully.') normalization = kwargs.pop('normalization','f') if normalization in ['flux','f']: return self.drawImage(*args, method='phot', **kwargs) else: # We don't have a method for this, but I think it must be rare. Photon shooting # with surface brightness normalization seems pretty odd. We do use it in the test # suite a few times though. So, need to reproduce a bit of code to get the # pixel area to switch to sb normalization (via the gain). if len(args) > 0: image = args[0] else: image = kwargs.get('image', None) scale = kwargs.get('scale', None) wcs = kwargs.get('wcs', None) offset = kwargs.get('offset', None) use_true_center = kwargs.get('use_true_center', None) wcs = self._determine_wcs(scale, wcs, image) offset = self._parse_offset(offset) local_wcs = self._local_wcs(wcs, image, offset, use_true_center) gain = kwargs.pop('gain',1.) gain *= local_wcs.pixelArea() return self.drawImage(*args, method='phot', gain=gain, **kwargs)
def _new_GSP_init(self, *args, **kwargs): if 'alias_threshold' in kwargs: if 'folding_threshold' in kwargs: raise TypeError('Cannot specify both alias_threshold and folding_threshold') depr('alias_threshold',1.1,'folding_threshold') kwargs['folding_threshold'] = kwargs.pop('alias_threshold') _orig_GSP_init(self, *args, **kwargs)
def GSObject_applyRotation(self, theta): """A deprecated method that is roughly equivalent to obj = obj.rotate(theta)""" depr('applyRotation', 1.1, 'obj = obj.rotate(theta)') new_obj = self.rotate(theta) self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def GSObject_applyTransformation(self, dudx, dudy, dvdx, dvdy): """A deprecated method that is roughly equivalent to obj = obj.transform(...)""" depr('applyTransformation', 1.1, 'obj = obj.transform(dudx,dudy,dvdx,dvdy)') new_obj = self.transform(dudx,dudy,dvdx,dvdy) self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def GSObject_applyLensing(self, g1, g2, mu): """A deprecated method that is roughly equivalent to obj = obj.lens(g1,g2,mu)""" depr('applyLensing', 1.1, 'obj = obj.lens(g1,g2,mu)') new_obj = self.lens(g1,g2,mu) self.SBProfile = new_obj.SBProfile if hasattr(self,'noise'): self.noise = new_obj.noise self.__class__ = new_obj.__class__
def ConstImageViewI(*args, **kwargs): """A deprecated alias for galsim.Image(..., dtype=numpy.int32, make_const=True) """ depr('ConstImageView[type] or ConstImageViewI', 1.1, 'ImageI(..., make_const=True)') kwargs['dtype'] = numpy.int32 kwargs['make_const'] = True return galsim.Image(*args, **kwargs)
def CN_applyTransformation(self, dudx, dudy, dvdx, dvdy): """A deprecated method that is roughly equivalent to obj = obj.transform(...)""" depr('applyTransformation', 1.1, 'obj = obj.transform(dudx,dudy,dvdx,dvdy)') new_obj = self.copy().transform(dudx,dudy,dvdx,dvdy) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def GSObject_drawShoot(self, *args, **kwargs): """A deprecated synonym for obj.drawImage(method='phot') """ depr( 'drawShoot', 1.1, "drawImage(..., method='phot')", 'Note: drawImage has different args than draw did. ' + 'Read the docs for the method keywords carefully.') normalization = kwargs.pop('normalization', 'f') if normalization in ['flux', 'f']: return self.drawImage(*args, method='phot', **kwargs) else: # We don't have a method for this, but I think it must be rare. Photon shooting # with surface brightness normalization seems pretty odd. We do use it in the test # suite a few times though. So, need to reproduce a bit of code to get the # pixel area to switch to sb normalization (via the gain). if len(args) > 0: image = args[0] else: image = kwargs.get('image', None) scale = kwargs.get('scale', None) wcs = kwargs.get('wcs', None) offset = kwargs.get('offset', None) use_true_center = kwargs.get('use_true_center', None) wcs = self._determine_wcs(scale, wcs, image) offset = self._parse_offset(offset) local_wcs = self._local_wcs(wcs, image, offset, use_true_center) gain = kwargs.pop('gain', 1.) gain *= local_wcs.pixelArea() return self.drawImage(*args, method='phot', gain=gain, **kwargs)
def CN_calculateCovarianceMatrix(self, bounds, scale): """This function is deprecated and will be removed in a future version. If you have a use for this function and would like to keep it, please open an issue at: https://github.com/GalSim-developers/GalSim/issues Old documentation: ------------------ Calculate the covariance matrix for an image with specified properties. A correlation function also specifies a covariance matrix for noise in an image of known dimensions and pixel scale. The user specifies these bounds and pixel scale, and this method returns a covariance matrix as a square Image object, with the upper triangle containing the covariance values. @param bounds Bounds corresponding to the dimensions of the image for which a covariance matrix is required. @param scale Pixel scale of the image for which a covariance matrix is required. @returns the covariance matrix (as an Image). """ depr( 'calculateCovarianceMatrix', 1.3, '', 'This functionality has been removed. If you have a need for it, please open ' + 'an issue requesting the functionality.') return galsim._galsim._calculateCovarianceMatrix(self._profile._sbp, bounds, scale)
def CN_applyDilation(self, scale): """A deprecated method that is roughly equivalent to obj = obj.dilate(scale)""" depr('applyDilation', 1.1, 'obj = obj.dilate(scale)') new_obj = self.copy().dilate(scale) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def Bounds_setXMin(self, xmin): """Deprecated method for setting the value of xmin. """ depr( 'setXMin', 1.1, 'bounds = galsim.' + self.__class__.__name__ + '(xmin,bounds.xmax,bounds.ymin,bounds.ymax)') self._setXMin(xmin)
def CN_applyLensing(self, g1, g2, mu): """A deprecated method that is roughly equivalent to obj = obj.lens(g1,g2,mu)""" depr('applyLensing', 1.1, 'obj = obj.lens(g1,g2,mu)') new_obj = self.copy().lens(g1,g2,mu) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def CN_applyRotation(self, theta): """A deprecated method that is roughly equivalent to obj = obj.rotate(theta)""" depr('applyRotation', 1.1, 'obj = obj.rotate(theta)') new_obj = self.rotate(theta) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def from_name(name, tol=None, gsparams=None): """A factory function to create an `Interpolant` of the correct type according to the (string) name of the `Interpolant`. This is mostly used to simplify how config files specify the `Interpolant` to use. Valid names are: - 'delta' = `Delta` - 'nearest' = `Nearest` - 'sinc' = `SincInterpolant` - 'linear' = `Linear` - 'cubic' = `Cubic` - 'quintic' = `Quintic` - 'lanczosN' = `Lanczos` (where N is an integer, given the ``n`` parameter) In addition, if you want to specify the ``conserve_dc`` option for `Lanczos`, you can append either T or F to represent ``conserve_dc = True/False`` (respectively). Otherwise, the default ``conserve_dc=True`` is used. Parameters: name: The name of the interpolant to create. tol: [deprecated] gsparams: An optional `GSParams` argument. [default: None] """ if tol is not None: from galsim.deprecated import depr depr('tol', 2.2, 'gsparams=GSParams(kvalue_accuracy=tol)') gsparams = GSParams(kvalue_accuracy=tol) gsparams = GSParams.check(gsparams) # Do these in rough order of likelihood (most to least) if name.lower() == 'quintic': return Quintic(gsparams=gsparams) if name.lower().startswith('lanczos'): conserve_dc = True if name[-1].upper() in ('T', 'F'): conserve_dc = (name[-1].upper() == 'T') name = name[:-1] try: n = int(name[7:]) except: raise GalSimValueError( "Invalid Lanczos specification. Should look like " "lanczosN, where N is an integer", name) return Lanczos(n, conserve_dc, gsparams=gsparams) elif name.lower() == 'linear': return Linear(gsparams=gsparams) elif name.lower() == 'cubic': return Cubic(gsparams=gsparams) elif name.lower() == 'nearest': return Nearest(gsparams=gsparams) elif name.lower() == 'delta': return Delta(gsparams=gsparams) elif name.lower() == 'sinc': return SincInterpolant(gsparams=gsparams) else: raise GalSimValueError("Invalid Interpolant name %s.", name, ('linear', 'cubic', 'quintic', 'lanczosN', 'nearest', 'delta', 'sinc'))
def calculateFlux(self, bandpass): """ Return the flux (photons/cm^2/s) of the SED through the bandpass. @param bandpass A Bandpass object representing a filter, or None to compute the bolometric flux. For the bolometric flux the integration limits will be set to (0, infinity), which implies that the SED needs to be evaluable over this entire range. @returns the flux through the bandpass. """ if self.dimensionless: raise TypeError("Cannot calculate flux of dimensionless SED.") if bandpass is None: # do bolometric flux from galsim.deprecated import depr depr('Using calculateFlux(bandpass=None) to compute a bolometric flux', 1.5, '', "If you need this functionality, you can use a pseudo-bolometric Bandpass created " "with: bp = Bandpass('1', 'nm', blue_limit=sed.blue_limit, " "red_limit=sed.red_limit)") bp = galsim.Bandpass('1', 'nm', self.blue_limit, self.red_limit) return self.calculateFlux(bp) else: # do flux through bandpass if len(bandpass.wave_list) > 0 or len(self.wave_list) > 0: slop = 1e-6 # nm if (self.blue_limit > bandpass.blue_limit + slop or self.red_limit < bandpass.red_limit - slop): raise ValueError("SED undefined within Bandpass") x, _, _ = galsim.utilities.combine_wave_list(self, bandpass) return np.trapz(bandpass(x) * self(x), x) else: return galsim.integ.int1d(lambda w: bandpass(w)*self(w), bandpass.blue_limit, bandpass.red_limit)
def PA_setPhoton(self, i, x, y, flux): """Deprecated method for setting x,y,flux values""" depr('setPhoton(i,x,y,flux)', 1.5, 'pa.x[i] = x; pa.y[i] = y; pa.flux[i] = flux') self.x[i] = x self.y[i] = y self.flux[i] = flux
def CN_calculateCovarianceMatrix(self, bounds, scale): """This function is deprecated and will be removed in a future version. If you have a use for this function and would like to keep it, please open an issue at: https://github.com/GalSim-developers/GalSim/issues Old documentation: ------------------ Calculate the covariance matrix for an image with specified properties. A correlation function also specifies a covariance matrix for noise in an image of known dimensions and pixel scale. The user specifies these bounds and pixel scale, and this method returns a covariance matrix as a square Image object, with the upper triangle containing the covariance values. @param bounds Bounds corresponding to the dimensions of the image for which a covariance matrix is required. @param scale Pixel scale of the image for which a covariance matrix is required. @returns the covariance matrix (as an Image). """ depr('calculateCovarianceMatrix',1.3,'', 'This functionality has been removed. If you have a need for it, please open '+ 'an issue requesting the functionality.') return galsim._galsim._calculateCovarianceMatrix(self._profile.SBProfile, bounds, scale)
def CN_scaleVariance(self, variance_ratio): """A deprecated method that is roughly equivalent to corr = corr * variance_ratio""" depr('scaleVariance', 1.1, 'obj = obj * variance_ratio') new_obj = self.copy().withScaledVariance(variance_ratio) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def Bounds_setYMax(self, ymax): """Deprecated method for setting the value of ymax. """ depr( 'setYMax', 1.1, 'bounds = galsim.' + self.__class__.__name__ + '(bounds.xmin,bounds.xmax,bounds.ymin,ymax)') self._setYMax(ymax)
def at(self, x, y): """This method is a synonym for im(x,y). It is a bit faster than im(x,y), since GalSim does not have to parse the different options available for __call__. (i.e. im(x,y) or im(pos) or im(x=x,y=y)) """ depr('image.at(x,y)', 1.5, 'image.getValue(x,y)') return self.getValue(x,y)
def InterpolantXY(arg): """A deprecated function for converting a 1d interpolant into a 2d interpolant. This is no longer needed. """ depr('InterpolatedXY', 1.3, 'the 1-d Interpolant by itself') return arg
def at(self, x, y): """This method is a synonym for im(x,y). It is a bit faster than im(x,y), since GalSim does not have to parse the different options available for __call__. (i.e. im(x,y) or im(pos) or im(x=x,y=y)) """ depr('image.at(x,y)', 1.5, 'image.getValue(x,y)') return self.getValue(x, y)
def Bandpass_rdiv(self, other): depr( '__rdiv__', 1.3, "Bandpass(throughput=lambda wave:other/bandpass(wave))", "We removed this function because we don't know of any clear use case. " + "If you have one, please open an issue, and we can add this function back." ) blue_limit = self.blue_limit red_limit = self.red_limit wave_list = self.wave_list if isinstance(other, galsim.Bandpass): if len(other.wave_list) > 0: wave_list = np.union1d(wave_list, other.wave_list) blue_limit = max([self.blue_limit, other.blue_limit]) red_limit = min([self.red_limit, other.red_limit]) wave_list = wave_list[(wave_list >= blue_limit) & (wave_list <= red_limit)] if hasattr(other, '__call__'): tp = lambda w: other(w) / self.func(w) else: tp = lambda w: other / self.func(w) return galsim.Bandpass(tp, 'nm', blue_limit, red_limit, _wave_list=wave_list)
def _new_GSP_init(self, *args, **kwargs): if 'alias_threshold' in kwargs: if 'folding_threshold' in kwargs: raise TypeError( 'Cannot specify both alias_threshold and folding_threshold') depr('alias_threshold', 1.1, 'folding_threshold') kwargs['folding_threshold'] = kwargs.pop('alias_threshold') _orig_GSP_init(self, *args, **kwargs)
def CCDNoise_setReadNoise(self, read_noise): """Deprecated method to set the value of read_noise """ depr( 'setReadNoise', 1.1, 'noise = galsim.CCDNoise(noise.rng, noise.sky_level, noise.gain, read_noise)' ) self._setReadNoise(read_noise)
def CCDNoise_setGain(self, gain): """Deprecated method to set the value of gain """ depr( 'setGain', 1.1, 'noise = galsim.CCDNoise(noise.rng, noise.sky_level, gain, noise.read_noise)' ) self._setGain(gain)
def CCDNoise_setSkyLevel(self, sky_level): """Deprecated method to set the value of sky_level """ depr( 'setSkyLevel', 1.1, 'noise = galsim.CCDNoise(noise.rng, sky_level, noise.gain, noise.read_noise)' ) self._setSkyLevel(sky_level)
def Shapelet_fitImage(self, image, center=None, normalization='flux'): """A deprecated method that is roughly equivalent to self = galsim.FitShapelet(self.sigma, self.order, image) """ depr('fitImage', 1.1, 'galsim.FitShapelet') new_obj = galsim.FitShapelet(self.sigma, self.order, image, center, normalization) bvec = new_obj.SBProfile.getBVec() galsim.GSObject.__init__(self, galsim._galsim.SBShapelet(self.sigma, bvec))
def __init__(self, n, conserve_dc=True, tol=None, gsparams=None): if tol is not None: from galsim.deprecated import depr depr('tol', 2.2, 'gsparams=GSParams(kvalue_accuracy=tol)') gsparams = GSParams(kvalue_accuracy=tol) self._n = int(n) self._conserve_dc = bool(conserve_dc) self._gsparams = GSParams.check(gsparams)
def CN_convolveWith(self, gsobject, gsparams=None): """A deprecated method that is roughly equivalent to cn = cn.convolvedWith(gsobject,gsparams) """ depr('convolveWith', 1.1, 'obj = obj.convolvedWith(gsobject, gsparams)') new_obj = self.copy().convolvedWith(gsobject, gsparams) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def Shapelet_setBVec(self,bvec): """Deprecated method to change the bvec""" depr('setBVec',1.1,'shapelet = galsim.Shapelet(sigma, order, bvec=bvec)') bvec_size = galsim.ShapeletSize(self.order) if len(bvec) != bvec_size: raise ValueError("bvec is the wrong size for the Shapelet order") import numpy bvec = galsim.shapelet.LVector(self.order,numpy.array(bvec)) galsim.GSObject.__init__(self, galsim._galsim.SBShapelet(self.sigma, bvec))
def CN_setVariance(self, variance): """A deprecated method that is roughly equivalent to corr = corr.withVariance(variance) """ depr('setVariance', 1.1, 'obj = obj.withVariance(variance)') new_obj = self.withVariance(variance) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def CN_convolveWith(self, gsobject, gsparams=None): """A deprecated method that is roughly equivalent to cn = cn.convolvedWith(gsobject,gsparams) """ depr('convolveWith', 1.1, 'obj = obj.convolvedWith(gsobject, gsparams)') new_obj = self.copy().convolvedWith(gsobject,gsparams) self._profile = new_obj._profile self._profile_for_stored = None # Reset the stored profile as it is no longer up-to-date self.__class__ = new_obj.__class__
def Shapelet_setBVec(self, bvec): """Deprecated method to change the bvec""" depr('setBVec', 1.1, 'shapelet = galsim.Shapelet(sigma, order, bvec=bvec)') bvec_size = galsim.ShapeletSize(self.order) if len(bvec) != bvec_size: raise ValueError("bvec is the wrong size for the Shapelet order") import numpy bvec = galsim.shapelet.LVector(self.order, numpy.array(bvec)) self._sbp = galsim._galsim.SBShapelet(self.sigma, bvec)
def __init__(self, rule): if rule == midpt: from galsim.deprecated import depr depr('galsim.integ.midpt', 1.5, 'galsim.integ.midptRule') rule = midptRule elif rule == np.trapz: from galsim.deprecated import depr depr('np.trapz', 1.5, 'galsim.integ.trapzRule') rule = trapzRule self.rule = rule
def FitShapelet(sigma, order, image, center=None, normalization='flux', gsparams=None): "Deprecated function equivalent to Shapelet.fit" depr("FitShapelet", 1.5, 'galsim.Shapelet.fit(...)') return galsim.Shapelet.fit(sigma, order, image, center, normalization, gsparams)
def SED_rdiv(self, other): depr('__rdiv__', 1.3, "SED(spec=lambda wave:other/bandpass(wave))", "We removed this function because we don't know of any clear use case. "+ "If you have one, please open an issue, and we can add this function back.") if hasattr(other, '__call__'): spec = lambda w: other(w * (1.0 + self.redshift)) / self(w * (1.0 + self.redshift)) else: spec = lambda w: other / self(w * (1.0 + self.redshift)) return galsim.SED(spec, wave_type='nm', flux_type='fphotons', redshift=self.redshift, _wave_list=self.wave_list, _blue_limit=self.blue_limit, _red_limit=self.red_limit)
def Chromatic_draw(self, *args, **kwargs): """A deprecated synonym for obj.drawImage(method='no_pixel') """ depr('draw', 1.1, "drawImage(..., method='no_pixel'", 'Note: drawImage has different args than draw did. '+ 'Read the docs for the method keywords carefully.') normalization = kwargs.pop('normalization','f') if normalization in ['flux','f']: return self.drawImage(*args, method='no_pixel', **kwargs) else: return self.drawImage(*args, method='sb', **kwargs)
def GSObject_copy(self): """Returns a copy of an object. NB. This is a shallow copy, which is normally fine. However, if the object has a noise attribute, then the copy will use the same rng, so calls to things like noise.whitenImage from the two copies would produce different realizations of the noise. If you want these to be precisely identical, then copy.deepcopy will make an exact duplicate, which will have identical noise realizations for that kind of application. """ depr('copy', 1.5, "", "GSObjects are immutable, so there's no need for copy.") import copy return copy.copy(self)