def draw_exp(params, image=None, gsparams=None, dtype=None): """Draw an Exponential profile in k-space onto the given image params = [ half_light_radius, flux, e1, e2, x0, y0 ] image is optional, but if provided will be used as is. """ exp = galsim.Exponential(params[0], flux=params[1], gsparams=gsparams) exp = exp._shear(galsim._Shear(params[2] + 1j * params[3])) exp = exp._shift(galsim.PositionD(params[4], params[5])) if image is None: image = exp.drawKImage(dtype=dtype, nx=256, ny=256) else: image = exp._drawKImage(image) return image
def draw_exp(params, image=None, gsparams=None, dtype=None): """Draw an Exponential profile in k-space onto the given image params = [ half_light_radius, flux, e1, e2, x0, y0 ] image is optional, but if provided will be used as is. """ exp = galsim.Exponential(params[0], flux=params[1], gsparams=gsparams) exp = exp._shear(galsim._Shear(params[2] + 1j * params[3])) exp = exp._shift(galsim.PositionD(params[4],params[5])) if image is None: image = exp.drawKImage(dtype=dtype, nx=256, ny=256) else: image = exp._drawKImage(image) return image
def draw_spergel(params, image=None, gsparams=None, dtype=None): """Draw a Spergel profile in k-space onto the given image params = [ half_light_radius, flux, e1, e2, x0, y0 ] image is optional, but if provided will be used as is. """ nu = 0.5 gal = galsim.Spergel(nu, params[0], flux=params[1], gsparams=gsparams) gal = gal._shear(galsim._Shear(params[2] + 1j * params[3])) gal = gal._shift(galsim.PositionD(params[4], params[5])) if image is None: image = gal.drawKImage(dtype=dtype, nx=256, ny=256) else: image = gal._drawKImage(image) return image
def draw_spergel(params, image=None, gsparams=None, dtype=None): """Draw a Spergel profile in k-space onto the given image params = [ half_light_radius, flux, e1, e2, x0, y0 ] image is optional, but if provided will be used as is. """ nu = 0.5 gal = galsim.Spergel(nu, params[0], flux=params[1], gsparams=gsparams) gal = gal._shear(galsim._Shear(params[2] + 1j * params[3])) gal = gal._shift(galsim.PositionD(params[4],params[5])) if image is None: image = gal.drawKImage(dtype=dtype, nx=256, ny=256) else: image = gal._drawKImage(image) return image
def _resid(self, params, star, convert_func): """Residual function to use with least_squares. Essentially `chi` from `chisq`, but not summed over pixels yet. :param params: A numpy array of model parameters. :param star: A Star instance. :param convert_func: An optional function to apply to the profile being fit before drawing it onto the image. This is used by composite PSFs to isolate the effect of just this model component. :returns: `chi` as a flattened numpy array. """ image, weight, image_pos = star.data.getImage() flux, du, dv, scale, g1, g2 = params # Make sure the shear is sane. g = g1 + 1j * g2 if np.abs(g) >= 1.: # Return "infinity" return np.ones_like(image.array.ravel()) * 1.e300 # We shear/dilate/shift the profile as follows. # prof = self.gsobj.dilate(scale).shear(g1=g1, g2=g2).shift(du, dv) * flux # However, it is a bit faster to do all these operations at once to avoid some superfluous # calculations that GalSim does for each of these steps when done separately. jac = galsim._Shear(g).getMatrix() jac[:, :] *= scale flux /= scale**2 prof = galsim._Transform(self.gsobj, jac, offset=(du, dv), flux_ratio=flux) # Equivalent to galsim.Image(image, dtype=float), but without the sanity checks. model_image = galsim._Image(np.empty_like(image.array, dtype=float), image.bounds, image.wcs) if convert_func is not None: prof = convert_func(prof) prof.drawImage(model_image, method=self._method, center=image_pos) # Caculate sqrt(weight) * (model_image - image) in place for efficiency. model_image.array[:, :] -= image.array model_image.array[:, :] *= np.sqrt(weight.array) return model_image.array.ravel()
def _lmfit_resid(self, lmparams, star): """Residual function to use with lmfit. Essentially `chi` from `chisq`, but not summed over pixels yet. :param lmparams: An lmfit.Parameters() instance. The model. :param star: A Star instance. The data. :returns: `chi` as a flattened numpy array. """ import galsim image, weight, image_pos = star.data.getImage() flux, du, dv, scale, g1, g2 = lmparams.valuesdict().values() # Fit du and dv regardless of force_model_center. The difference is whether the fit # value is recorded (force_model_center=False) or discarded (force_model_center=True). # We shear/dilate/shift the profile as follows. # prof = self.gsobj.dilate(scale).shear(g1=g1, g2=g2).shift(du, dv) * flux # However, it is a bit faster to do all these operations at once to avoid some superfluous # calculations that GalSim does for each of these steps when done separately. jac = galsim._Shear(g1 + 1j * g2).getMatrix() jac[:, :] *= scale flux /= scale**2 if galsim.__version__ >= '2.0': prof = galsim._Transform(self.gsobj, jac.ravel(), offset=galsim.PositionD(du, dv), flux_ratio=flux) else: prof = galsim._Transform(self.gsobj, *jac.ravel(), offset=galsim.PositionD(du, dv), flux_ratio=flux) # Equivalent to galsim.Image(image, dtype=float), but without the sanity checks. model_image = galsim._Image(np.empty_like(image.array, dtype=float), image.bounds, image.wcs) prof.drawImage(model_image, method=self._method, offset=(image_pos - model_image.true_center)) # Caculate sqrt(weight) * (model_image - image) in place for efficiency. model_image.array[:, :] -= image.array model_image.array[:, :] *= np.sqrt(weight.array) return model_image.array.ravel()
def _lmfit_resid(self, lmparams, star): """Residual function to use with lmfit. Essentially `chi` from `chisq`, but not summed over pixels yet. :param lmparams: An lmfit.Parameters() instance. The model. :param star: A Star instance. The data. :returns: `chi` as a flattened numpy array. """ import galsim image, weight, image_pos = star.data.getImage() flux, du, dv, scale, g1, g2 = lmparams.valuesdict().values() # Fit du and dv regardless of force_model_center. The difference is whether the fit # value is recorded (force_model_center=False) or discarded (force_model_center=True). # We shear/dilate/shift the profile as follows. # prof = self.gsobj.dilate(scale).shear(g1=g1, g2=g2).shift(du, dv) * flux # However, it is a bit faster to do all these operations at once to avoid some superfluous # calculations that GalSim does for each of these steps when done separately. jac = galsim._Shear(g1 + 1j*g2).getMatrix() jac[:,:] *= scale flux /= scale**2 if galsim.__version__ >= '2.0': prof = galsim._Transform(self.gsobj, jac.ravel(), offset=galsim.PositionD(du,dv), flux_ratio=flux) else: prof = galsim._Transform(self.gsobj, *jac.ravel(), offset=galsim.PositionD(du,dv), flux_ratio=flux) # Equivalent to galsim.Image(image, dtype=float), but without the sanity checks. model_image = galsim._Image(np.empty_like(image.array, dtype=float), image.bounds, image.wcs) prof.drawImage(model_image, method=self._method, offset=(image_pos - model_image.true_center)) # Caculate sqrt(weight) * (model_image - image) in place for efficiency. model_image.array[:,:] -= image.array model_image.array[:,:] *= np.sqrt(weight.array) return model_image.array.ravel()
def test_shear_initialization(): """Test that Shears can be initialized in a variety of ways and get the expected results.""" # first make an empty Shear and make sure that it has zeros in the right places s = galsim.Shear() vec = [s.g, s.g1, s.g2, s.e, s.e1, s.e2, s.eta, s.esq] vec_ideal = np.zeros(len(vec)) np.testing.assert_array_almost_equal( vec, vec_ideal, decimal=decimal, err_msg="Incorrectly initialized empty shear") # now loop over shear values and ways of initializing for ind in range(n_shear): # initialize with reduced shear components s = galsim.Shear(g1=g1[ind], g2=g2[ind]) all_shear_vals(s, ind) if g1[ind] == 0.0: s = galsim.Shear(g2=g2[ind]) all_shear_vals(s, ind) if g2[ind] == 0.0: s = galsim.Shear(g1=g1[ind]) all_shear_vals(s, ind) # initialize with distortion components s = galsim.Shear(e1=e1[ind], e2=e2[ind]) all_shear_vals(s, ind) if e1[ind] == 0.0: s = galsim.Shear(e2=e2[ind]) all_shear_vals(s, ind) if e2[ind] == 0.0: s = galsim.Shear(e1=e1[ind]) all_shear_vals(s, ind) # initialize with conformal shear components s = galsim.Shear(eta1=eta1[ind], eta2=eta2[ind]) all_shear_vals(s, ind) if eta1[ind] == 0.0: s = galsim.Shear(eta2=eta2[ind]) all_shear_vals(s, ind) if eta2[ind] == 0.0: s = galsim.Shear(eta1=eta1[ind]) all_shear_vals(s, ind) # initialize with axis ratio and position angle s = galsim.Shear(q=q[ind], beta=beta[ind] * galsim.radians) all_shear_vals(s, ind) # initialize with reduced shear and position angle s = galsim.Shear(g=g[ind], beta=beta[ind] * galsim.radians) all_shear_vals(s, ind) # initialize with distortion and position angle s = galsim.Shear(e=e[ind], beta=beta[ind] * galsim.radians) all_shear_vals(s, ind) # initialize with conformal shear and position angle s = galsim.Shear(eta=eta[ind], beta=beta[ind] * galsim.radians) all_shear_vals(s, ind) # initialize with a complex number g1 + 1j * g2 s = galsim.Shear(g1[ind] + 1j * g2[ind]) all_shear_vals(s, ind) s = galsim._Shear(g1[ind] + 1j * g2[ind]) all_shear_vals(s, ind) # which should also be the value of s.shear s2 = galsim.Shear(s.shear) all_shear_vals(s2, ind) # Check picklability do_pickle(s) # finally check some examples of invalid initializations for Shear try: np.testing.assert_raises(TypeError, galsim.Shear, 0.3) np.testing.assert_raises(TypeError, galsim.Shear, 0.3, 0.3) np.testing.assert_raises(TypeError, galsim.Shear, g1=0.3, e2=0.2) np.testing.assert_raises(TypeError, galsim.Shear, eta1=0.3, beta=0. * galsim.degrees) np.testing.assert_raises(TypeError, galsim.Shear, q=0.3) np.testing.assert_raises(ValueError, galsim.Shear, q=1.3, beta=0. * galsim.degrees) np.testing.assert_raises(ValueError, galsim.Shear, g1=0.9, g2=0.6) np.testing.assert_raises(ValueError, galsim.Shear, e=-1.3, beta=0. * galsim.radians) np.testing.assert_raises(ValueError, galsim.Shear, e=1.3, beta=0. * galsim.radians) np.testing.assert_raises(ValueError, galsim.Shear, e1=0.7, e2=0.9) np.testing.assert_raises(TypeError, galsim.Shear, g=0.5) np.testing.assert_raises(TypeError, galsim.Shear, e=0.5) np.testing.assert_raises(TypeError, galsim.Shear, eta=0.5) np.testing.assert_raises(ValueError, galsim.Shear, eta=-0.5, beta=0. * galsim.radians) np.testing.assert_raises(ValueError, galsim.Shear, g=1.3, beta=0. * galsim.radians) np.testing.assert_raises(ValueError, galsim.Shear, g=-0.3, beta=0. * galsim.radians) np.testing.assert_raises(TypeError, galsim.Shear, e=0.3, beta=0.) np.testing.assert_raises(TypeError, galsim.Shear, eta=0.3, beta=0.) np.testing.assert_raises(TypeError, galsim.Shear, randomkwarg=0.1) np.testing.assert_raises(TypeError, galsim.Shear, g1=0.1, randomkwarg=0.1) np.testing.assert_raises(TypeError, galsim.Shear, g1=0.1, e1=0.1) np.testing.assert_raises(TypeError, galsim.Shear, g1=0.1, e=0.1) np.testing.assert_raises(TypeError, galsim.Shear, g1=0.1, g=0.1) np.testing.assert_raises(TypeError, galsim.Shear, beta=45.0 * galsim.degrees) np.testing.assert_raises(TypeError, galsim.Shear, beta=45.0 * galsim.degrees, g=0.3, eta=0.1) np.testing.assert_raises(TypeError, galsim.Shear, beta=45.0, g=0.3) np.testing.assert_raises(TypeError, galsim.Shear, q=0.1, beta=0.) except ImportError: print('The assert_raises tests require nose')