def test_dcr(): """Test the dcr surface op """ # This tests that implementing DCR with the surface op is equivalent to using # ChromaticAtmosphere. # We use fairly extreme choices for the parameters to make the comparison easier, so # we can still get good discrimination of any errors with only 10^6 photons. zenith_angle = 45 * galsim.degrees # Larger angle has larger DCR. parallactic_angle = 129 * galsim.degrees # Something random, not near 0 or 180 pixel_scale = 0.03 # Small pixel scale means shifts are many pixels, rather than a fraction. alpha = -1.2 # The normal alpha is -0.2, so this is exaggerates the effect. bandpass = galsim.Bandpass('LSST_r.dat', 'nm') base_wavelength = bandpass.effective_wavelength base_wavelength += 500 # This exaggerates the effects fairly substantially. sed = galsim.SED('CWW_E_ext.sed', wave_type='ang', flux_type='flambda') flux = 1.e6 base_PSF = galsim.Kolmogorov(fwhm=0.3) # Use ChromaticAtmosphere im1 = galsim.ImageD(50, 50, scale=pixel_scale) star = galsim.DeltaFunction() * sed star = star.withFlux(flux, bandpass=bandpass) chrom_PSF = galsim.ChromaticAtmosphere(base_PSF, base_wavelength=base_wavelength, zenith_angle=zenith_angle, parallactic_angle=parallactic_angle, alpha=alpha) chrom = galsim.Convolve(star, chrom_PSF) chrom.drawImage(bandpass, image=im1) # Use PhotonDCR im2 = galsim.ImageD(50, 50, scale=pixel_scale) dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, zenith_angle=zenith_angle, parallactic_angle=parallactic_angle, alpha=alpha) achrom = base_PSF.withFlux(flux) rng = galsim.BaseDeviate(31415) wave_sampler = galsim.WavelengthSampler(sed, bandpass, rng) surface_ops = [wave_sampler, dcr] achrom.drawImage(image=im2, method='phot', rng=rng, surface_ops=surface_ops) im1 /= flux # Divide by flux, so comparison is on a relative basis. im2 /= flux printval(im2, im1, show=False) np.testing.assert_almost_equal( im2.array, im1.array, decimal=4, err_msg="PhotonDCR didn't match ChromaticAtmosphere") # Repeat with thinned bandpass and SED to check that thin still works well. im3 = galsim.ImageD(50, 50, scale=pixel_scale) thin = 0.1 # Even higher also works. But this is probably enough. thin_bandpass = bandpass.thin(thin) thin_sed = sed.thin(thin) print('len bp = %d => %d' % (len(bandpass.wave_list), len(thin_bandpass.wave_list))) print('len sed = %d => %d' % (len(sed.wave_list), len(thin_sed.wave_list))) wave_sampler = galsim.WavelengthSampler(thin_sed, thin_bandpass, rng) achrom.drawImage(image=im3, method='phot', rng=rng, surface_ops=surface_ops) im3 /= flux printval(im3, im1, show=False) np.testing.assert_almost_equal( im3.array, im1.array, decimal=4, err_msg="thinning factor %f led to 1.e-4 level inaccuracy" % thin) # Check scale_unit im4 = galsim.ImageD(50, 50, scale=pixel_scale / 60) dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, zenith_angle=zenith_angle, parallactic_angle=parallactic_angle, scale_unit='arcmin', alpha=alpha) surface_ops = [wave_sampler, dcr] achrom.dilate(1. / 60).drawImage(image=im4, method='phot', rng=rng, surface_ops=surface_ops) im4 /= flux printval(im4, im1, show=False) np.testing.assert_almost_equal( im4.array, im1.array, decimal=4, err_msg="PhotonDCR with scale_unit=arcmin, didn't match") # Check some other valid options # alpha = 0 means don't do any size scaling. # obj_coord, HA and latitude are another option for setting the angles # pressure, temp, and water pressure are settable. # Also use a non-trivial WCS. wcs = galsim.FitsWCS('des_data/DECam_00154912_12_header.fits') image = galsim.Image(50, 50, wcs=wcs) bandpass = galsim.Bandpass('LSST_r.dat', wave_type='nm').thin(0.1) base_wavelength = bandpass.effective_wavelength lsst_lat = galsim.Angle.from_dms('-30:14:23.76') lsst_long = galsim.Angle.from_dms('-70:44:34.67') local_sidereal_time = 3.14 * galsim.hours # Not pi. This is the time for this observation. im5 = galsim.ImageD(50, 50, wcs=wcs) obj_coord = wcs.toWorld(im5.true_center) base_PSF = galsim.Kolmogorov(fwhm=0.9) achrom = base_PSF.withFlux(flux) dcr = galsim.PhotonDCR( base_wavelength=bandpass.effective_wavelength, obj_coord=obj_coord, HA=local_sidereal_time - obj_coord.ra, latitude=lsst_lat, pressure=72, # default is 69.328 temperature=290, # default is 293.15 H2O_pressure=0.9) # default is 1.067 #alpha=0) # default is 0, so don't need to set it. surface_ops = [wave_sampler, dcr] achrom.drawImage(image=im5, method='phot', rng=rng, surface_ops=surface_ops) im6 = galsim.ImageD(50, 50, wcs=wcs) star = galsim.DeltaFunction() * sed star = star.withFlux(flux, bandpass=bandpass) chrom_PSF = galsim.ChromaticAtmosphere( base_PSF, base_wavelength=bandpass.effective_wavelength, obj_coord=obj_coord, HA=local_sidereal_time - obj_coord.ra, latitude=lsst_lat, pressure=72, temperature=290, H2O_pressure=0.9, alpha=0) chrom = galsim.Convolve(star, chrom_PSF) chrom.drawImage(bandpass, image=im6) im5 /= flux # Divide by flux, so comparison is on a relative basis. im6 /= flux printval(im5, im6, show=False) np.testing.assert_almost_equal( im5.array, im6.array, decimal=3, err_msg="PhotonDCR with alpha=0 didn't match") # Also check invalid parameters zenith_coord = galsim.CelestialCoord(13.54 * galsim.hours, lsst_lat) assert_raises( TypeError, galsim.PhotonDCR, zenith_angle=zenith_angle, parallactic_angle=parallactic_angle) # base_wavelength is required assert_raises(TypeError, galsim.PhotonDCR, base_wavelength=500, parallactic_angle=parallactic_angle ) # zenith_angle (somehow) is required assert_raises( TypeError, galsim.PhotonDCR, 500, zenith_angle=34.4, parallactic_angle=parallactic_angle) # zenith_angle must be Angle assert_raises(TypeError, galsim.PhotonDCR, 500, zenith_angle=zenith_angle, parallactic_angle=34.5) # parallactic_angle must be Angle assert_raises(TypeError, galsim.PhotonDCR, 500, obj_coord=obj_coord, latitude=lsst_lat) # Missing HA assert_raises(TypeError, galsim.PhotonDCR, 500, obj_coord=obj_coord, HA=local_sidereal_time - obj_coord.ra) # Missing latitude assert_raises(TypeError, galsim.PhotonDCR, 500, obj_coord=obj_coord) # Need either zenith_coord, or (HA,lat) assert_raises(TypeError, galsim.PhotonDCR, 500, obj_coord=obj_coord, zenith_coord=zenith_coord, HA=local_sidereal_time - obj_coord.ra) # Can't have both HA and zenith_coord assert_raises(TypeError, galsim.PhotonDCR, 500, obj_coord=obj_coord, zenith_coord=zenith_coord, latitude=lsst_lat) # Can't have both lat and zenith_coord assert_raises(TypeError, galsim.PhotonDCR, 500, zenith_angle=zenith_angle, parallactic_angle=parallactic_angle, H20_pressure=1.) # invalid (misspelled) assert_raises(ValueError, galsim.PhotonDCR, 500, zenith_angle=zenith_angle, parallactic_angle=parallactic_angle, scale_unit='inches') # invalid scale_unit # Invalid to use dcr without some way of setting wavelengths. assert_raises(galsim.GalSimError, achrom.drawImage, im2, method='phot', surface_ops=[dcr])
def test_dcr_moments(): """Check that DCR gets the direction of the moment changes correct for some simple geometries. i.e. Basically check the sign conventions used in the DCR code. """ # First, the basics. # 1. DCR shifts blue photons closer to zenith, because the index of refraction larger. # cf. http://lsstdesc.github.io/chroma/ # 2. Galsim models profiles as seen from Earth with North up (and therefore East left). # 3. Hour angle is negative when the object is in the east (soon after rising, say), # zero when crossing the zenith meridian, and then positive to the west. # Use g-band, where the effect is more dramatic across the band than in redder bands. # Also use a reference wavelength significantly to the red, so there should be a net # overall shift towards zenith as well as a shear along the line to zenith. bandpass = galsim.Bandpass('LSST_g.dat', 'nm').thin(0.1) base_wavelength = 600 # > red end of g band # Uniform across the band is fine for this. sed = galsim.SED('1', wave_type='nm', flux_type='fphotons') rng = galsim.BaseDeviate(31415) wave_sampler = galsim.WavelengthSampler(sed, bandpass, rng) star = galsim.Kolmogorov(fwhm=0.3, flux=1.e6) # 10^6 photons should be enough. im = galsim.ImageD( 50, 50, scale=0.05) # Small pixel scale, so shift is many pixels. ra = 0 * galsim.degrees # Completely irrelevant here. lat = -20 * galsim.degrees # Also doesn't really matter much. # 1. HA < 0, Dec < lat Spot should be shifted up and right. e2 > 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=-2 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord( ra, lat - 20 * galsim.degrees)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('1. HA < 0, Dec < lat: ', moments) assert moments['My'] > 0 # up assert moments['Mx'] > 0 # right assert moments['Mxy'] > 0 # e2 > 0 # 2. HA = 0, Dec < lat Spot should be shifted up. e1 < 0, e2 ~= 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=0 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord( ra, lat - 20 * galsim.degrees)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('2. HA = 0, Dec < lat: ', moments) assert moments['My'] > 0 # up assert abs(moments['Mx']) < 0.05 # not left or right assert moments['Mxx'] < moments['Myy'] # e1 < 0 assert abs(moments['Mxy']) < 0.1 # e2 ~= 0 # 3. HA > 0, Dec < lat Spot should be shifted up and left. e2 < 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=2 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord( ra, lat - 20 * galsim.degrees)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('3. HA > 0, Dec < lat: ', moments) assert moments['My'] > 0 # up assert moments['Mx'] < 0 # left assert moments['Mxy'] < 0 # e2 < 0 # 4. HA < 0, Dec = lat Spot should be shifted right. e1 > 0, e2 ~= 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=-2 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord(ra, lat)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('4. HA < 0, Dec = lat: ', moments) assert abs(moments['My'] ) < 1. # not up or down (Actually slightly down in the south.) assert moments['Mx'] > 0 # right assert moments['Mxx'] > moments['Myy'] # e1 > 0 assert abs( moments['Mxy'] ) < 2. # e2 ~= 0 (Actually slightly negative because of curvature.) # 5. HA = 0, Dec = lat Spot should not be shifted. e1 ~= 0, e2 ~= 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=0 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord(ra, lat)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('5. HA = 0, Dec = lat: ', moments) assert abs(moments['My']) < 0.05 # not up or down assert abs(moments['Mx']) < 0.05 # not left or right assert abs(moments['Mxx'] - moments['Myy']) < 0.1 # e1 ~= 0 assert abs(moments['Mxy']) < 0.1 # e2 ~= 0 # 6. HA > 0, Dec = lat Spot should be shifted left. e1 > 0, e2 ~= 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=2 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord(ra, lat)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('6. HA > 0, Dec = lat: ', moments) assert abs(moments['My'] ) < 1. # not up or down (Actually slightly down in the south.) assert moments['Mx'] < 0 # left assert moments['Mxx'] > moments['Myy'] # e1 > 0 assert abs( moments['Mxy'] ) < 2. # e2 ~= 0 (Actually slgihtly positive because of curvature.) # 7. HA < 0, Dec > lat Spot should be shifted down and right. e2 < 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=-2 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord( ra, lat + 20 * galsim.degrees)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('7. HA < 0, Dec > lat: ', moments) assert moments['My'] < 0 # down assert moments['Mx'] > 0 # right assert moments['Mxy'] < 0 # e2 < 0 # 8. HA = 0, Dec > lat Spot should be shifted down. e1 < 0, e2 ~= 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=0 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord( ra, lat + 20 * galsim.degrees)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('8. HA = 0, Dec > lat: ', moments) assert moments['My'] < 0 # down assert abs(moments['Mx']) < 0.05 # not left or right assert moments['Mxx'] < moments['Myy'] # e1 < 0 assert abs(moments['Mxy']) < 0.1 # e2 ~= 0 # 9. HA > 0, Dec > lat Spot should be shifted down and left. e2 > 0. dcr = galsim.PhotonDCR(base_wavelength=base_wavelength, HA=2 * galsim.hours, latitude=lat, obj_coord=galsim.CelestialCoord( ra, lat + 20 * galsim.degrees)) surface_ops = [wave_sampler, dcr] star.drawImage(image=im, method='phot', rng=rng, surface_ops=surface_ops) moments = galsim.utilities.unweighted_moments(im, origin=im.true_center) print('9. HA > 0, Dec > lat: ', moments) assert moments['My'] < 0 # down assert moments['Mx'] < 0 # left assert moments['Mxy'] > 0 # e2 > 0
def drawNoise(noise): im = galsim.ImageD(10,10) im.addNoise(noise) return im.array.astype(np.float32).tolist()
# For information on where to download the .pkl file below, see the python script # `devel/external/hst/make_cosmos_cfimage.py` NOISEIMFILE = "acs_I_unrot_sci_20_noisearrays.pkl" # Input pickled list filename CFIMFILE_SUB = "acs_I_unrot_sci_20_cf_subtracted.fits" # Output image of correlation function (sub) CFIMFILE_UNS = "acs_I_unrot_sci_20_cf_unsubtracted.fits" # Output image of correlation function RSEED = 12334566 ud = galsim.UniformDeviate(RSEED) # Case 1: subtract_mean=True; Case 2: subtract_mean=False cn1 = galsim.getCOSMOSNoise(ud, CFIMFILE_SUB, dx_cosmos=1.) cn2 = galsim.getCOSMOSNoise(ud, CFIMFILE_UNS, dx_cosmos=1.) testim1 = galsim.ImageD(7, 7) testim2 = galsim.ImageD(7, 7) var1 = 0. var2 = 0. noisearrays = cPickle.load(open(NOISEIMFILE, 'rb')) for noisearray, i in zip(noisearrays, range(len(noisearrays))): noise1 = galsim.ImageViewD((noisearray.copy()).astype(np.float64), scale=1.) noise2 = galsim.ImageViewD((noisearray.copy()).astype(np.float64), scale=1.) cn1.applyWhiteningTo(noise1) cn2.applyWhiteningTo(noise2) var1 += noise1.array.var() var2 += noise2.array.var() cntest1 = galsim.CorrelatedNoise(ud, noise1) cntest2 = galsim.CorrelatedNoise(ud, noise2) cntest1.draw(testim1, dx=1., add_to_image=True)
def test_OpticalPSF_pupil_plane(): """Test the ability to generate a PSF using an image of the pupil plane. """ import time t1 = time.time() # Test case: lam/diam=0.12, obscuration=0.18, 4 struts of the default width and with rotation # from the vertical of -15 degrees. There are two versions of these tests at different # oversampling levels. # # To generate the pupil plane that was saved for this case, I did the following: # - Temporarily edited galsim/optics.py right after the call to generate_pupil_plane() in the # wavefront() method, adding the following lines: # tmp_im = utilities.roll2d(in_pupil, (in_pupil.shape[0] / 2, in_pupil.shape[1] / 2)) # tmp_im = galsim.Image(np.ascontiguousarray(tmp_im).astype(np.int32)) # tmp_im.write('tests/Optics_comparison_images/sample_pupil_rolled.fits') # - Executed the following command: # oversampling = 1.5 # pad_factor = 1.5 # galsim.OpticalPSF(0.12, obscuration=0.18, nstruts=4, strut_angle=-15.*galsim.degrees, # oversampling=oversampling, pad_factor=pad_factor) # - Then I made it write to # tests/Optics_comparison_images/sample_pupil_rolled_oversample.fits.gz, and reran the command # with oversampling = 4. and pad_factor = 4. # # First test: should get excellent agreement between that particular OpticalPSF with specified # options and one from loading the pupil plane image. Note that this won't work if you change # the optical PSF parameters, unless you also regenerate the test image. lam_over_diam = 0.12 obscuration = 0.18 nstruts = 4 strut_angle = -15. * galsim.degrees scale = 0.055 ref_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, nstruts=nstruts, oversampling=pp_oversampling, strut_angle=strut_angle, pad_factor=pp_pad_factor) im = galsim.fits.read(os.path.join(imgdir, pp_file)) test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, oversampling=pp_oversampling, pupil_plane_im=im, pad_factor=pp_pad_factor) im_ref_psf = ref_psf.drawImage(scale=scale) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) if pp_test_type == 'image': np.testing.assert_array_almost_equal( im_test_psf.array, im_ref_psf.array, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image for basic model after loading pupil plane." ) else: test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_ref_psf.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma, ref_moments.moments_sigma, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image for basic model after loading pupil plane." ) # It is supposed to be able to figure this out even if we *don't* tell it the pad factor. So # make sure that it still works even if we don't tell it that value. test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im, oversampling=pp_oversampling) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) if pp_test_type == 'image': np.testing.assert_array_almost_equal( im_test_psf.array, im_ref_psf.array, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image for basic model after loading pupil plane without " "specifying parameters.") else: test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_ref_psf.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma, ref_moments.moments_sigma, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image for basic model after loading pupil plane without " "specifying parameters.") # Next test (less trivial): Rotate the struts by +27 degrees, and check that agreement is # good. This is making sure that the linear interpolation that is done when rotating does not # result in significant loss of accuracy. rot_angle = 27. * galsim.degrees ref_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, nstruts=nstruts, strut_angle=strut_angle + rot_angle, oversampling=pp_oversampling, pad_factor=pp_pad_factor) test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im, pupil_angle=rot_angle, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_ref_psf = ref_psf.drawImage(scale=scale) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) # We are slightly less stringent here since it should not be exact. if pp_test_type == 'image': np.testing.assert_array_almost_equal( im_test_psf.array, im_ref_psf.array, decimal=pp_decimal - 1, err_msg= "Inconsistent OpticalPSF image for rotated model after loading pupil plane." ) else: test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_ref_psf.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma, ref_moments.moments_sigma, decimal=pp_decimal - 1, err_msg= "Inconsistent OpticalPSF image for rotated model after loading pupil plane." ) # Now include aberrations. Here we are testing the ability to figure out the pupil plane extent # and sampling appropriately. Those get fed into the routine for making the aberrations. defocus = -0.03 coma1 = 0.03 spher = -0.02 ref_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, nstruts=nstruts, strut_angle=strut_angle, defocus=defocus, coma1=coma1, spher=spher, oversampling=pp_oversampling, pad_factor=pp_pad_factor) test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im, defocus=defocus, coma1=coma1, spher=spher, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_ref_psf = ref_psf.drawImage(scale=scale) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) if pp_test_type == 'image': np.testing.assert_array_almost_equal( im_test_psf.array, im_ref_psf.array, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image for aberrated model after loading pupil plane." ) else: test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_ref_psf.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma, ref_moments.moments_sigma, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image for aberrated model after loading pupil plane." ) # Test for preservation of symmetries: the result should be the same if the pupil plane is # rotated by integer multiples of 2pi/(nstruts). ref_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, nstruts=nstruts, strut_angle=strut_angle, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_ref_psf = ref_psf.drawImage(scale=scale) for ind in range(1, nstruts): rot_angle = ind * 2. * np.pi / nstruts test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im, pupil_angle=rot_angle * galsim.radians, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) if pp_test_type == 'image': np.testing.assert_array_almost_equal( im_test_psf.array, im_ref_psf.array, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image after rotating pupil plane by invariant " "angle.") else: test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_test_psf.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma, ref_moments.moments_sigma, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image after rotating pupil plane by invariant " "angle.") # Test that if we rotate pupil plane with no aberrations, that's equivalent to rotating the PSF # itself. Use rotation angle of 90 degrees so numerical issues due to the interpolation should # be minimal. rot_angle = 90. * galsim.degrees psf_1 = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im, oversampling=pp_oversampling, pad_factor=pp_pad_factor) rot_psf_1 = psf_1.rotate(rot_angle) psf_2 = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im, pupil_angle=rot_angle, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_1 = psf_1.drawImage(scale=scale) im_2 = galsim.ImageD(im_1.array.shape[0], im_1.array.shape[1]) im_2 = psf_2.drawImage(image=im_2, scale=scale) if pp_test_type == 'image': np.testing.assert_array_almost_equal( im_1.array, im_2.array, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image after rotating pupil plane vs. rotating PSF." ) else: test_moments = im_1.FindAdaptiveMom() ref_moments = im_2.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma, ref_moments.moments_sigma, decimal=pp_decimal, err_msg= "Inconsistent OpticalPSF image after rotating pupil plane vs. rotating PSF." ) # Supply the pupil plane at higher resolution, and make sure that the routine figures out the # sampling and gets the right image scale etc. rescale_fac = 0.77 ref_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, nstruts=nstruts, strut_angle=strut_angle, oversampling=pp_oversampling, pad_factor=pp_pad_factor / rescale_fac) # Make higher resolution pupil plane image via interpolation im.scale = 1. # this doesn't matter, just put something so the next line works int_im = galsim.InterpolatedImage(galsim.Image(im, scale=im.scale, dtype=np.float32), calculate_maxk=False, calculate_stepk=False, x_interpolant='linear') new_im = int_im.drawImage(scale=rescale_fac * im.scale, method='no_pixel') test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=new_im, oversampling=pp_oversampling) im_ref_psf = ref_psf.drawImage(scale=scale) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_ref_psf.FindAdaptiveMom() if pp_test_type == 'image': np.testing.assert_almost_equal( test_moments.moments_sigma / ref_moments.moments_sigma - 1., 0, decimal=2, err_msg= "Inconsistent OpticalPSF image for basic model after loading high-res pupil plane." ) else: np.testing.assert_almost_equal( test_moments.moments_sigma / ref_moments.moments_sigma - 1., 0, decimal=1, err_msg= "Inconsistent OpticalPSF image for basic model after loading high-res pupil plane." ) # Now supply the pupil plane at the original resolution, but remove some of the padding. We # want it to properly recognize that it needs more padding, and include it. remove_pad = -23 sub_im = im[im.bounds.addBorder(remove_pad)] test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=sub_im, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_ref_psf.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma / ref_moments.moments_sigma - 1., 0, decimal=pp_decimal - 3, err_msg= "Inconsistent OpticalPSF image for basic model after loading less padded pupil plane." ) # Now supply the pupil plane at the original resolution, with extra padding. new_pad = 76 big_im = galsim.Image(im.bounds.addBorder(new_pad)) big_im[im.bounds] = im test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=big_im, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_test_psf = galsim.ImageD(im_ref_psf.array.shape[0], im_ref_psf.array.shape[1]) im_test_psf = test_psf.drawImage(image=im_test_psf, scale=scale) test_moments = im_test_psf.FindAdaptiveMom() ref_moments = im_ref_psf.FindAdaptiveMom() np.testing.assert_almost_equal( test_moments.moments_sigma, ref_moments.moments_sigma, decimal=pp_decimal - 2, err_msg="Inconsistent OpticalPSF image size for basic model " "after loading more padded pupil plane.") # Check for same answer if we use image, array, or filename for reading in array. test_psf = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_test_psf = test_psf.drawImage(scale=scale) test_psf_2 = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, pupil_plane_im=im.array, oversampling=pp_oversampling, pad_factor=pp_pad_factor) im_test_psf_2 = test_psf_2.drawImage(scale=scale) test_psf_3 = galsim.OpticalPSF(lam_over_diam, obscuration=obscuration, oversampling=pp_oversampling, pupil_plane_im=os.path.join( imgdir, pp_file), pad_factor=pp_pad_factor) im_test_psf_3 = test_psf_3.drawImage(scale=scale) np.testing.assert_almost_equal( im_test_psf.array, im_test_psf_2.array, decimal=pp_decimal, err_msg="Inconsistent OpticalPSF image from Image vs. array.") np.testing.assert_almost_equal( im_test_psf.array, im_test_psf_3.array, decimal=pp_decimal, err_msg="Inconsistent OpticalPSF image from Image vs. file read-in.") t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def do_shoot(prof, img, name): # For photon shooting, we calculate the number of photons to use based on the target # accuracy we are shooting for. (Pun intended.) # For each pixel, # uncertainty = sqrt(N_pix) * flux_photon = sqrt(N_tot * flux_pix / flux_tot) * flux_tot / N_tot # = sqrt(flux_pix) * sqrt(flux_tot) / sqrt(N_tot) # This is largest for the brightest pixel. So we use: # N = flux_max * flux_tot / photon_shoot_accuracy^2 photon_shoot_accuracy = 2.e-3 # The number of decimal places at which to test the photon shooting photon_decimal_test = 2 test_flux = 1.8 print('Start do_shoot') # Verify that shoot with rng=None runs prof.shoot(100, rng=None) # And also verify 0, 1, or 2 photons. prof.shoot(0) prof.shoot(1) prof.shoot(2) # Test photon shooting for a particular profile (given as prof). prof.drawImage(img) flux_max = img.array.max() print('prof.flux = ',prof.flux) print('flux_max = ',flux_max) flux_tot = img.array.sum(dtype=float) print('flux_tot = ',flux_tot) if flux_max > 1.: # Since the number of photons required for a given accuracy level (in terms of # number of decimal places), we rescale the comparison by the flux of the # brightest pixel. prof /= flux_max img /= flux_max # The formula for number of photons needed is: # nphot = flux_max * flux_tot / photon_shoot_accuracy**2 # But since we rescaled the image by 1/flux_max, it becomes nphot = flux_tot / flux_max / photon_shoot_accuracy**2 elif flux_max < 0.1: # If the max is very small, at least bring it up to 0.1, so we are testing something. scale = 0.1 / flux_max print('scale = ',scale) prof *= scale img *= scale nphot = flux_max * flux_tot * scale * scale / photon_shoot_accuracy**2 else: nphot = flux_max * flux_tot / photon_shoot_accuracy**2 print('prof.flux => ',prof.flux) print('img.sum => ',img.array.sum(dtype=float)) print('img.max => ',img.array.max()) print('nphot = ',nphot) img2 = img.copy() # Use a deterministic random number generator so we don't fail tests because of rare flukes # in the random numbers. rng = galsim.UniformDeviate(12345) prof.drawImage(img2, n_photons=nphot, poisson_flux=False, rng=rng, method='phot') print('img2.sum => ',img2.array.sum(dtype=float)) printval(img2,img) np.testing.assert_array_almost_equal( img2.array, img.array, photon_decimal_test, err_msg="Photon shooting for %s disagrees with expected result"%name) # Test normalization dx = img.scale # Test with a large image to make sure we capture enough of the flux # even for slow convergers like Airy (which needs a _very_ large image) or Sersic. print('stepk, maxk = ',prof.stepk,prof.maxk) if 'Airy' in name: img = galsim.ImageD(2048,2048, scale=dx) elif 'Sersic' in name or 'DeVauc' in name or 'Spergel' in name or 'VonKarman' in name: img = galsim.ImageD(512,512, scale=dx) else: img = galsim.ImageD(128,128, scale=dx) prof = prof.withFlux(test_flux) prof.drawImage(img) print('img.sum = ',img.array.sum(dtype=float),' cf. ',test_flux) np.testing.assert_almost_equal(img.array.sum(dtype=float), test_flux, 4, err_msg="Flux normalization for %s disagrees with expected result"%name) # max_sb is not always very accurate, but it should be an overestimate if wrong. assert img.array.max() <= prof.max_sb*dx**2 * 1.4, "max_sb for %s is too small."%name scale = test_flux / flux_tot # from above nphot *= scale * scale print('nphot -> ',nphot) if 'InterpolatedImage' in name or 'PhaseScreen' in name: nphot *= 10 print('nphot -> ',nphot) prof.drawImage(img, n_photons=nphot, poisson_flux=False, rng=rng, method='phot') print('img.sum = ',img.array.sum(dtype=float),' cf. ',test_flux) np.testing.assert_allclose( img.array.sum(dtype=float), test_flux, rtol=10**(-photon_decimal_test), err_msg="Photon shooting normalization for %s disagrees with expected result"%name) print('img.max = ',img.array.max(),' cf. ',prof.max_sb*dx**2) print('ratio = ',img.array.max() / (prof.max_sb*dx**2)) assert img.array.max() <= prof.max_sb*dx**2 * 1.4, \ "Photon shooting for %s produced too high max pixel."%name
def main(args): # Draw the original galaxies and measure their shapes rgc = galsim.RealGalaxyCatalog(catalog_filename, dir=catalog_dir) g1_list = [] g2_list = [] sigma_list = [] for i in range(args.first_index, args.first_index + args.nitems): test_image = galsim.ImageD(imsize, imsize) real_galaxy = galsim.RealGalaxy(rgc, index=i) real_galaxy.original_image.draw(test_image) shape = CatchAdaptiveMomErrors(test_image) if shape == -10: g1_list.append(-10) g2_list.append(-10) sigma_list.append(-10) else: g1_list.append(shape.observed_shape.g1) g2_list.append(shape.observed_shape.g2) sigma_list.append(shape.moments_sigma) g1_list = numpy.array(g1_list) g2_list = numpy.array(g2_list) # Define the config dictionaries we will use for all the following tests config_and_file_list = get_config(nitems=args.nitems, first_index=args.first_index, file_root=args.file_root) i = 1 # For printing status statements # Now, run through the various things we need to test in loops. for base_config, output_file in config_and_file_list: f = open(output_file, 'w') for padding in padding_list: # Amount of padding for interpolant in use_interpolants: # Possible interpolants print 'Angle test ', for angle in angle_list: # Possible rotation angles print i, i += 1 print_results(f, g1_list, g2_list, sigma_list, test_realgalaxy(base_config, angle=angle, x_interpolant=interpolant, padding=padding, seed=rseed + args.first_index), first_index=args.first_index) print_results(f, g1_list, g2_list, sigma_list, test_realgalaxy(base_config, angle=angle, k_interpolant=interpolant, padding=padding, seed=rseed + args.first_index), first_index=args.first_index) print '' print 'Shear/magnification test ', for ( g1, g2, mag ) in shear_and_magnification_list: # Shear and magnification print i, "(", g1, g2, ")", i += 1 print_results(f, g1_list, g2_list, sigma_list, test_realgalaxy(base_config, shear=(g1, g2), magnification=mag, x_interpolant=interpolant, padding=padding, seed=rseed + args.first_index), first_index=args.first_index) print_results(f, g1_list, g2_list, sigma_list, test_realgalaxy(base_config, shear=(g1, g2), magnification=mag, k_interpolant=interpolant, padding=padding, seed=rseed + args.first_index), first_index=args.first_index) print '' for shift in shift_list: print i, "(", shift, ")", i += 1 print_results(f, g1_list, g2_list, sigma_list, test_realgalaxy(base_config, shift=shift, x_interpolant=interpolant, padding=padding, seed=rseed + args.first_index), first_index=args.first_index) print_results(f, g1_list, g2_list, sigma_list, test_realgalaxy(base_config, shift=shift, k_interpolant=interpolant, padding=padding, seed=rseed + args.first_index), first_index=args.first_index) print '' f.close()
def test_operations_simple(): """Simple test of operations on InterpolatedImage: shear, magnification, rotation, shifting.""" import time t1 = time.time() # Make some nontrivial image that can be described in terms of sums and convolutions of # GSObjects. We want this to be somewhat hard to describe, but should be at least # critically-sampled, so put in an Airy PSF. gal_flux = 1000. pix_scale = 0.03 # arcsec bulge_frac = 0.3 bulge_hlr = 0.3 # arcsec bulge_e = 0.15 bulge_pos_angle = 30. * galsim.degrees disk_hlr = 0.6 # arcsec disk_e = 0.5 disk_pos_angle = 60. * galsim.degrees lam = 800 # nm NB: don't use lambda - that's a reserved word. tel_diam = 2.4 # meters lam_over_diam = lam * 1.e-9 / tel_diam # radians lam_over_diam *= 206265 # arcsec im_size = 512 bulge = galsim.Sersic(4, half_light_radius=bulge_hlr) bulge.applyShear(e=bulge_e, beta=bulge_pos_angle) disk = galsim.Exponential(half_light_radius=disk_hlr) disk.applyShear(e=disk_e, beta=disk_pos_angle) gal = bulge_frac * bulge + (1. - bulge_frac) * disk gal.setFlux(gal_flux) psf = galsim.Airy(lam_over_diam) pix = galsim.Pixel(pix_scale) obj = galsim.Convolve(gal, psf, pix) im = obj.draw(dx=pix_scale) # Turn it into an InterpolatedImage with default param settings int_im = galsim.InterpolatedImage(im) # Shear it, and compare with expectations from GSObjects directly test_g1 = -0.07 test_g2 = 0.1 test_decimal = 2 # in % difference, i.e. 2 means 1% agreement comp_region = 30 # compare the central region of this linear size test_int_im = int_im.createSheared(g1=test_g1, g2=test_g2) ref_obj = obj.createSheared(g1=test_g1, g2=test_g2) # make large images im = galsim.ImageD(im_size, im_size) ref_im = galsim.ImageD(im_size, im_size) test_int_im.draw(image=im, dx=pix_scale) ref_obj.draw(image=ref_im, dx=pix_scale) # define subregion for comparison new_bounds = galsim.BoundsI(1, comp_region, 1, comp_region) new_bounds.shift((im_size - comp_region) / 2, (im_size - comp_region) / 2) im_sub = im.subImage(new_bounds) ref_im_sub = ref_im.subImage(new_bounds) diff_im = im_sub - ref_im_sub rel = diff_im / im_sub zeros_arr = np.zeros((comp_region, comp_region)) # require relative difference to be smaller than some amount np.testing.assert_array_almost_equal( rel.array, zeros_arr, test_decimal, err_msg='Sheared InterpolatedImage disagrees with reference') # Magnify it, and compare with expectations from GSObjects directly test_mag = 1.08 test_decimal = 2 # in % difference, i.e. 2 means 1% agreement comp_region = 30 # compare the central region of this linear size test_int_im = int_im.createMagnified(test_mag) ref_obj = obj.createMagnified(test_mag) # make large images im = galsim.ImageD(im_size, im_size) ref_im = galsim.ImageD(im_size, im_size) test_int_im.draw(image=im, dx=pix_scale) ref_obj.draw(image=ref_im, dx=pix_scale) # define subregion for comparison new_bounds = galsim.BoundsI(1, comp_region, 1, comp_region) new_bounds.shift((im_size - comp_region) / 2, (im_size - comp_region) / 2) im_sub = im.subImage(new_bounds) ref_im_sub = ref_im.subImage(new_bounds) diff_im = im_sub - ref_im_sub rel = diff_im / im_sub zeros_arr = np.zeros((comp_region, comp_region)) # require relative difference to be smaller than some amount np.testing.assert_array_almost_equal( rel.array, zeros_arr, test_decimal, err_msg='Magnified InterpolatedImage disagrees with reference') # Lens it (shear and magnify), and compare with expectations from GSObjects directly test_g1 = -0.03 test_g2 = -0.04 test_mag = 0.74 test_decimal = 2 # in % difference, i.e. 2 means 1% agreement comp_region = 30 # compare the central region of this linear size test_int_im = int_im.createLensed(test_g1, test_g2, test_mag) ref_obj = obj.createLensed(test_g1, test_g2, test_mag) # make large images im = galsim.ImageD(im_size, im_size) ref_im = galsim.ImageD(im_size, im_size) test_int_im.draw(image=im, dx=pix_scale) ref_obj.draw(image=ref_im, dx=pix_scale) # define subregion for comparison new_bounds = galsim.BoundsI(1, comp_region, 1, comp_region) new_bounds.shift((im_size - comp_region) / 2, (im_size - comp_region) / 2) im_sub = im.subImage(new_bounds) ref_im_sub = ref_im.subImage(new_bounds) diff_im = im_sub - ref_im_sub rel = diff_im / im_sub zeros_arr = np.zeros((comp_region, comp_region)) # require relative difference to be smaller than some amount np.testing.assert_array_almost_equal( rel.array, zeros_arr, test_decimal, err_msg='Lensed InterpolatedImage disagrees with reference') # Rotate it, and compare with expectations from GSObjects directly test_rot_angle = 32. * galsim.degrees test_decimal = 2 # in % difference, i.e. 2 means 1% agreement comp_region = 30 # compare the central region of this linear size test_int_im = int_im.createRotated(test_rot_angle) ref_obj = obj.createRotated(test_rot_angle) # make large images im = galsim.ImageD(im_size, im_size) ref_im = galsim.ImageD(im_size, im_size) test_int_im.draw(image=im, dx=pix_scale) ref_obj.draw(image=ref_im, dx=pix_scale) # define subregion for comparison new_bounds = galsim.BoundsI(1, comp_region, 1, comp_region) new_bounds.shift((im_size - comp_region) / 2, (im_size - comp_region) / 2) im_sub = im.subImage(new_bounds) ref_im_sub = ref_im.subImage(new_bounds) diff_im = im_sub - ref_im_sub rel = diff_im / im_sub zeros_arr = np.zeros((comp_region, comp_region)) # require relative difference to be smaller than some amount np.testing.assert_array_almost_equal( rel.array, zeros_arr, test_decimal, err_msg='Rotated InterpolatedImage disagrees with reference') # Shift it, and compare with expectations from GSObjects directly x_shift = -0.31 y_shift = 0.87 test_decimal = 2 # in % difference, i.e. 2 means 1% agreement comp_region = 30 # compare the central region of this linear size test_int_im = int_im.createShifted(x_shift, y_shift) ref_obj = obj.createShifted(x_shift, y_shift) # make large images im = galsim.ImageD(im_size, im_size) ref_im = galsim.ImageD(im_size, im_size) test_int_im.draw(image=im, dx=pix_scale) ref_obj.draw(image=ref_im, dx=pix_scale) # define subregion for comparison new_bounds = galsim.BoundsI(1, comp_region, 1, comp_region) new_bounds.shift((im_size - comp_region) / 2, (im_size - comp_region) / 2) im_sub = im.subImage(new_bounds) ref_im_sub = ref_im.subImage(new_bounds) diff_im = im_sub - ref_im_sub rel = diff_im / im_sub zeros_arr = np.zeros((comp_region, comp_region)) # require relative difference to be smaller than some amount np.testing.assert_array_almost_equal( rel.array, zeros_arr, test_decimal, err_msg='Shifted InterpolatedImage disagrees with reference') t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
interpolants behave. A simple script used to quickly generate plots for the discussion of which interpolant should be used to describe correlation functions. See the discussion at https://github.com/GalSim-developers/GalSim/pull/452#discussion-diff-5701561 """ import numpy as np import matplotlib.pyplot as plt import galsim CFSIZE = 9 UPSAMPLING = 3 rng = galsim.BaseDeviate(752424) gd = galsim.GaussianNoise(rng) noise_image = galsim.ImageD(CFSIZE, CFSIZE) noise_image.addNoise(gd) cn = galsim.CorrelatedNoise(rng, noise_image, x_interpolant=galsim.Nearest(tol=1.e-4), dx=1.) test_image = galsim.ImageD(2 * UPSAMPLING * CFSIZE, 2 * UPSAMPLING * CFSIZE, scale=1. / float(UPSAMPLING)) cn.applyRotation(30. * galsim.degrees) cn.draw(test_image) plt.clf() plt.pcolor(test_image.array)
parent_path = argv[1] seed_step = 1 e1 = 0 e2 = 0.6 sersic_idx = 0.31 scale_radius = 0.3 gal_flux = 8000 noise_sig = 60 pixel_scale = 0.187 stamp_size = 48 psf = galsim.Moffat(beta=3.5, fwhm=0.7, flux=1.0, trunc=1.4).shear(e1=0.1, e2=0.) psf_img = galsim.ImageD(stamp_size, stamp_size) psf.drawImage(image=psf_img, scale=pixel_scale) psf_arr = numpy.float32(psf_img.array) hdu = fits.PrimaryHDU(psf_arr) psf_path = parent_path + '/psf.fits' hdu.writeto(psf_path, overwrite=True) gal = galsim.Sersic(scale_radius=scale_radius, n=sersic_idx, trunc=4.5 * scale_radius, flux=1.0) g1_input = [0, -0.04, 0, 0.04, -0.02, 0, 0.02, 0, 0.02] g2_input = [0, 0, 0.04, -0.04, 0, -0.02, 0, 0.02, -0.02] for shear_id in range(len(g1_input)):
hst_ncf = None bd = galsim.BaseDeviate(12345) # Seed is basically unimportant here for noiseim in noiseims: noiseim = noiseim.astype(np.float64) if hst_ncf is None: # Initialize the HST noise correlation function using the first image hst_ncf = galsim.CorrelatedNoise( bd, galsim.ImageViewD(noiseim), correct_periodicity=True, subtract_mean=SUBTRACT_MEAN) else: hst_ncf += galsim.CorrelatedNoise( bd, galsim.ImageViewD(noiseim), correct_periodicity=True, subtract_mean=SUBTRACT_MEAN) hst_ncf /= float(len(noiseims)) # Draw and plot an output image of the resulting correlation function cfimage = galsim.ImageD(NPIX, NPIX) hst_ncf.draw(cfimage, dx=1.) # Save this to the output filename specified in the script header cfimage.write(CFIMFILE) else: cfimage = galsim.fits.read(CFIMFILE) # Then make nice plots import matplotlib.pyplot as plt plt.clf() plt.pcolor(cfimage.array, vmin=0.) plt.axis((0, NPIX, 0, NPIX)) plt.colorbar() plt.set_cmap('hot') plt.title(r'COSMOS F814W-unrotated-sci noise correlation function') plt.savefig(CFPLOTFILE)
def test_crg_noise_draw_transform_commutativity(): """Test commutativity of ChromaticRealGalaxy correlated noise under operations of drawImage and applying transformations. """ LSST_i = galsim.Bandpass(os.path.join(bppath, "LSST_r.dat"), 'nm') f606w_cat = galsim.RealGalaxyCatalog('AEGIS_F606w_catalog.fits', dir=image_dir) f814w_cat = galsim.RealGalaxyCatalog('AEGIS_F814w_catalog.fits', dir=image_dir) psf = galsim.Gaussian(fwhm=0.6) crg = galsim.ChromaticRealGalaxy([f606w_cat, f814w_cat], id=14886, maxk=psf.maxk) factor = 1.5 g1 = g2 = 0.1 mu = 1.2 theta = 45 * galsim.degrees jac = [1.1, 0.1, -0.1, 1.2] orig = galsim.Convolve(crg, psf) orig.drawImage(LSST_i) draw_transform_img = galsim.ImageD(16, 16, scale=0.2) transform_draw_img = draw_transform_img.copy() multiplied = orig * factor multiplied.drawImage(LSST_i) # needed to populate noise property (orig.noise * factor**2).drawImage(image=draw_transform_img) multiplied.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) divided = orig / factor divided.drawImage(LSST_i) (orig.noise / factor**2).drawImage(image=draw_transform_img) divided.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) expanded = orig.expand(factor) expanded.drawImage(LSST_i) orig.noise.expand(factor).drawImage(image=draw_transform_img) expanded.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) dilated = orig.dilate(factor) dilated.drawImage(LSST_i) orig.noise.dilate(factor).drawImage(image=draw_transform_img) dilated.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) magnified = orig.magnify(mu) magnified.drawImage(LSST_i) orig.noise.magnify(mu).drawImage(image=draw_transform_img) magnified.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) lensed = orig.lens(g1, g2, mu) lensed.drawImage(LSST_i) orig.noise.lens(g1, g2, mu).drawImage(image=draw_transform_img) lensed.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) rotated = orig.rotate(theta) rotated.drawImage(LSST_i) orig.noise.rotate(theta).drawImage(image=draw_transform_img) rotated.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) sheared = orig.shear(g1=g1, g2=g2) sheared.drawImage(LSST_i) orig.noise.shear(g1=g1, g2=g2).drawImage(image=draw_transform_img) sheared.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array) transformed = orig.transform(*jac) transformed.drawImage(LSST_i) orig.noise.transform(*jac).drawImage(image=draw_transform_img) transformed.noise.drawImage(image=transform_draw_img) np.testing.assert_array_almost_equal(draw_transform_img.array, transform_draw_img.array)
def test_real_galaxy_ideal(): """Test accuracy of various calculations with fake Gaussian RealGalaxy vs. ideal expectations""" ind_fake = 1 # index of mock galaxy (Gaussian) in catalog fake_gal_fwhm = 0.7 # arcsec fake_gal_shear1 = 0.29 # shear representing intrinsic shape component 1 fake_gal_shear2 = -0.21 # shear representing intrinsic shape component 2 # note non-round, to detect possible issues with x<->y or others that might not show up using # circular galaxy fake_gal_flux = 1000.0 fake_gal_orig_PSF_fwhm = 0.1 # arcsec fake_gal_orig_PSF_shear1 = 0.0 fake_gal_orig_PSF_shear2 = -0.07 # read in faked Gaussian RealGalaxy from file rgc = galsim.RealGalaxyCatalog(catalog_file, dir=image_dir) assert len(rgc) == rgc.getNObjects() == rgc.nobjects == len(rgc.cat) rg = galsim.RealGalaxy(rgc, index=ind_fake) # as a side note, make sure it behaves okay given a legit RNG and a bad RNG # or when trying to specify the galaxy too many ways rg_1 = galsim.RealGalaxy(rgc, index=ind_fake, rng=galsim.BaseDeviate(1234)) rg_2 = galsim.RealGalaxy(rgc, random=True) assert_raises(TypeError, galsim.RealGalaxy, rgc, index=ind_fake, rng='foo') assert_raises(TypeError, galsim.RealGalaxy, rgc) assert_raises(TypeError, galsim.RealGalaxy, rgc, index=ind_fake, flux=12, flux_rescale=2) assert_raises(ValueError, galsim.RealGalaxy, rgc, index=ind_fake, id=0) assert_raises(ValueError, galsim.RealGalaxy, rgc, index=ind_fake, random=True) assert_raises(ValueError, galsim.RealGalaxy, rgc, id=0, random=True) # Different RNGs give different random galaxies. rg_3 = galsim.RealGalaxy(rgc, random=True, rng=galsim.BaseDeviate(12345)) rg_4 = galsim.RealGalaxy(rgc, random=True, rng=galsim.BaseDeviate(67890)) assert rg_3.index != rg_4.index, 'Different seeds did not give different random objects!' gsp = galsim.GSParams(xvalue_accuracy=1.e-8, kvalue_accuracy=1.e-8) rg_5 = galsim.RealGalaxy(rgc, random=True, rng=galsim.BaseDeviate(67890), gsparams=gsp) assert rg_5 != rg_4 assert rg_5 == rg_4.withGSParams(gsp) assert rg_5 == rg_4.withGSParams(xvalue_accuracy=1.e-8, kvalue_accuracy=1.e-8) check_basic(rg, "RealGalaxy", approx_maxsb=True) check_basic(rg_1, "RealGalaxy", approx_maxsb=True) check_basic(rg_2, "RealGalaxy", approx_maxsb=True) do_pickle( rgc, lambda x: [ x.getGalImage(ind_fake), x.getPSFImage(ind_fake), x.getNoiseProperties(ind_fake) ]) do_pickle( rgc, lambda x: drawNoise(x.getNoise(ind_fake, rng=galsim.BaseDeviate(123)))) do_pickle(rgc) do_pickle( rg, lambda x: [ x.gal_image, x.psf_image, repr(x.noise), x.original_psf.flux, x.original_gal.flux, x.flux ]) do_pickle(rg, lambda x: x.drawImage(nx=20, ny=20, scale=0.7)) do_pickle(rg_1, lambda x: x.drawImage(nx=20, ny=20, scale=0.7)) do_pickle(rg) do_pickle(rg_1) ## for the generation of the ideal right answer, we need to add the intrinsic shape of the ## galaxy and the lensing shear using the rule for addition of distortions which is ugly, but oh ## well: targ_pixel_scale = [0.18, 0.25] # arcsec targ_PSF_fwhm = [0.7, 1.0] # arcsec targ_PSF_shear1 = [-0.03, 0.0] targ_PSF_shear2 = [0.05, -0.08] targ_applied_shear1 = 0.06 targ_applied_shear2 = -0.04 fwhm_to_sigma = 1.0 / (2.0 * np.sqrt(2.0 * np.log(2.0))) (d1, d2) = galsim.utilities.g1g2_to_e1e2(fake_gal_shear1, fake_gal_shear2) (d1app, d2app) = galsim.utilities.g1g2_to_e1e2(targ_applied_shear1, targ_applied_shear2) denom = 1.0 + d1 * d1app + d2 * d2app dapp_sq = d1app**2 + d2app**2 d1tot = (d1 + d1app + d2app / dapp_sq * (1.0 - np.sqrt(1.0 - dapp_sq)) * (d2 * d1app - d1 * d2app)) / denom d2tot = (d2 + d2app + d1app / dapp_sq * (1.0 - np.sqrt(1.0 - dapp_sq)) * (d1 * d2app - d2 * d1app)) / denom # convolve with a range of Gaussians, with and without shear (note, for this test all the # original and target ePSFs are Gaussian - there's no separate pixel response so that everything # can be calculated analytically) for tps in targ_pixel_scale: for tpf in targ_PSF_fwhm: for tps1 in targ_PSF_shear1: for tps2 in targ_PSF_shear2: print('tps,tpf,tps1,tps2 = ', tps, tpf, tps1, tps2) # make target PSF targ_PSF = galsim.Gaussian(fwhm=tpf).shear(g1=tps1, g2=tps2) # simulate image tmp_gal = rg.withFlux(fake_gal_flux).shear( g1=targ_applied_shear1, g2=targ_applied_shear2) final_tmp_gal = galsim.Convolve(targ_PSF, tmp_gal) sim_image = final_tmp_gal.drawImage(scale=tps, method='no_pixel') # galaxy sigma, in units of pixels on the final image sigma_ideal = (fake_gal_fwhm / tps) * fwhm_to_sigma # compute analytically the expected galaxy moments: mxx_gal, myy_gal, mxy_gal = ellip_to_moments( d1tot, d2tot, sigma_ideal) # compute analytically the expected PSF moments: targ_PSF_e1, targ_PSF_e2 = galsim.utilities.g1g2_to_e1e2( tps1, tps2) targ_PSF_sigma = (tpf / tps) * fwhm_to_sigma mxx_PSF, myy_PSF, mxy_PSF = ellip_to_moments( targ_PSF_e1, targ_PSF_e2, targ_PSF_sigma) # get expected e1, e2, sigma for the PSF-convolved image tot_e1, tot_e2, tot_sigma = moments_to_ellip( mxx_gal + mxx_PSF, myy_gal + myy_PSF, mxy_gal + mxy_PSF) # compare with images that are expected expected_gaussian = galsim.Gaussian(flux=fake_gal_flux, sigma=tps * tot_sigma) expected_gaussian = expected_gaussian.shear(e1=tot_e1, e2=tot_e2) expected_image = galsim.ImageD(sim_image.array.shape[0], sim_image.array.shape[1]) expected_gaussian.drawImage(expected_image, scale=tps, method='no_pixel') printval(expected_image, sim_image) np.testing.assert_array_almost_equal( sim_image.array, expected_image.array, decimal=3, err_msg= "Error in comparison of ideal Gaussian RealGalaxy calculations" )
def test_knots_defaults(): """ Create a random walk galaxy and test that the getters work for default inputs """ # try constructing with mostly defaults npoints = 100 hlr = 8.0 rng = galsim.BaseDeviate(1234) rw = galsim.RandomKnots(npoints, half_light_radius=hlr, rng=rng) assert rw.npoints == npoints, "expected npoints==%d, got %d" % (npoints, rw.npoints) assert rw.input_half_light_radius==hlr,\ "expected hlr==%g, got %g" % (hlr, rw.input_half_light_radius) nobj = len(rw.points) assert nobj == npoints, "expected %d objects, got %d" % (npoints, nobj) pts = rw.points assert pts.shape == ( npoints, 2), "expected (%d,2) shape for points, got %s" % (npoints, pts.shape) np.testing.assert_almost_equal(rw.centroid.x, np.mean(pts[:, 0])) np.testing.assert_almost_equal(rw.centroid.y, np.mean(pts[:, 1])) gsp = galsim.GSParams(xvalue_accuracy=1.e-8, kvalue_accuracy=1.e-8) rng2 = galsim.BaseDeviate(1234) rw2 = galsim.RandomKnots(npoints, half_light_radius=hlr, rng=rng2, gsparams=gsp) assert rw2 != rw assert rw2 == rw.withGSParams(gsp) # Check that they produce identical images. psf = galsim.Gaussian(sigma=0.8) conv1 = galsim.Convolve(rw.withGSParams(gsp), psf) conv2 = galsim.Convolve(rw2, psf) im1 = conv1.drawImage() im2 = conv2.drawImage() assert im1 == im2 # Check that image is not sensitive to use of rng by other objects. rng3 = galsim.BaseDeviate(1234) rw3 = galsim.RandomKnots(npoints, half_light_radius=hlr, rng=rng3) rng3.discard(523) conv1 = galsim.Convolve(rw, psf) conv3 = galsim.Convolve(rw3, psf) im1 = conv1.drawImage() im3 = conv2.drawImage() assert im1 == im3 # Run some basic tests of correctness check_basic(conv1, "RandomKnots") im = galsim.ImageD(64, 64, scale=0.5) do_shoot(conv1, im, "RandomKnots") do_kvalue(conv1, im, "RandomKnots") do_pickle(rw) do_pickle(conv1) do_pickle(conv1, lambda x: x.drawImage(scale=1)) # Check negative flux rw3 = rw.withFlux(-2.3) assert rw3 == galsim.RandomKnots(npoints, half_light_radius=hlr, rng=galsim.BaseDeviate(1234), flux=-2.3) conv = galsim.Convolve(rw3, psf) check_basic(conv, "RandomKnots with negative flux")
def get_mbobs(self, return_truth_cat=False): """Make a simulated MultiBandObsList for metadetect. Parameters ---------- return_truth_cat : bool If True, return the truth catalog. Returns ------- mbobs : MultiBandObsList """ all_band_obj, positions, z_population = self._get_band_objects() truth_cat = np.zeros(len(positions), dtype=[('x', 'f8'), ('y', 'f8'), ('z_population', 'f8')]) truth_cat['z_population'] = z_population _, _, _, _, method = self._render_psf_image(x=self.im_cen, y=self.im_cen) mbobs = ngmix.MultiBandObsList() for band in range(self.n_bands): im = galsim.ImageD(nrow=self.dim, ncol=self.dim, xmin=0, ymin=0) band_objects = [o[band] for o in all_band_obj] for obj_ind, (obj, pos) in enumerate(zip(band_objects, positions)): truth_cat['x'][obj_ind] = pos.x truth_cat['y'][obj_ind] = pos.y # draw with setup_only to get the image size _im = obj.drawImage(wcs=self.wcs, method=method, setup_only=True).array assert _im.shape[0] == _im.shape[1] # now get location of the stamp x_ll = int(pos.x - (_im.shape[1] - 1) / 2) y_ll = int(pos.y - (_im.shape[0] - 1) / 2) # get the offset of the center dx = pos.x - (x_ll + (_im.shape[1] - 1) / 2) dy = pos.y - (y_ll + (_im.shape[0] - 1) / 2) dx *= self.scale dy *= self.scale # draw and set the proper origin stamp = obj.shift(dx=dx, dy=dy).drawImage(nx=_im.shape[1], ny=_im.shape[0], wcs=self.wcs, method=method) stamp.setOrigin(x_ll, y_ll) # intersect and add to total image overlap = stamp.bounds & im.bounds im[overlap] += stamp[overlap] im = im.array.copy() im += self.noise_rng.normal(scale=self.noise[band], size=im.shape) wt = im * 0 + 1.0 / self.noise[band]**2 bmask = np.zeros(im.shape, dtype='i4') noise = self.noise_rng.normal(size=im.shape) / np.sqrt(wt) if self.mask_and_interp: im, noise, bmask = self._mask_and_interp(im, noise) galsim_jac = self._get_local_jacobian(x=self.im_cen, y=self.im_cen) psf_obs = self.get_psf_obs(x=self.im_cen, y=self.im_cen, band=band) if self.homogenize_psf: im, noise, psf_img = self._homogenize_psf(im, noise, band) psf_obs.set_image(psf_img) jac = ngmix.jacobian.Jacobian(row=self.im_cen, col=self.im_cen, wcs=galsim_jac) obs = ngmix.Observation(im, weight=wt, bmask=bmask, ormask=bmask.copy(), jacobian=jac, psf=psf_obs, noise=noise) obslist = ngmix.ObsList() obslist.append(obs) mbobs.append(obslist) if return_truth_cat: return mbobs, truth_cat else: return mbobs
-0.02, -0.31, )) * np.pi / 2. # First make an image that we'll use for interpolation: g1 = galsim.Gaussian(sigma=3.1, flux=2.4) g1.applyShear(g1=0.2, g2=0.1) g2 = galsim.Gaussian(sigma=1.9, flux=3.1) g2.applyShear(g1=-0.4, g2=0.3) g2.applyShift(-0.3, 0.5) g3 = galsim.Gaussian(sigma=4.1, flux=1.6) g3.applyShear(g1=0.1, g2=-0.1) g3.applyShift(0.7, -0.2) final = g1 + g2 + g3 ref_image = galsim.ImageD(128, 128) dx = 0.4 # The reference image was drawn with the old convention, which is now use_true_center=False final.draw(image=ref_image, dx=dx, normalization='sb', use_true_center=False) def test_sbinterpolatedimage(): """Test that we can make SBInterpolatedImages from Images of various types, and convert back. """ import time t1 = time.time() # for each type, try to make an SBInterpolatedImage, and check that when we draw an image from # that SBInterpolatedImage that it is the same as the original lan3 = galsim.Lanczos(3, True, 1.E-4) lan3_2d = galsim.InterpolantXY(lan3)
import matplotlib.pyplot as plt import galsim IMSIZE = 40 # First make a noise field with an even number of elements enoise = galsim.ImageViewD(np.random.randn(IMSIZE, IMSIZE)) encf = galsim.correlatednoise.CorrFunc(enoise) print encf.SBProfile.xValue(galsim.PositionD(0, 0)) # Then make a noise field with an odd number of elements onoise = galsim.ImageViewD(np.random.randn(IMSIZE + 1, IMSIZE + 1)) oncf = galsim.correlatednoise.CorrFunc(onoise) print oncf.SBProfile.xValue(galsim.PositionD(0, 0)) testim = galsim.ImageD(10, 10) cv = encf.SBProfile.getCovarianceMatrix(testim.view(), dx=1.) #plt.pcolor(cv.array); plt.colorbar() # Construct an image with noise correlated in the y direction plt.figure() ynoise = galsim.ImageViewD(enoise.array[:, :] + np.roll(enoise.array, 1, axis=0)) plt.pcolor(ynoise.array) plt.colorbar() plt.title('Noise correlated in y direction') plt.savefig('ynoise.png') yncf = galsim.correlatednoise.CorrFunc(ynoise) yim = galsim.ImageD(IMSIZE, IMSIZE) yncf.draw(yim, dx=1.)
def test_realspace_conv(): """Test that real-space convolution of an InterpolatedImage matches the FFT result """ import time t1 = time.time() # Note: It is not usually a good idea to use real-space convolution with an InterpolatedImage. # It will almost always be much slower than the FFT convolution. So it's probably only # a good idea if the image is very small and/or you absolutely need to avoid the ringing # that can show up in FFT convolutions. # That said, we still need to make sure the code is correct. Especially since it # didn't used to be, as reported in issue #432. So, here goes. # set up image scale and size raw_scale = 0.23 raw_size = 15 # We draw onto a smaller image so the unit test doesn't take forever! target_scale = 0.7 target_size = 3 gal = galsim.Exponential(flux=1.7, half_light_radius=1.2) gal_im = gal.draw(dx=raw_scale, image=galsim.ImageD(raw_size, raw_size)) psf1 = galsim.Gaussian(flux=1, half_light_radius=0.77) psf_im = psf1.draw(dx=raw_scale, image=galsim.ImageD(raw_size, raw_size)) #for interp in ['nearest', 'linear', 'cubic', 'quintic', 'lanczos3', 'lanczos5', 'lanczos7']: for interp in ['linear', 'cubic', 'quintic']: # Note 1: The Lanczos interpolants pass these tests just fine. They just take a long # time to run, even with the small images we are working with. So skip them for regular # unit testing. Developers working on this should re-enable those while testing. # Note 2: I couldn't get 'nearest' to pass the tests. Specifically the im3 == im4 test. # I don't know whether there is a bug in the Nearest class functions (seems unlikely since # they are so simple) or in the real-space convolver or if the nature of the Nearest # interpolation (with its very large extent in k-space and hard edges in real space) is # such that we don't actually expect the test to pass. Anyway, it also takes a very long # time to run (before failing), so it's probably not a good idea to use it for # real-space convolution anyway. print 'interp = ', interp gal = galsim.InterpolatedImage(gal_im, x_interpolant=interp) # First convolve with a Gaussian: psf = psf1 c1 = galsim.Convolve([gal, psf], real_space=True) c2 = galsim.Convolve([gal, psf], real_space=False) im1 = c1.draw(dx=target_scale, image=galsim.ImageD(target_size, target_size)) print 'im1 = ', im1.array[:, :] im2 = c2.draw(dx=target_scale, image=galsim.ImageD(target_size, target_size)) print 'im2 = ', im2.array[:, :] np.testing.assert_array_almost_equal(im1.array, im2.array, 5) print 'im1 == im2' # Now make the psf also an InterpolatedImage: psf = galsim.InterpolatedImage(psf_im, x_interpolant=interp, flux=1) c3 = galsim.Convolve([gal, psf], real_space=True) c4 = galsim.Convolve([gal, psf], real_space=False) im3 = c3.draw(dx=target_scale, image=galsim.ImageD(target_size, target_size)) print 'im3 = ', im3.array[:, :] im4 = c4.draw(dx=target_scale, image=galsim.ImageD(target_size, target_size), wmult=5) print 'im4 = ', im4.array[:, :] np.testing.assert_array_almost_equal(im1.array, im3.array, 2) # Note: only 2 d.p. since the interpolated image version of the psf is really a different # profile from the original. Especially for the lower order interpolants. So we don't # expect these images to be equal to many decimal places. print 'im1 == im3' np.testing.assert_array_almost_equal(im3.array, im4.array, 5) print 'im3 == im4' t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_OpticalPSF_aberrations_struts(): """Test the generation of optical aberrations and struts against a known result. """ import time t1 = time.time() lod = 0.04 obscuration = 0.3 imsize = 128 # Size of saved images as generated by generate_optics_comparison_images.py myImg = galsim.ImageD(imsize, imsize) # We don't bother running all of these for the regular unit tests, since it adds # ~10s to the test run time on a fast-ish laptop. So only run these when individually # running python test_optics.py. # NB: The test images were made with oversampling=1, so use that for these tests. if __name__ == "__main__": # test defocus savedImg = galsim.fits.read(os.path.join(imgdir, "optics_defocus.fits")) optics = galsim.OpticalPSF(lod, defocus=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg= "Optical aberration (defocus) disagrees with expected result") # test astig1 savedImg = galsim.fits.read(os.path.join(imgdir, "optics_astig1.fits")) optics = galsim.OpticalPSF(lod, defocus=.5, astig1=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg="Optical aberration (astig1) disagrees with expected result" ) # test astig2 savedImg = galsim.fits.read(os.path.join(imgdir, "optics_astig2.fits")) optics = galsim.OpticalPSF(lod, defocus=.5, astig2=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg="Optical aberration (astig2) disagrees with expected result" ) # test coma1 savedImg = galsim.fits.read(os.path.join(imgdir, "optics_coma1.fits")) optics = galsim.OpticalPSF(lod, coma1=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg="Optical aberration (coma1) disagrees with expected result" ) # test coma2 savedImg = galsim.fits.read(os.path.join(imgdir, "optics_coma2.fits")) optics = galsim.OpticalPSF(lod, coma2=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg="Optical aberration (coma2) disagrees with expected result" ) # test trefoil1 savedImg = galsim.fits.read( os.path.join(imgdir, "optics_trefoil1.fits")) optics = galsim.OpticalPSF(lod, trefoil1=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg= "Optical aberration (trefoil1) disagrees with expected result") # test trefoil2 savedImg = galsim.fits.read( os.path.join(imgdir, "optics_trefoil2.fits")) optics = galsim.OpticalPSF(lod, trefoil2=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg= "Optical aberration (trefoil2) disagrees with expected result") # test spherical savedImg = galsim.fits.read(os.path.join(imgdir, "optics_spher.fits")) optics = galsim.OpticalPSF(lod, spher=.5, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg="Optical aberration (spher) disagrees with expected result" ) # test all aberrations savedImg = galsim.fits.read(os.path.join(imgdir, "optics_all.fits")) optics = galsim.OpticalPSF(lod, defocus=.5, astig1=0.5, astig2=0.3, coma1=0.4, coma2=-0.3, trefoil1=-0.2, trefoil2=0.1, spher=-0.8, obscuration=obscuration, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg= "Optical aberration (all aberrations) disagrees with expected result") # test struts savedImg = galsim.fits.read(os.path.join(imgdir, "optics_struts.fits")) optics = galsim.OpticalPSF(lod, obscuration=obscuration, nstruts=5, strut_thick=0.04, strut_angle=8. * galsim.degrees, astig2=0.04, coma1=-0.07, defocus=0.09, oversampling=1) try: np.testing.assert_raises(TypeError, galsim.OpticalPSF, lod, nstruts=5, strut_thick=0.01, strut_angle=8.) # wrong units except ImportError: print 'The assert_raises tests require nose' # Make sure it doesn't have some weird error if strut_angle=0 (should be the easiest case, but # check anyway...) optics_2 = galsim.OpticalPSF(lod, obscuration=obscuration, nstruts=5, strut_thick=0.04, strut_angle=0. * galsim.degrees, astig2=0.04, coma1=-0.07, defocus=0.09, oversampling=1) myImg = optics.draw(myImg, scale=0.2 * lod, use_true_center=True) np.testing.assert_array_almost_equal( myImg.array, savedImg.array, 6, err_msg="Optical PSF (with struts) disagrees with expected result") # make sure it doesn't completely explode when asked to return a PSF with non-circular pupil and # non-zero obscuration optics = galsim.OpticalPSF(lod, obscuration=obscuration, nstruts=5, strut_thick=0.04, strut_angle=8. * galsim.degrees, astig2=0.04, coma1=-0.07, defocus=0.09, oversampling=1, circular_pupil=False) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)