def test_celestialcoord_basic(): """Basic tests of CelestialCoord construction. etc. """ c1 = galsim.CelestialCoord(0. * galsim.radians, 0. * galsim.radians) numpy.testing.assert_almost_equal(c1.ra.rad(), 0., decimal=12) numpy.testing.assert_almost_equal(c1.dec.rad(), 0., decimal=12) c2 = galsim.CelestialCoord(11. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c2.ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c2.dec / galsim.degrees, -37., decimal=12) c3 = galsim.CelestialCoord(35. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c3.ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c3.dec / galsim.degrees, -37., decimal=12) c4 = galsim.CelestialCoord(-13. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c4.ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c4.dec / galsim.degrees, -37., decimal=12) numpy.testing.assert_almost_equal(c2.distanceTo(c3).rad(), 0., decimal=12) numpy.testing.assert_almost_equal(c2.distanceTo(c4).rad(), 0., decimal=12) # Check picklability do_pickle(c1) do_pickle(c2) do_pickle(c3) do_pickle(c4)
def test_galactic(): # According to wikipedia: http://en.wikipedia.org/wiki/Galactic_coordinate_system # the galactic center is located at 17h:45.6m, -28.94d center = galsim.CelestialCoord((17. + 45.6 / 60.) * galsim.hours, -28.94 * galsim.degrees) print 'center.galactic = ', center.galactic() el, b = center.galactic() numpy.testing.assert_almost_equal(el.rad(), 0., decimal=3) numpy.testing.assert_almost_equal(b.rad(), 0., decimal=3) # The north pole is at 12h:51.4m, 27.13d north = galsim.CelestialCoord((12. + 51.4 / 60.) * galsim.hours, 27.13 * galsim.degrees) print 'north.galactic = ', north.galactic() el, b = north.galactic() numpy.testing.assert_almost_equal(b.rad(), pi / 2., decimal=3) # The south pole is at 0h:51.4m, -27.13d south = galsim.CelestialCoord((0. + 51.4 / 60.) * galsim.hours, -27.13 * galsim.degrees) print 'south.galactic = ', south.galactic() el, b = south.galactic() numpy.testing.assert_almost_equal(b.rad(), -pi / 2., decimal=3) # The anti-center is at 5h:42.6m, 28.92d anticenter = galsim.CelestialCoord((5. + 45.6 / 60.) * galsim.hours, 28.94 * galsim.degrees) print 'anticenter.galactic = ', anticenter.galactic() el, b = anticenter.galactic() numpy.testing.assert_almost_equal(el.rad(), pi, decimal=3) numpy.testing.assert_almost_equal(b.rad(), 0., decimal=3)
def zenith_parallactic_angles(obj_coord, zenith_coord=None, HA=None, latitude=None): """Compute the zenith angle and parallactic angle of a celestial coordinate, given either the celestial coordinate of the zenith, or equivalently, the hour angle of the coordinate and the latitude of the observer. This is useful for the function ChromaticAtmosphere() in the galsim.chromatic module. @param obj_coord A CelestialCoord object for which the zenith and parallactic angles will be computed. @param zenith_coord A CelestialCoord indicating the coordinates of the zenith. @param HA The hour angle (as an Angle) of the coordinate for which the zenith and parallactic angles will be computed. @param latitude The observer's latitude, as an Angle. @returns the tuple `(zenith_angle, parallactic_angle)`, each of which is an Angle. """ if zenith_coord is None: if HA is None or latitude is None: raise ValueError( "Need to provide either zenith_coord or (HA, latitude) to" + "zenith_parallactic_angles()") zenith_coord = galsim.CelestialCoord(HA + obj_coord.ra, latitude) zenith_angle = obj_coord.distanceTo(zenith_coord) NCP = galsim.CelestialCoord(0.0 * galsim.degrees, 90 * galsim.degrees) parallactic_angle = obj_coord.angleBetween(zenith_coord, NCP) return zenith_angle, parallactic_angle
def test_wfirst_backgrounds(): """Test the WFIRST background estimation routines for basic sanity. """ import datetime # The routine should not allow us to look directly at the sun since the background there is high # (to understate the problem). If no date is supplied, then the routine assumes RA=dec=0 means # we are looking at the sun. bp_dict = galsim.wfirst.getBandpasses() bp = bp_dict[ 'J129'] # one of the standard filters, doesn't really matter which with assert_raises(ValueError): galsim.wfirst.getSkyLevel(bp, world_pos=galsim.CelestialCoord( 0. * galsim.degrees, 0. * galsim.degrees)) # near autumn equinox with assert_raises(ValueError): galsim.wfirst.getSkyLevel(bp, world_pos=galsim.CelestialCoord( 180. * galsim.degrees, 5. * galsim.degrees), date=datetime.date(2025, 9, 15)) # world_pos must be a CelestialCoord. with assert_raises(TypeError): galsim.wfirst.getSkyLevel(bp, world_pos=galsim.PositionD(300, 400)) # No world_pos works. Produces sky level for some plausible generic location. sky_level = galsim.wfirst.getSkyLevel(bp) print('sky_level = ', sky_level) np.testing.assert_allclose( sky_level, 6233.47369567) # regression test relative to v1.6 # But not with a non-wfirst bandpass with assert_raises(galsim.GalSimError): galsim.wfirst.getSkyLevel(galsim.Bandpass('wave', 'nm', 400, 550)) # The routine should have some obvious symmetry, for example, ecliptic latitude above vs. below # plane and ecliptic longitude positive vs. negative (or vs. 360 degrees - original value). # Because of how equatorial and ecliptic coordinates are related on the adopted date, we can do # this test as follows: test_ra = 50. * galsim.degrees test_dec = 10. * galsim.degrees test_pos_p = galsim.CelestialCoord(test_ra, test_dec) test_pos_m = galsim.CelestialCoord( -1. * (test_ra / galsim.degrees) * galsim.degrees, -1. * (test_dec / galsim.degrees) * galsim.degrees) level_p = galsim.wfirst.getSkyLevel(bp, world_pos=test_pos_p) level_m = galsim.wfirst.getSkyLevel(bp, world_pos=test_pos_m) np.testing.assert_almost_equal(level_m, level_p, decimal=8) # The routine should handle an input exposure time sensibly. Our original level_p was in # e-/arcsec^2 using the WFIRST exposure time. We will define another exposure time, pass it in, # and confirm that the output is consistent with this. level_p_2 = galsim.wfirst.getSkyLevel(bp, world_pos=test_pos_p, exptime=1.7 * galsim.wfirst.exptime) np.testing.assert_almost_equal(1.7 * level_p, level_p_2, decimal=8)
def test_wfirst_backgrounds(): """Test the WFIRST background estimation routines for basic sanity. """ import time import datetime t1 = time.time() # The routine should not allow us to look directly at the sun since the background there is high # (to understate the problem). If no date is supplied, then the routine assumes RA=dec=0 means # we are looking at the sun. bp_dict = galsim.wfirst.getBandpasses() bp = bp_dict[ 'J129'] # one of the standard filters, doesn't really matter which try: np.testing.assert_raises(ValueError, galsim.wfirst.getSkyLevel, bp, world_pos=galsim.CelestialCoord( 0. * galsim.degrees, 0. * galsim.degrees)) # near autumn equinox np.testing.assert_raises(ValueError, galsim.wfirst.getSkyLevel, bp, world_pos=galsim.CelestialCoord( 180. * galsim.degrees, 5. * galsim.degrees), date=datetime.date(2025, 9, 15)) except ImportError: print 'The assert_raises tests require nose' # The routine should have some obvious symmetry, for example, ecliptic latitude above vs. below # plane and ecliptic longitude positive vs. negative (or vs. 360 degrees - original value). # Because of how equatorial and ecliptic coordinates are related on the adopted date, we can do # this test as follows: test_ra = 50. * galsim.degrees test_dec = 10. * galsim.degrees test_pos_p = galsim.CelestialCoord(test_ra, test_dec) test_pos_m = galsim.CelestialCoord( -1. * (test_ra / galsim.degrees) * galsim.degrees, -1. * (test_dec / galsim.degrees) * galsim.degrees) level_p = galsim.wfirst.getSkyLevel(bp, world_pos=test_pos_p) level_m = galsim.wfirst.getSkyLevel(bp, world_pos=test_pos_m) np.testing.assert_almost_equal(level_m, level_p, decimal=8) # The routine should handle an input exposure time sensibly. Our original level_p was in # e-/arcsec^2 using the WFIRST exposure time. We will define another exposure time, pass it in, # and confirm that the output is consistent with this. level_p_2 = galsim.wfirst.getSkyLevel(bp, world_pos=test_pos_p, exptime=1.7 * galsim.wfirst.exptime) np.testing.assert_almost_equal(1.7 * level_p, level_p_2, decimal=8) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def buildWCS(self, config, base, logger): index, index_key = galsim.config.GetIndex(config, base) if index == 0: return galsim.TanWCS( galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024,1024)), galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees)) elif index == 1: return galsim.TanWCS( galsim.AffineTransform(0.25, -0.02, 0.01, 0.24, galsim.PositionD(1024,1024)), galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)) else: raise ValueError("Custom WCS only supports building 2 WCS's")
def test_galactic(): """Test the conversion from equatorial to galactic coordinates.""" # According to wikipedia: http://en.wikipedia.org/wiki/Galactic_coordinate_system # the galactic center is located at 17h:45.6m, -28.94d # But I get more precise values from https://arxiv.org/pdf/1010.3773.pdf center = galsim.CelestialCoord( galsim.Angle.from_hms('17:45:37.1991'), galsim.Angle.from_dms('-28:56:10.2207')) print('center.galactic = ',center.galactic()) el,b = center.galactic() np.testing.assert_almost_equal(el.wrap().rad, 0., decimal=8) np.testing.assert_almost_equal(b.rad, 0., decimal=8) # Go back from galactic coords to CelestialCoord center2 = galsim.CelestialCoord.from_galactic(el,b) np.testing.assert_allclose(center2.ra.rad, center.ra.rad) np.testing.assert_allclose(center2.dec.rad, center.dec.rad) # The north pole is at 12h:51.4m, 27.13d again with more precise values from the above paper. north = galsim.CelestialCoord( galsim.Angle.from_hms('12:51:26.27549'), galsim.Angle.from_dms('27:07:41.7043')) print('north.galactic = ',north.galactic()) el,b = north.galactic() np.testing.assert_allclose(b.rad, pi/2.) north2 = galsim.CelestialCoord.from_galactic(el,b) np.testing.assert_allclose(north2.ra.rad, north.ra.rad) np.testing.assert_allclose(north2.dec.rad, north.dec.rad) south = galsim.CelestialCoord( galsim.Angle.from_hms('00:51:26.27549'), galsim.Angle.from_dms('-27:07:41.7043')) print('south.galactic = ',south.galactic()) el,b = south.galactic() np.testing.assert_allclose(b.rad, -pi/2.) south2 = galsim.CelestialCoord.from_galactic(el,b) np.testing.assert_allclose(south2.ra.rad, south.ra.rad) np.testing.assert_allclose(south2.dec.rad, south.dec.rad) anticenter = galsim.CelestialCoord( galsim.Angle.from_hms('05:45:37.1991'), galsim.Angle.from_dms('28:56:10.2207')) print('anticenter.galactic = ',anticenter.galactic()) el,b = anticenter.galactic() np.testing.assert_almost_equal(el.rad, pi, decimal=8) np.testing.assert_almost_equal(b.rad, 0., decimal=8) anticenter2 = galsim.CelestialCoord.from_galactic(el,b) np.testing.assert_allclose(anticenter2.ra.rad, anticenter.ra.rad) np.testing.assert_allclose(anticenter2.dec.rad, anticenter.dec.rad)
def test_precess(): """Test precession between epochs.""" # I don't have much of a test here. The formulae are what they are. # But it should at least be the case that a precession trip that ends up # back at the original epoch should leave the coord unchanged. orig = galsim.CelestialCoord(0.234 * galsim.radians, 0.342 * galsim.radians) # First the trivial case of no precession. c0 = orig.precess(2000., 2000.) numpy.testing.assert_almost_equal(c0.ra.rad, orig.ra.rad) numpy.testing.assert_almost_equal(c0.dec.rad, orig.dec.rad) # Now to 1950 and back (via 1900). c1 = orig.precess(2000., 1950.) c2 = c1.precess(1950., 1900.) c3 = c2.precess(1900., 2000.) numpy.testing.assert_almost_equal(c3.ra.rad, orig.ra.rad) numpy.testing.assert_almost_equal(c3.dec.rad, orig.dec.rad) # I found a website that does precession calculations, so check that we are # consistent with them. # http://www.bbastrodesigns.com/coordErrors.html dra_1950 = -(2. + 39.07/60.)/60. * galsim.hours / galsim.radians ddec_1950 = -(16. + 16.3/60.)/60. * galsim.degrees / galsim.radians print('delta from website: ',dra_1950,ddec_1950) print('delta from precess: ',(c1.ra-orig.ra),(c1.dec-orig.dec)) numpy.testing.assert_almost_equal(dra_1950, c1.ra.rad-orig.ra.rad, decimal=5) numpy.testing.assert_almost_equal(ddec_1950, c1.dec.rad-orig.dec.rad, decimal=5) dra_1900 = -(5. + 17.74/60.)/60. * galsim.hours / galsim.radians ddec_1900 = -(32. + 35.4/60.)/60. * galsim.degrees / galsim.radians print('delta from website: ',dra_1900,ddec_1900) print('delta from precess: ',(c2.ra-orig.ra),(c2.dec-orig.dec)) numpy.testing.assert_almost_equal(dra_1900, c2.ra.rad-orig.ra.rad, decimal=5) numpy.testing.assert_almost_equal(ddec_1900, c2.dec.rad-orig.dec.rad, decimal=5)
def get_coadd_center_gs_pos(coadd_wcs, coadd_bbox): """ get the sky position of the center of the coadd within the bbox as a galsim CelestialCoord Parameters ---------- coadd_wcs: DM wcs The wcs for the coadd coadd_bbox: geom.Box2I The bounding box for the coadd within larger wcs system Returns ------- galsim CelestialCoord """ # world origin is at center of the coadd, which itself # is in a bbox shifted from the overall WORLD_ORIGIN bbox_cen_skypos = coadd_wcs.pixelToSky(coadd_bbox.getCenter()) return galsim.CelestialCoord( ra=float(bbox_cen_skypos.getRa()) * galsim.radians, dec=float(bbox_cen_skypos.getDec()) * galsim.radians, )
def test_passing_camera_by_hand(self): """ Test that you can pass a camera from one WCS to another """ with warnings.catch_warnings(record=True) as ww: wcs1 = LsstWCS(self.pointing, self.rotation, chip_name='R:0,1 S:1,1', camera=self.wcs.camera) self.assertEqual(len(ww), 0) # verify that, if the camera does not have the pointing or rotation angle you want, # a new camera will be instantiated with warnings.catch_warnings(record=True) as ww: wcs1 = LsstWCS(galsim.CelestialCoord(0.0*galsim.degrees, 0.0*galsim.degrees), self.rotation, chip_name='R:0,1 S:1,1', camera=self.wcs.camera) expected_message = "The camera you passed to LsstWCS does not have the same\n" \ "pointing and rotation angle as you asked for for this WCS.\n" \ "LsstWCS is creating a new camera with the pointing and\n" \ "rotation angle you specified in the constructor for LsstWCS." self.assertEqual(str(ww[0].message), expected_message) with warnings.catch_warnings(record=True) as ww: wcs1 = LsstWCS(self.pointing, 49.0*galsim.degrees, chip_name='R:0,1 S:1,1', camera=self.wcs.camera) expected_message = "The camera you passed to LsstWCS does not have the same\n" \ "pointing and rotation angle as you asked for for this WCS.\n" \ "LsstWCS is creating a new camera with the pointing and\n" \ "rotation angle you specified in the constructor for LsstWCS." self.assertEqual(str(ww[0].message), expected_message)
def buildWCS(self, config, base, logger): """Build the TanWCS based on the specifications in the config dict. @param config The configuration dict for the wcs type. @param base The base configuration dict. @param logger If provided, a logger for logging debug statements. @returns the constructed WCS object. """ req = { "dudx" : float, "dudy" : float, "dvdx" : float, "dvdy" : float, "ra" : galsim.Angle, "dec" : galsim.Angle } opt = { "units" : str, "origin" : galsim.PositionD } params, safe = galsim.config.GetAllParams(config, base, req=req, opt=opt) dudx = params['dudx'] dudy = params['dudy'] dvdx = params['dvdx'] dvdy = params['dvdy'] ra = params['ra'] dec = params['dec'] units = params.get('units', 'arcsec') origin = params.get('origin', None) affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin) world_origin = galsim.CelestialCoord(ra, dec) units = galsim.angle.get_angle_unit(units) return galsim.TanWCS(affine=affine, world_origin=world_origin, units=units)
def _GenerateFromRADec(config, base, value_type): """@brief Return a CelestialCoord constructed from given (ra,dec) """ req = { 'ra' : galsim.Angle, 'dec' : galsim.Angle } kwargs, safe = GetAllParams(config, base, req=req) #print(base['obj_num'],'Generate from RADec: kwargs = ',kwargs) return galsim.CelestialCoord(**kwargs), safe
def _ecliptic_to_equatorial(ecliptic_pos, epoch): # Helper routine to go backwards from ecliptic coordinates to equatorial using a given epoch for # the obliquity of the ecliptic. # Should input a tuple of (lam, beta) values and an epoch, and get back a CelestialCoord. lam, beta = ecliptic_pos import math # Get the (x, y, z)_ecliptic from (lam, beta). cosbeta = math.cos(beta.rad()) sinbeta = math.sin(beta.rad()) coslam = math.cos(lam.rad()) sinlam = math.sin(lam.rad()) x_ecl = cosbeta * coslam y_ecl = cosbeta * sinlam z_ecl = sinbeta # Transform to (x, y, z)_equatorial. ep = _ecliptic_obliquity(epoch) cos_ep = math.cos(ep.rad()) sin_ep = math.sin(ep.rad()) x_eq = x_ecl y_eq = cos_ep * y_ecl - sin_ep * z_ecl z_eq = sin_ep * y_ecl + cos_ep * z_ecl # Transform to RA, dec. dec = math.asin(z_eq) * galsim.radians ra = math.atan2(y_eq, x_eq) * galsim.radians # Return as a CelestialCoord return galsim.CelestialCoord(ra, dec)
def _readHeader(header): pointing = galsim.CelestialCoord( header.get("RApoint") * galsim.radians, header.get("DECpoint") * galsim.radians) rot = header.get("ROT") * galsim.radians return LsstWCS(pointing, rot, header.get("CNAME"))
def test_roman_psf_wcs(): """Test drawing the PSF with a provided WCS.""" # Make a PSF without giving a wcs image_pos = galsim.PositionD(153, 921) psf = galsim.roman.getPSF(SCA=5, bandpass='******', wavelength=1950., pupil_bin=8, SCA_pos=image_pos) # Draw it on an image with pixel_scale wcs im_scale = psf.drawImage(scale=galsim.roman.pixel_scale, center=image_pos) # Get a plausible commemorative observation for Roman's 100th birthday. world_pos = galsim.CelestialCoord( ra=galsim.Angle.from_hms('16:01:41.01257'), # AG Draconis dec=galsim.Angle.from_dms('66:48:10.1312')) PA = 112 * galsim.degrees # Random. date = datetime.datetime(2025, 5, 16) # NGR's 100th birthday. wcs_dict = galsim.roman.getWCS(PA=PA, world_pos=world_pos, date=date) wcs = wcs_dict[5] # Get the PSF in real world coordinates with this wcs psf = galsim.roman.getPSF(SCA=5, bandpass='******', wavelength=1950., pupil_bin=8, SCA_pos=image_pos, wcs=wcs) # Draw on an image with this wcs. im_wcs = psf.drawImage(bounds=im_scale.bounds, wcs=wcs, center=image_pos) np.testing.assert_allclose(im_wcs.array, im_scale.array)
def test_pickle(): """Test the reading a file written with python 2 pickling is readable with python 2 or 3. """ if __name__ == '__main__': logger = piff.config.setup_logger(verbose=2) else: logger = piff.config.setup_logger(log_file='output/test_pickle.log') # First, this is the output file written by the above test_single function on python 2. # Shoudl be trivially readable by python 2, but make sure it is also readable by python 3. psf = piff.read('input/test_single_py27.piff', logger=logger) wcs1 = galsim.TanWCS( galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024, 1024)), galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees)) wcs2 = galsim.TanWCS( galsim.AffineTransform(0.25, -0.02, 0.01, 0.24, galsim.PositionD(1024, 1024)), galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)) data1 = fitsio.read('input/test_single_cat1.fits') data2 = fitsio.read('input/test_single_cat2.fits') field_center = galsim.CelestialCoord(0 * galsim.degrees, -25 * galsim.degrees) for chipnum, data, wcs in [(1, data1, wcs1), (2, data2, wcs2)]: for k in range(len(data)): x = data['x'][k] y = data['y'][k] e1 = data['e1'][k] e2 = data['e2'][k] s = data['s'][k] #print('k,x,y = ',k,x,y) #print(' true s,e1,e2 = ',s,e1,e2) image_pos = galsim.PositionD(x, y) star = piff.Star.makeTarget(x=x, y=y, wcs=wcs, stamp_size=48, pointing=field_center, chipnum=chipnum) star = psf.drawStar(star) #print(' fitted s,e1,e2 = ',star.fit.params) np.testing.assert_almost_equal(star.fit.params, [s, e1, e2], decimal=6)
def TanWCSBuilder(dudx, dudy, dvdx, dvdy, ra, dec, units='arcsec', origin=galsim.PositionD(0,0)): # The TanWCS uses a custom builder because the normal function takes an AffineTransform, which # we need to construct. It also takes a CelestialCoord for its world_origin parameter, so we # make that out of ra and dec parameters. affine = galsim.AffineTransform(dudx, dudy, dvdx, dvdy, origin) world_origin = galsim.CelestialCoord(ra, dec) units = galsim.angle.get_angle_unit(units) return galsim.TanWCS(affine, world_origin, units)
def __call__(self, ind): pos = self.wcs.toImage(galsim.CelestialCoord( ra=self.truth_cat['ra'][ind] * galsim.degrees, dec=self.truth_cat['dec'][ind] * galsim.degrees)) obj = galsim.Exponential(half_light_radius=0.5).withFlux(64000) obj = obj.shear(g1=self.g1, g2=self.g2) psf = self.psf.getPSF(image_pos=pos) return galsim.Convolve([obj, psf]), pos
def make_a_star(ud, this_im_wcs, psf, affine): # Choose a random RA, Dec around the sky_center. center_dec = this_im_wcs.center.dec center_ra = this_im_wcs.center.ra dec = center_dec + (ud() - 0.5) * image_ysize_arcsec * galsim.arcsec ra = center_ra + ( ud() - 0.5) * image_xsize_arcsec / numpy.cos(dec) * galsim.arcsec world_pos = galsim.CelestialCoord(ra, dec) # We will need the image position as well, so use the wcs to get that image_pos = this_im_wcs.posToImage(world_pos) # We also need this in the tangent plane, which we call "world coordinates" here, # since the PowerSpectrum class is really defined on that plane, not in (ra,dec). # This is still an x/y corrdinate uv_pos = affine.toWorld(image_pos) # Draw star flux at random; based on distribution of star fluxes in real images # Generate PSF at location of star, convolve simple Airy with the PSF to make a star flux_dist = galsim.DistDeviate( ud, function= '/Users/jemcclea/Research/GalSim/examples/output/empirical_psfs/v2/stars_flux300_prob.txt' ) #,interpolant='floor') star_flux = (flux_dist()) * (exp_time / 300.) shining_star = galsim.Airy(lam=lam, obscuration=0.3840, diam=tel_diam, scale_unit=galsim.arcsec, flux=star_flux) this_psf = psf.getPSF(image_pos) star = galsim.Convolve([shining_star, this_psf]) # Account for the fractional part of the position # cf. demo9.py for an explanation of this nominal position stuff. x_nominal = image_pos.x + 0.5 y_nominal = image_pos.y + 0.5 ix_nominal = int(math.floor(x_nominal + 0.5)) iy_nominal = int(math.floor(y_nominal + 0.5)) dx = x_nominal - ix_nominal dy = y_nominal - iy_nominal offset = galsim.PositionD(dx, dy) star_stamp = star.drawImage(wcs=this_im_wcs.local(image_pos), offset=offset, method='no_pixel') # Recenter the stamp at the desired position: star_stamp.setCenter(ix_nominal, iy_nominal) star_truth = truth() star_truth.ra = ra.deg star_truth.dec = dec.deg star_truth.x = ix_nominal star_truth.y = iy_nominal return star_stamp, star_truth
def make_a_star(ud, wcs, psf, affine): # Choose a random RA, Dec around the sky_center. dec = center_dec + (ud() - 0.5) * image_ysize_arcsec * galsim.arcsec ra = center_ra + ( ud() - 0.5) * image_xsize_arcsec / numpy.cos(dec) * galsim.arcsec world_pos = galsim.CelestialCoord(ra, dec) # We will need the image position as well, so use the wcs to get that image_pos = wcs.toImage(world_pos) # We also need this in the tangent plane, which we call "world coordinates" here, # This is still an x/y corrdinate uv_pos = affine.toWorld(image_pos) # Draw star flux at random; based on distribution of star fluxes in real images # Generate PSF at location of star, convolve simple Airy with the PSF to make a star flux_dist = galsim.DistDeviate(ud, function=lambda x: x**-1, x_min=799.2114, x_max=890493.9) """ flux_dist = galsim.DistDeviate(ud, function = lambda x:x**-1.5, x_min = 3000, x_max = 30000) """ star_flux = flux_dist() shining_star = galsim.Airy(lam=lam, obscuration=0.380, diam=tel_diam, scale_unit=galsim.arcsec, flux=star_flux) this_psf = psf.getPSF(image_pos) star = galsim.Convolve([shining_star, optics, this_psf]) #star=galsim.Convolve([shining_star,this_psf]) # Account for the fractional part of the position # cf. demo9.py for an explanation of this nominal position stuff. x_nominal = image_pos.x + 0.5 y_nominal = image_pos.y + 0.5 ix_nominal = int(math.floor(x_nominal + 0.5)) iy_nominal = int(math.floor(y_nominal + 0.5)) dx = x_nominal - ix_nominal dy = y_nominal - iy_nominal offset = galsim.PositionD(dx, dy) #star_stamp = star.drawImage(wcs=wcs.local(image_pos), offset=offset, method='no_pixel') star_stamp = star.drawImage(wcs=wcs.local(image_pos), offset=offset) #,method='no_pixel') # Recenter the stamp at the desired position: star_stamp.setCenter(ix_nominal, iy_nominal) star_truth = truth() star_truth.ra = ra.deg star_truth.dec = dec.deg star_truth.x = ix_nominal star_truth.y = iy_nominal return star_stamp, star_truth
def roman_psf_rotation(): b = galsim.BoundsI(1,32,1,32) WCS1 = wfirst.getWCS(world_pos = galsim.CelestialCoord(ra=100*galsim.degrees, dec=-10*galsim.degrees), PA = 0.*galsim.radians)[1] WCS2 = wfirst.getWCS(world_pos = galsim.CelestialCoord(ra=100*galsim.degrees, dec=-10*galsim.degrees), PA = 30.*galsim.radians)[1] psf1 = wfirst.getPSF(1, 'H158', wcs=WCS1, pupil_bin=4, wavelength=wfirst.getBandpasses(AB_zeropoint=True)['H158'].effective_wavelength) psf2 = wfirst.getPSF(1, 'H158', wcs=WCS2, pupil_bin=4, wavelength=wfirst.getBandpasses(AB_zeropoint=True)['H158'].effective_wavelength) #star_model1 = galsim.DeltaFunction(flux=1.) #star_model2 = galsim.DeltaFunction(flux=1.) star_stamp1 = galsim.Image(b, scale=wfirst.pixel_scale) star_stamp2 = galsim.Image(b, scale=wfirst.pixel_scale) #star_model1 = galsim.Convolve(star_model1, psf1) #star_model2 = galsim.Convolve(star_model2, psf2) psf1.drawImage(image=star_stamp1) psf2.drawImage(image=star_stamp2) np.savetxt("/hpc/group/cosmology/masaya/wfirst_simulation/paper/roman_psf_PA0b.txt", star_stamp1.array) np.savetxt("/hpc/group/cosmology/masaya/wfirst_simulation/paper/roman_psf_PA30b.txt", star_stamp2.array)
def safe_to_image(wcs, ra, dec): try: return wcs.toImage( galsim.CelestialCoord(ra * ra_units, dec * dec_units)) except galsim.GalSimError: # pragma: no cover # If the ra,dec is way off the image, this might fail to converge. # In this case return something clearly not on an image so it gets # excluded during the bounds check. return galsim.PositionD(1.e99, 1.e99)
def test_attribute_exceptions(self): """ Test that exceptions are raised when you try to set attributes """ with self.assertRaises(AttributeError) as context: self.camera.pointing = galsim.CelestialCoord(34.0*galsim.degrees, 18.0*galsim.degrees) with self.assertRaises(AttributeError) as context: self.camera.rotation_angle = 56.0*galsim.degrees
def galsim_world2pix(wcs_, ra_list, dec_list): npos = len(ra_list) px = np.zeros(npos) py = np.zeros(npos) for j in range(npos): radecpos = galsim.CelestialCoord(ra=ra_list[j] * galsim.degrees, dec=dec_list[j] * galsim.degrees) xypos = wcs_.toImage(radecpos) px[j] = xypos.x py[j] = xypos.y return px, py
def test_attribute_exceptions(self): """ Test that exceptions are raised when you try to set attributes """ start = time.clock() with self.assertRaises(AttributeError) as context: self.camera.pointing = galsim.CelestialCoord(34.0*galsim.degrees, 18.0*galsim.degrees) with self.assertRaises(AttributeError) as context: self.camera.rotation_angle = 56.0*galsim.degrees print 'time to run %s = %e sec' % (funcname(), time.clock()-start)
def test_galactic(): """Test the conversion from equatorial to galactic coordinates.""" import time t1 = time.time() # According to wikipedia: http://en.wikipedia.org/wiki/Galactic_coordinate_system # the galactic center is located at 17h:45.6m, -28.94d center = galsim.CelestialCoord((17. + 45.6 / 60.) * galsim.hours, -28.94 * galsim.degrees) print 'center.galactic = ', center.galactic() el, b = center.galactic() numpy.testing.assert_almost_equal(el.rad(), 0., decimal=3) numpy.testing.assert_almost_equal(b.rad(), 0., decimal=3) # The north pole is at 12h:51.4m, 27.13d north = galsim.CelestialCoord((12. + 51.4 / 60.) * galsim.hours, 27.13 * galsim.degrees) print 'north.galactic = ', north.galactic() el, b = north.galactic() numpy.testing.assert_almost_equal(b.rad(), pi / 2., decimal=3) # The south pole is at 0h:51.4m, -27.13d south = galsim.CelestialCoord((0. + 51.4 / 60.) * galsim.hours, -27.13 * galsim.degrees) print 'south.galactic = ', south.galactic() el, b = south.galactic() numpy.testing.assert_almost_equal(b.rad(), -pi / 2., decimal=3) # The anti-center is at 5h:42.6m, 28.92d anticenter = galsim.CelestialCoord((5. + 45.6 / 60.) * galsim.hours, 28.94 * galsim.degrees) print 'anticenter.galactic = ', anticenter.galactic() el, b = anticenter.galactic() numpy.testing.assert_almost_equal(el.rad(), pi, decimal=3) numpy.testing.assert_almost_equal(b.rad(), 0., decimal=3) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_extra_interp(): # Test that specifying extra_interp_properties works properly # TODO: This is a very bare bones test of the interface. There is basically no test of # this functionality at all yet. TBD! sigma = 1.3 g1 = 0.23 g2 = -0.17 psf = galsim.Gaussian(sigma=sigma).shear(g1=g1, g2=g2) wcs = galsim.JacobianWCS(0.26, 0.05, -0.08, -0.29) image = galsim.Image(64, 64, wcs=wcs) psf.drawImage(image, method='no_pixel') # use g-i color as an extra property for interpolation. props = dict(gi_color=0.3) print('props = ', props) star = piff.Star(piff.StarData(image, image.true_center, properties=props), None) model = piff.Gaussian(fastfit=True, include_pixel=False) interp = piff.Mean() psf = piff.SimplePSF(model, interp, extra_interp_properties=['gi_color']) assert psf.extra_interp_properties == ['gi_color'] # Note: Mean doesn't actually do anything useful with the extra properties, so this # isn't really testing anything other than that the code doesn't completely break. pointing = galsim.CelestialCoord(-5 * galsim.arcmin, -25 * galsim.degrees) psf.fit([star], wcs={0: wcs}, pointing=pointing) # Not much of a check here. Just check that it actually draws something with flux ~= 1 im = psf.draw(x=5, y=7, gi_color=0.3) np.testing.assert_allclose(im.array.sum(), 1.0, rtol=1.e-3) # Check missing or extra properties with np.testing.assert_raises(TypeError): psf.draw(x=5, y=7) with np.testing.assert_raises(TypeError): psf.draw(x=5, y=7, gi_color=0.3, ri_color=3) # No stars raises an error. (This can happen in practice if all stars are excluded on input.) with np.testing.assert_raises(RuntimeError): psf.fit([], wcs={0: wcs}, pointing=pointing) # Also for SingleChipPSf psf2 = piff.SingleChipPSF(psf, extra_interp_properties=['gi_color']) assert psf2.extra_interp_properties == ['gi_color'] with np.testing.assert_raises(TypeError): psf2.draw(x=5, y=7, chipnum=0)
def setup(): """Build an input image and catalog used by a few tests below. """ wcs = galsim.TanWCS( galsim.AffineTransform(0.26, 0.05, -0.08, -0.24, galsim.PositionD(1024, 1024)), #galsim.AffineTransform(0.26, 0., 0., 0.26, galsim.PositionD(1024,1024)), galsim.CelestialCoord(5 * galsim.arcmin, -25 * galsim.degrees)) # Make the image (copied from test_single_image in test_simple.py) image = galsim.Image(2048, 2048, wcs=wcs) # Where to put the stars. x_list = [ 123.12, 345.98, 567.25, 1094.94, 924.15, 1532.74, 1743.11, 888.39, 1033.29, 1409.31 ] y_list = [ 345.43, 567.45, 1094.32, 924.29, 1532.92, 1743.83, 888.83, 1033.19, 1409.20, 123.11 ] # Draw a Gaussian PSF at each location on the image. sigma = 1.3 g1 = 0.23 g2 = -0.17 du = 0.09 # in arcsec dv = -0.07 flux = 123.45 psf = galsim.Gaussian(sigma=sigma).shear(g1=g1, g2=g2).shift(du, dv) * flux for x, y in zip(x_list, y_list): bounds = galsim.BoundsI(int(x - 31), int(x + 32), int(y - 31), int(y + 32)) offset = galsim.PositionD(x - int(x) - 0.5, y - int(y) - 0.5) psf.drawImage(image=image[bounds], method='no_pixel', offset=offset) image.addNoise( galsim.GaussianNoise(rng=galsim.BaseDeviate(1234), sigma=1e-6)) # Write out the image to a file image_file = os.path.join('output', 'test_stats_image.fits') image.write(image_file) # Write out the catalog to a file dtype = [('x', 'f8'), ('y', 'f8')] data = np.empty(len(x_list), dtype=dtype) data['x'] = x_list data['y'] = y_list cat_file = os.path.join('output', 'test_stats_cat.fits') fitsio.write(cat_file, data, clobber=True)
def test_celestialcoord_basic(): """Basic tests of CelestialCoord construction. etc. """ c1 = galsim.CelestialCoord(0. * galsim.radians, 0. * galsim.radians) numpy.testing.assert_almost_equal(c1.ra.rad, 0., decimal=12) numpy.testing.assert_almost_equal(c1.dec.rad, 0., decimal=12) c2 = galsim.CelestialCoord(11. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c2.ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c2.dec / galsim.degrees, -37., decimal=12) c3 = galsim.CelestialCoord(35. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c3.normal().ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c3.normal().dec / galsim.degrees, -37., decimal=12) c4 = galsim.CelestialCoord(-13. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c4.normal().ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c4.normal().dec / galsim.degrees, -37., decimal=12) numpy.testing.assert_almost_equal(c2.distanceTo(c3).rad, 0., decimal=12) numpy.testing.assert_almost_equal(c2.distanceTo(c4).rad, 0., decimal=12) x, y, z = c1.get_xyz() print('c1 is at x,y,z = ', x, y, z) np.testing.assert_equal((x, y, z), (1, 0, 0)) assert c1 == galsim.CelestialCoord.from_xyz(x, y, z) x, y, z = c2.get_xyz() print('c2 is at x,y,z = ', x, y, z) assert c2 == galsim.CelestialCoord.from_xyz(x, y, z) assert_raises(ValueError, galsim.CelestialCoord.from_xyz, 0, 0, 0) # Check picklability do_pickle(c1) do_pickle(c2) do_pickle(c3) do_pickle(c4) assert c1 == galsim.CelestialCoord(ra=0. * galsim.degrees, dec=0. * galsim.degrees) assert c2 == galsim.CelestialCoord(ra=165. * galsim.degrees, dec=-37. * galsim.degrees) assert c1 != c2 assert c1 != c3 assert c1 != c4
def test_celestialcoord_basic(): """Basic tests of CelestialCoord construction. etc. """ c1 = galsim.CelestialCoord(0. * galsim.radians, 0. * galsim.radians) numpy.testing.assert_almost_equal(c1.ra.rad(), 0., decimal=12) numpy.testing.assert_almost_equal(c1.dec.rad(), 0., decimal=12) c2 = galsim.CelestialCoord(11. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c2.ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c2.dec / galsim.degrees, -37., decimal=12) c3 = galsim.CelestialCoord(35. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c3.ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c3.dec / galsim.degrees, -37., decimal=12) c4 = galsim.CelestialCoord(-13. * galsim.hours, -37. * galsim.degrees) numpy.testing.assert_almost_equal(c4.ra / galsim.hours, 11., decimal=12) numpy.testing.assert_almost_equal(c4.dec / galsim.degrees, -37., decimal=12) numpy.testing.assert_almost_equal(c2.distanceTo(c3).rad(), 0., decimal=12) numpy.testing.assert_almost_equal(c2.distanceTo(c4).rad(), 0., decimal=12) x, y, z = c1.get_xyz() print('c1 is at x,y,z = ', x, y, z) np.testing.assert_equal((x, y, z), (1, 0, 0)) assert c1 == galsim.CelestialCoord.from_xyz(x, y, z) x, y, z = c2.get_xyz() print('c2 is at x,y,z = ', x, y, z) assert c2 == galsim.CelestialCoord.from_xyz(x, y, z) # 0,0,0 shouldn't die at least, although the return value is a bit arbitrary. c5 = galsim.CelestialCoord.from_xyz(0, 0, 0) print('0,0,0 returns coord ', c5) # Check picklability do_pickle(c1) do_pickle(c2) do_pickle(c3) do_pickle(c4) do_pickle(c5) assert c1 == galsim.CelestialCoord(ra=0. * galsim.degrees, dec=0. * galsim.degrees) assert c2 == galsim.CelestialCoord(ra=165. * galsim.degrees, dec=-37. * galsim.degrees) assert c1 != c2 assert c1 != c3 assert c1 != c4