def test_SED_div(): """Check that SEDs divide like I think they should... """ a0 = galsim.SED(galsim.LookupTable([1,2,3,4,5], [1.1,2.2,3.3,4.4,5.5]), wave_type='nm', flux_type='fphotons') for z in [0, 0.2, 0.4]: a = a0.atRedshift(z) # SED divided by function b = lambda w: w**2 c = a/b x = 3.0 np.testing.assert_almost_equal(c(x), a(x)/b(x), 10, err_msg="Found wrong value in SED.__div__") # SED divided by scalar d = a/4.2 np.testing.assert_almost_equal(d(x), a(x)/4.2, 10, err_msg="Found wrong value in SED.__div__") do_pickle(d) # assignment division d /= 2 np.testing.assert_almost_equal(d(x), a(x)/4.2/2, 10, err_msg="Found wrong value in SED.__div__") do_pickle(d) # SED divided by dimensionless SED e = galsim.SED('wave', 'nm', '1') d /= e np.testing.assert_almost_equal(d(x), a(x)/4.2/2/e(x), 10, err_msg="Found wrong value in SED.__div__")
def test_stepk_maxk(): """Test options to specify (or not) stepk and maxk. """ aper = galsim.Aperture(diam=1.0) rng = galsim.BaseDeviate(123456) # Test frozen AtmosphericScreen first atm = galsim.Atmosphere(screen_size=30.0, altitude=10.0, speed=0.1, alpha=1.0, rng=rng) psf = galsim.PhaseScreenPSF(atm, 500.0, aper=aper, scale_unit=galsim.arcsec) stepk = psf.stepK() maxk = psf.maxK() psf2 = galsim.PhaseScreenPSF(atm, 500.0, aper=aper, scale_unit=galsim.arcsec, _force_stepk=stepk/1.5, _force_maxk=maxk*2.0) np.testing.assert_almost_equal( psf2.stepK(), stepk/1.5, decimal=7, err_msg="PhaseScreenPSF did not adopt forced value for stepK") np.testing.assert_almost_equal( psf2.maxK(), maxk*2.0, decimal=7, err_msg="PhaseScreenPSF did not adopt forced value for maxK") do_pickle(psf) do_pickle(psf2) # Try out non-geometric-shooting psf3 = atm.makePSF(lam=500.0, aper=aper, geometric_shooting=False) img = galsim.Image(32, 32, scale=0.2) do_shoot(psf3, img, "PhaseScreenPSF") # Also make sure a few other methods at least run psf3.centroid() psf3.maxSB()
def test_aperture(): """Test various ways to construct Apertures.""" # Simple tests for constructing and pickling Apertures. aper1 = galsim.Aperture(diam=1.0) im = galsim.fits.read(os.path.join(imgdir, pp_file)) aper2 = galsim.Aperture(diam=1.0, pupil_plane_im=im) do_pickle(aper1) do_pickle(aper2) # Automatically created Aperture should match one created via OpticalScreen aper1 = galsim.Aperture(diam=1.0) aper2 = galsim.Aperture(diam=1.0, lam=500, screen_list=[galsim.OpticalScreen(diam=1.0)]) err_str = ("Aperture created implicitly using Airy does not match Aperture created using " "OpticalScreen.") assert aper1 == aper2, err_str
def test_SED_basic(): """Basic tests of SED functionality """ c = constants.c.to('nm / s').value # speed of light h = constants.h.to('erg s').value # Planck's constant nm_w = np.arange(10, 1002, 10) A_w = np.arange(100, 10002, 100) try: # Eval-str must return a Real np.testing.assert_raises(ValueError, galsim.SED, spec="'eggs'", wave_type='A', flux_type='flambda') except ImportError: print('The assert_raises tests require nose') # All of these should be equivalent. Flat spectrum with F_lambda = 200 erg/nm s_list = [ galsim.SED(spec=lambda x: 200., flux_type='flambda', wave_type='nm'), galsim.SED(spec='200', flux_type='flambda', wave_type='nanometers'), galsim.SED('200', wave_type='nanometers', flux_type='flambda'), galsim.SED('200', 'nm', 'flambda'), galsim.SED('np.sqrt(4.e4)', 'nm', 'flambda'), galsim.SED('numpy.sqrt(4.e4)', 'nm', 'flambda'), galsim.SED('math.sqrt(4.e4)', 'nm', 'flambda'), # 200 erg/nm / 10 A/nm = 20 erg/A galsim.SED(spec='20', flux_type='flambda', wave_type='Angstroms'), # 200 erg/nm / (hc/w erg/photon) = 200 w/hc photons/nm galsim.SED(spec='200 * wave / %r' % (h * c), wave_type='NANOmeters', flux_type='fphotons'), # 200 erg/nm / (hc/w erg/photon) / 10 A/nm = 20 (w in A)/hc photons/A galsim.SED(spec='20 * (wave/10) / %r' % (h * c), flux_type='fphotons', wave_type='Ang'), # 200 erg/nm / (c/w^2 Hz/nm) = 200 w^2/c erg/Hz galsim.SED(spec='200 * wave**2 / %r' % c, flux_type='fnu', wave_type='nm'), galsim.SED(spec='200 * (wave/10)**2 / %r' % c, flux_type='fnu', wave_type='A'), galsim.SED(galsim.LookupTable([1, 1e3], [200, 200], interpolant='linear'), wave_type='nanometers', flux_type='flambda'), galsim.SED(galsim.LookupTable([1, 1e4], [20, 20], interpolant='linear'), wave_type='ang', flux_type='flambda'), galsim.SED(galsim.LookupTable([1, 1e3], [200 / (h * c), 2e5 / (h * c)], interpolant='linear'), flux_type='fphotons', wave_type='nm'), galsim.SED(galsim.LookupTable([1, 1e4], [2 / (h * c), 2e4 / (h * c)], interpolant='linear'), flux_type='fphotons', wave_type='A'), galsim.SED(galsim.LookupTable([1, 1e3], [200 / c, 2e8 / c], interpolant='linear', x_log=True, f_log=True), flux_type='fnu', wave_type='nanometers'), galsim.SED(galsim.LookupTable([1, 1e4], [2 / c, 2e8 / c], interpolant='linear', x_log=True, f_log=True), flux_type='fnu', wave_type='A'), galsim.SED(galsim.LookupTable(nm_w, 200. * np.ones(100)), wave_type='nanometers', flux_type='flambda'), galsim.SED(galsim.LookupTable(A_w, 20. * np.ones(100)), flux_type='flambda', wave_type='A'), galsim.SED(galsim.LookupTable(nm_w, 200. * nm_w / (h * c)), flux_type='fphotons', wave_type='nm'), galsim.SED(galsim.LookupTable(A_w, 2. * A_w / (h * c)), flux_type='fphotons', wave_type='A'), galsim.SED(galsim.LookupTable(nm_w, 200. * nm_w**2 / c), flux_type='fnu', wave_type='nanometers'), galsim.SED(galsim.LookupTable(A_w, 2. * A_w**2 / c), flux_type='fnu', wave_type='A'), galsim.SED(galsim.LookupTable( [1, 100 - 1.e-10, 100, 1000, 1000 + 1.e-10, 2000], [0., 0., 200., 200., 0., 0.], interpolant='linear'), wave_type='nm', flux_type='flambda') ] s_list += [ s_list[9].thin(), s_list[10].thin(), s_list[11].thin(), s_list[12].thin(), s_list[13].thin(), s_list[14].thin(), s_list[15].thin(), s_list[15].thin(preserve_range=True), s_list[18].thin(), s_list[18].thin(preserve_range=True), s_list[21].thin(), s_list[21].thin(preserve_range=True), galsim.SED('1000', 'nm', 'flambda', redshift=4), galsim.SED('1000', 'nm', 'flambda').atRedshift(4.0), ] for k, s in enumerate(s_list): print(k, ' s = ', s) np.testing.assert_almost_equal(s(400) * h * c / 400, 200, decimal=10) np.testing.assert_almost_equal(s(900) * h * c / 900, 200, decimal=10) waves = np.arange(700, 800, 10) np.testing.assert_array_almost_equal(s(waves) * h * c / waves, 200, decimal=10) if k < len(s_list) - 2: np.testing.assert_equal(s.redshift, 0.) else: np.testing.assert_almost_equal(s.redshift, 4.) # Only the first one is not picklable if k > 0: do_pickle(s, lambda x: (x(470), x(490), x(910))) do_pickle(s)
def test_SED_mul(): """Check that SEDs multiply like I think they should... """ sed0 = galsim.SED(galsim.LookupTable([1, 2, 3, 4, 5], [1.1, 2.2, 3.3, 4.4, 5.5]), wave_type='nm', flux_type='fphotons') sed1 = galsim.SED(lambda nu: nu**2, wave_type=units.Hz, flux_type='fnu', fast=False) sed2 = galsim.SED(17.0, wave_type='ang', flux_type='1') for sed, z in zip([sed0, sed1, sed2], [0, 0.2, 0.4]): a = sed.atRedshift(z) # SED multiplied by function b = lambda w: w**2 c = a * b x = 3.0 np.testing.assert_almost_equal( c(x), a(x) * b(x), 10, err_msg="Found wrong value in SED.__mul__") # function multiplied by SED c = b * a np.testing.assert_almost_equal( c(x), a(x) * b(x), 10, err_msg="Found wrong value in SED.__rmul__") # SED multiplied by scalar d = a * 4.2 np.testing.assert_almost_equal( d(x), a(x) * 4.2, 10, err_msg="Found wrong value in SED.__mul__") if sed is sed0: do_pickle(d) # assignment multiplication d *= 2 np.testing.assert_almost_equal( d(x), a(x) * 4.2 * 2, 10, err_msg="Found wrong value in SED.__mul__") if sed is sed0: do_pickle(d) # SED multiplied by dimensionless, constant SED e = galsim.SED(2.0, 'nm', '1') f = a * e np.testing.assert_almost_equal( f(x), a(x) * e(x), 10, err_msg="Found wrong value in SED.__mul__") f = e * a np.testing.assert_almost_equal( f(x), e(x) * a(x), 10, err_msg="Found wrong value in SED.__mul__") # SED multiplied by dimensionless, non-constant SED g = galsim.SED('wave', 'nm', '1') h = a * g np.testing.assert_almost_equal( h(x), a(x) * g(x), 10, err_msg="Found wrong value in SED.__mul__") h2 = g * a np.testing.assert_almost_equal( h2(x), g(x) * a(x), 10, err_msg="Found wrong value in SED.__mul__") sed1 = galsim.SED('1', 'nm', 'fphotons', redshift=1) sed2 = galsim.SED('2', 'nm', 'fphotons', redshift=2) sed3 = galsim.SED('3', 'nm', '1') sed4 = galsim.SED('4', 'nm', '1') try: np.testing.assert_raises(TypeError, sed1.__mul__, sed2) except ImportError: print('The assert_raises tests require nose') np.testing.assert_almost_equal((sed1 * sed3)(100), 3.0, 10, "Found wrong value in SED.__mul__") np.testing.assert_almost_equal((sed2 * sed4)(10), 8.0, 10, "Found wrong value in SED.__mul__") np.testing.assert_almost_equal((sed3 * sed4)(30), 12.0, 10, "Found wrong value in SED.__mul__")
def test_SED_basic(): """Basic tests of SED functionality """ c = 2.99792458e17 # speed of light in nm/s h = 6.62606957e-27 # Planck's constant in erg seconds nm_w = np.arange(10,1002,10) A_w = np.arange(100,10002,100) # All of these should be equivalent. Flat spectrum with F_lambda = 200 erg/nm s_list = [ galsim.SED(spec=lambda x: 200., flux_type='flambda', wave_type='nm'), galsim.SED(spec='200', flux_type='flambda', wave_type='nanometers'), galsim.SED('200', wave_type='nanometers', flux_type='flambda'), galsim.SED('200', 'nm', 'flambda'), galsim.SED('np.sqrt(4.e4)', 'nm', 'flambda'), galsim.SED('numpy.sqrt(4.e4)', 'nm', 'flambda'), galsim.SED('math.sqrt(4.e4)', 'nm', 'flambda'), # 200 erg/nm / 10 A/nm = 20 erg/A galsim.SED(spec='20', flux_type='flambda', wave_type='Angstroms'), # 200 erg/nm / (hc/w erg/photon) = 200 w/hc photons/nm galsim.SED(spec='200 * wave / %r'%(h*c), wave_type='NANOmeters', flux_type='fphotons'), # 200 erg/nm / (hc/w erg/photon) / 10 A/nm = 20 (w in A)/hc photons/A galsim.SED(spec='20 * (wave/10) / %r'%(h*c), flux_type='fphotons', wave_type='Ang'), # 200 erg/nm / (c/w^2 Hz/nm) = 200 w^2/c erg/Hz galsim.SED(spec='200 * wave**2 / %r'%c, flux_type='fnu', wave_type='nm'), galsim.SED(spec='200 * (wave/10)**2 / %r'%c, flux_type='fnu', wave_type='A'), galsim.SED(galsim.LookupTable([1,1e3],[200,200], interpolant='linear'), wave_type='nanometers', flux_type='flambda'), galsim.SED(galsim.LookupTable([1,1e4],[20,20], interpolant='linear'), wave_type='ang', flux_type='flambda'), galsim.SED(galsim.LookupTable([1,1e3],[200/(h*c),2e5/(h*c)], interpolant='linear'), flux_type='fphotons', wave_type='nm'), galsim.SED(galsim.LookupTable([1,1e4],[2/(h*c),2e4/(h*c)], interpolant='linear'), flux_type='fphotons', wave_type='A'), galsim.SED(galsim.LookupTable([1,1e3],[200/c,2e8/c], interpolant='linear', x_log=True, f_log=True), flux_type='fnu', wave_type='nanometers'), galsim.SED(galsim.LookupTable([1,1e4],[2/c,2e8/c], interpolant='linear', x_log=True, f_log=True), flux_type='fnu', wave_type='A'), galsim.SED(galsim.LookupTable(nm_w, 200.*np.ones(100)), wave_type='nanometers', flux_type='flambda'), galsim.SED(galsim.LookupTable(A_w, 20.*np.ones(100)), flux_type='flambda', wave_type='A'), galsim.SED(galsim.LookupTable(nm_w, 200.*nm_w/(h*c)), flux_type='fphotons', wave_type='nm'), galsim.SED(galsim.LookupTable(A_w, 2.*A_w/(h*c)), flux_type='fphotons', wave_type='A'), galsim.SED(galsim.LookupTable(nm_w, 200.*nm_w**2/c), flux_type='fnu', wave_type='nanometers'), galsim.SED(galsim.LookupTable(A_w, 2.*A_w**2/c), flux_type='fnu', wave_type='A'), galsim.SED(galsim.LookupTable([1, 100-1.e-10, 100, 1000, 1000+1.e-10, 2000], [0., 0., 200., 200., 0., 0.], interpolant='linear'), wave_type='nm', flux_type='flambda') ] s_list += [ s_list[9].thin(), s_list[10].thin(), s_list[11].thin(), s_list[12].thin(), s_list[13].thin(), s_list[14].thin(), s_list[15].thin(), s_list[15].thin(preserve_range=True), s_list[18].thin(), s_list[18].thin(preserve_range=True), s_list[21].thin(), s_list[21].thin(preserve_range=True), galsim.SED('1000', 'nm', 'flambda', redshift=4), galsim.SED('1000', 'nm', 'flambda').atRedshift(4.0), ] for k,s in enumerate(s_list): print(k,' s = ', s) np.testing.assert_almost_equal(s(400)*h*c/400, 200, decimal=10) np.testing.assert_almost_equal(s(900)*h*c/900, 200, decimal=10) waves = np.arange(700,800,10) np.testing.assert_array_almost_equal(s(waves) * h*c/waves, 200, decimal=10) if k < len(s_list)-2: np.testing.assert_equal(s.redshift, 0.) else: np.testing.assert_almost_equal(s.redshift, 4.) # Only the first one is not picklable if k > 0: do_pickle(s, lambda x: (x(470), x(490), x(910)) ) do_pickle(s)
def test_SED_mul(): """Check that SEDs multiply like I think they should... """ sed0 = galsim.SED(galsim.LookupTable([1,2,3,4,5], [1.1,2.2,3.3,4.4,5.5]), wave_type='nm', flux_type='fphotons') sed1 = galsim.SED(lambda nu: nu**2, wave_type=units.Hz, flux_type='fnu', fast=False) sed2 = galsim.SED(17.0, wave_type='ang', flux_type='1') for sed, z in zip( [sed0, sed1, sed2], [0, 0.2, 0.4] ): a = sed.atRedshift(z) # SED multiplied by function b = lambda w: w**2 c = a*b x = 3.0 np.testing.assert_almost_equal(c(x), a(x) * b(x), 10, err_msg="Found wrong value in SED.__mul__") # function multiplied by SED c = b*a np.testing.assert_almost_equal(c(x), a(x) * b(x), 10, err_msg="Found wrong value in SED.__rmul__") # SED multiplied by scalar d = a*4.2 np.testing.assert_almost_equal(d(x), a(x) * 4.2, 10, err_msg="Found wrong value in SED.__mul__") if sed is sed0: do_pickle(d) # assignment multiplication d *= 2 np.testing.assert_almost_equal(d(x), a(x) * 4.2 * 2, 10, err_msg="Found wrong value in SED.__mul__") if sed is sed0: do_pickle(d) # SED multiplied by dimensionless, constant SED e = galsim.SED(2.0, 'nm', '1') f = a*e np.testing.assert_almost_equal(f(x), a(x) * e(x), 10, err_msg="Found wrong value in SED.__mul__") f = e*a np.testing.assert_almost_equal(f(x), e(x) * a(x), 10, err_msg="Found wrong value in SED.__mul__") # SED multiplied by dimensionless, non-constant SED g = galsim.SED('wave', 'nm', '1') h = a*g np.testing.assert_almost_equal(h(x), a(x) * g(x), 10, err_msg="Found wrong value in SED.__mul__") h2 = g*a np.testing.assert_almost_equal(h2(x), g(x) * a(x), 10, err_msg="Found wrong value in SED.__mul__") sed1 = galsim.SED('1', 'nm', 'fphotons', redshift=1) sed2 = galsim.SED('2', 'nm', 'fphotons', redshift=2) sed3 = galsim.SED('3', 'nm', '1') sed4 = galsim.SED('4', 'nm', '1') try: np.testing.assert_raises(TypeError, sed1.__mul__, sed2) except ImportError: print('The assert_raises tests require nose') np.testing.assert_almost_equal((sed1*sed3)(100), 3.0, 10, "Found wrong value in SED.__mul__") np.testing.assert_almost_equal((sed2*sed4)(10), 8.0, 10, "Found wrong value in SED.__mul__") np.testing.assert_almost_equal((sed3*sed4)(30), 12.0, 10, "Found wrong value in SED.__mul__")
def test_phase_screen_list(): """Test list-like behaviors of PhaseScreenList.""" rng = galsim.BaseDeviate(1234) rng2 = galsim.BaseDeviate(123) aper = galsim.Aperture(diam=1.0) ar1 = galsim.AtmosphericScreen(10, 1, alpha=0.997, L0=None, time_step=0.01, rng=rng) assert ar1._time == 0.0, "AtmosphericScreen initialized with non-zero time." do_pickle(ar1) do_pickle(ar1, func=lambda x: x._tab2d(12.3, 45.6)) do_pickle(ar1, func=lambda x: x._wavefront(aper.u, aper.v, None, theta0).sum()) do_pickle(ar1, func=lambda x: x.wavefront(aper.u, aper.v, 0.0).sum()) do_pickle(ar1, func=lambda x: np.sum(x.wavefront_gradient(aper.u, aper.v, 0.0))) t = np.empty_like(aper.u) ud = galsim.UniformDeviate(rng.duplicate()) ud.generate(t.ravel()) t *= 0.1 # Only do a few boiling steps do_pickle(ar1, func=lambda x: x.wavefront(aper.u, aper.v, t).sum()) do_pickle(ar1, func=lambda x: np.sum(x.wavefront_gradient(aper.u, aper.v, t))) # Try seeking backwards assert ar1._time > 0.0 ar1._seek(0.0) # But not before t=0.0 try: np.testing.assert_raises(ValueError, ar1._seek, -1.0) except ImportError: pass # Check that L0=np.inf and L0=None yield the same thing here too. ar2 = galsim.AtmosphericScreen(10, 1, alpha=0.997, L0=np.inf, time_step=0.01, rng=rng) assert ar1 == ar2 # Create a couple new screens with different types/parameters ar2 = galsim.AtmosphericScreen(10, 1, alpha=0.995, time_step=0.015, rng=rng2) assert ar1 != ar2 ar3 = galsim.OpticalScreen(diam=1.0, aberrations=[0, 0, 0, 0, 0, 0, 0, 0, 0.1]) do_pickle(ar3) do_pickle(ar3, func=lambda x: x._wavefront(aper.u, aper.v, None, theta0).sum()) do_pickle(ar3, func=lambda x: np.sum( x._wavefront_gradient(aper.u, aper.v, None, theta0))) do_pickle(ar3, func=lambda x: x.wavefront(aper.u, aper.v).sum()) do_pickle(ar3, func=lambda x: np.sum(x.wavefront_gradient(aper.u, aper.v))) atm = galsim.Atmosphere( screen_size=30.0, altitude=[0.0, 1.0], speed=[1.0, 2.0], direction=[0.0 * galsim.degrees, 120 * galsim.degrees], r0_500=0.15, rng=rng) atm.append(ar3) do_pickle(atm) do_pickle(atm, func=lambda x: x._wavefront(aper.u, aper.v, None, theta0).sum()) do_pickle(atm, func=lambda x: x.wavefront(aper.u, aper.v, 0.0, theta0).sum()) do_pickle(atm, func=lambda x: np.sum(x.wavefront_gradient(aper.u, aper.v, 0.0))) do_pickle(atm, func=lambda x: np.sum( x._wavefront_gradient(aper.u, aper.v, 0.0, theta0))) # testing append, extend, __getitem__, __setitem__, __delitem__, __eq__, __ne__ atm2 = galsim.PhaseScreenList(atm[:-1]) # Refers to first n-1 screens assert atm != atm2 # Append a different screen to the end of atm2 atm2.append(ar2) assert atm != atm2 # Swap the last screen in atm2 for the one that should match atm. del atm2[-1] atm2.append(atm[-1]) assert atm == atm2 # Test building from empty PhaseScreenList atm3 = galsim.PhaseScreenList() atm3.extend(atm2) assert atm == atm3 # Test constructing from existing PhaseScreenList atm4 = galsim.PhaseScreenList(atm3) del atm4[-1] assert atm != atm4 atm4.append(atm[-1]) assert atm == atm4 # Test swap atm4[0], atm4[1] = atm4[1], atm4[0] assert atm != atm4 atm4[0], atm4[1] = atm4[1], atm4[0] assert atm == atm4 wf = atm._wavefront(aper.u, aper.v, None, theta0) wf2 = atm2._wavefront(aper.u, aper.v, None, theta0) wf3 = atm3._wavefront(aper.u, aper.v, None, theta0) wf4 = atm4._wavefront(aper.u, aper.v, None, theta0) np.testing.assert_array_equal(wf, wf2, "PhaseScreenLists are inconsistent") np.testing.assert_array_equal(wf, wf3, "PhaseScreenLists are inconsistent") np.testing.assert_array_equal(wf, wf4, "PhaseScreenLists are inconsistent") # Check copy import copy # Shallow copy copies by reference. atm5 = copy.copy(atm) assert atm[0] == atm5[0] assert atm[0] is atm5[0] atm._seek(1.0) assert atm[0]._time == 1.0, "Wrong time for AtmosphericScreen" assert atm[0] == atm5[0] assert atm[0] is atm5[0] # Deepcopy actually makes an indepedent object in memory. atm5 = copy.deepcopy(atm) assert atm[0] == atm5[0] assert atm[0] is not atm5[0] atm._seek(2.0) assert atm[0]._time == 2.0, "Wrong time for AtmosphericScreen" # But we still get equality, since this doesn't depend on mutable internal state: assert atm[0] == atm5[0] # Constructor should accept both list and indiv layers as arguments. atm6 = galsim.PhaseScreenList(atm[0]) atm7 = galsim.PhaseScreenList([atm[0]]) assert atm6 == atm7 do_pickle(atm6, func=lambda x: x._wavefront(aper.u, aper.v, None, theta0).sum()) do_pickle(atm6, func=lambda x: np.sum(x.wavefront_gradient(aper.u, aper.v, 0.0))) atm6 = galsim.PhaseScreenList(atm[0], atm[1]) atm7 = galsim.PhaseScreenList([atm[0], atm[1]]) atm8 = galsim.PhaseScreenList( atm[0:2]) # Slice returns PhaseScreenList, so this works too. assert atm6 == atm7 assert atm6 == atm8 # Check some actual derived PSFs too, not just phase screens. Use a small pupil_plane_size and # relatively large pupil_plane_scale to speed up the unit test. atm._reset() assert atm[0]._time == 0.0, "Wrong time for AtmosphericScreen" kwargs = dict(exptime=0.05, time_step=0.01, diam=1.1, lam=1000.0) psf = atm.makePSF(**kwargs) do_pickle(psf) do_pickle(psf, func=lambda x: x.drawImage(nx=20, ny=20, scale=0.1)) psf2 = atm2.makePSF(**kwargs) psf3 = atm3.makePSF(**kwargs) psf4 = atm4.makePSF(**kwargs) np.testing.assert_array_equal(psf, psf2, "PhaseScreenPSFs are inconsistent") np.testing.assert_array_equal(psf, psf3, "PhaseScreenPSFs are inconsistent") np.testing.assert_array_equal(psf, psf4, "PhaseScreenPSFs are inconsistent")