def test_SED_withFlux(): """ Check that setting the flux works. """ rband = galsim.Bandpass(os.path.join(bppath, 'LSST_r.dat'), 'nm') for z in [0, 0.2, 0.4]: for fast in [True, False]: a = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), wave_type='ang', flux_type='flambda', fast=fast) if z != 0: a = a.atRedshift(z) a = a.withFlux(1.0, rband) np.testing.assert_array_almost_equal(a.calculateFlux(rband), 1.0, 5, "Setting SED flux failed.") # Should be equivalent to multiplying an SED * Bandpass and computing the # "bolometric" flux. ab = a * rband bolo_bp = galsim.Bandpass('1', blue_limit=ab.blue_limit, red_limit=ab.red_limit, wave_type='nm') np.testing.assert_array_almost_equal( ab.calculateFlux(bolo_bp), 1.0, 5, "Calculating SED flux from sed * bp failed.")
def test_SED_calculateSeeingMomentRatio(): # compute a relative moment shift and compare to externally generated known result. sed = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), 'nm', 'flambda') bandpass = galsim.Bandpass(os.path.join(bppath, 'LSST_r.dat'), 'nm') relative_size = sed.calculateSeeingMomentRatio(bandpass) # and now do the integral right here to compare. # \Delta r^2/r^2 = \frac{\int{sed(\lambda) * bandpass(\lambda) * (\lambda/500)^-0.4 d\lambda}} # {\int{sed(\lambda) * bandpass(\lambda) d\lambda}} waves = np.union1d(sed.wave_list, bandpass.wave_list) num = np.trapz(sed(waves) * bandpass(waves) * (waves/500.0)**(-0.4), waves) den = np.trapz(sed(waves) * bandpass(waves), waves) np.testing.assert_almost_equal(relative_size, num/den, 5) # Repeat with a function bandpass, since different path in code bp2 = galsim.Bandpass('1', 'nm', blue_limit=bandpass.blue_limit, red_limit=bandpass.red_limit) relative_size = sed.calculateSeeingMomentRatio(bp2) waves = (sed*bp2).wave_list num = np.trapz(sed(waves) * (waves/500.0)**(-0.4), waves) den = np.trapz(sed(waves), waves) np.testing.assert_almost_equal(relative_size, num/den, 4) # Invalid for dimensionless SED flat = galsim.SED(2.0, 'nm', '1') with assert_raises(galsim.GalSimSEDError): flat.calculateSeeingMomentRatio(bandpass)
def test_Bandpass_wave_type(): """Check that `wave_type='ang'` works in Bandpass.__init__ """ # Also check with and without explicit directory a0 = galsim.Bandpass(os.path.join(datapath, 'LSST_r.dat'), wave_type='nm') a1 = galsim.Bandpass('LSST_r.dat', wave_type='ang') np.testing.assert_approx_equal(a0.red_limit, a1.red_limit*10, err_msg="Bandpass.red_limit doesn't respect wave_type") np.testing.assert_approx_equal(a0.blue_limit, a1.blue_limit*10, err_msg="Bandpass.blue_limit doesn't respect wave_type") np.testing.assert_approx_equal(a0.effective_wavelength, a1.effective_wavelength*10, err_msg="Bandpass.effective_wavelength doesn't respect" +" wave_type") b0 = galsim.Bandpass(galsim.LookupTable([1,2,3,4,5], [1,2,3,4,5]), wave_type='nm') b1 = galsim.Bandpass(galsim.LookupTable([10,20,30,40,50], [1,2,3,4,5]), wave_type='ang') np.testing.assert_approx_equal(b0.red_limit, b1.red_limit, err_msg="Bandpass.red_limit doesn't respect wave_type") np.testing.assert_approx_equal(b0.blue_limit, b1.blue_limit, err_msg="Bandpass.blue_limit doesn't respect wave_type") np.testing.assert_approx_equal(b0.effective_wavelength, b1.effective_wavelength, err_msg="Bandpass.effective_wavelength doesn't respect" +" wave_type") np.testing.assert_array_almost_equal(b0([1,2,3,4,5]), b1([1,2,3,4,5]), decimal=7, err_msg="Bandpass.__call__ doesn't respect wave_type")
def test_Bandpass_wave_type(): """Check that `wave_type='ang'` works in Bandpass.__init__ """ import time t1 = time.time() a0 = galsim.Bandpass(os.path.join(datapath, 'LSST_r.dat')) a1 = galsim.Bandpass(os.path.join(datapath, 'LSST_r.dat'), wave_type='ang') np.testing.assert_approx_equal(a0.red_limit, a1.red_limit*10, err_msg="Bandpass.red_limit doesn't respect wave_type") np.testing.assert_approx_equal(a0.blue_limit, a1.blue_limit*10, err_msg="Bandpass.blue_limit doesn't respect wave_type") np.testing.assert_approx_equal(a0.effective_wavelength, a1.effective_wavelength*10, err_msg="Bandpass.effective_wavelength doesn't respect" +" wave_type") b0 = galsim.Bandpass(galsim.LookupTable([1,2,3,4,5], [1,2,3,4,5])) b1 = galsim.Bandpass(galsim.LookupTable([10,20,30,40,50], [1,2,3,4,5]), wave_type='ang') np.testing.assert_approx_equal(b0.red_limit, b1.red_limit, err_msg="Bandpass.red_limit doesn't respect wave_type") np.testing.assert_approx_equal(b0.blue_limit, b1.blue_limit, err_msg="Bandpass.blue_limit doesn't respect wave_type") np.testing.assert_approx_equal(b0.effective_wavelength, b1.effective_wavelength, err_msg="Bandpass.effective_wavelength doesn't respect" +" wave_type") np.testing.assert_array_almost_equal(b0([1,2,3,4,5]), b1([1,2,3,4,5]), decimal=7, err_msg="Bandpass.__call__ doesn't respect wave_type") t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)
def test_zp(): """Check that the zero points are maintained in an appropriate way when thinning, truncating.""" # Make a bandpass and set an AB zeropoint. bp = galsim.Bandpass(os.path.join(datapath, 'LSST_r.dat'), 'nm') bp = bp.withZeropoint(zeropoint='AB') # Confirm that if we use the default thinning kwargs, then the zeropoint for the thinned # bandpass is the same (exactly) as the original. bp_th = bp.thin() np.testing.assert_equal(bp.zeropoint, bp_th.zeropoint, "Zeropoint not preserved after thinning with defaults") bp_tr = bp.truncate(relative_throughput=1.e-4) np.testing.assert_equal(bp.zeropoint, bp_tr.zeropoint, "Zeropoint not preserved after truncating with defaults") # Confirm that if we explicit set the kwarg to clear the zeropoint when thinning or truncating, # or if we truncate using blue_limit or red_limit, then the new bandpass has no zeropoint bp_th = bp.thin(preserve_zp = False) assert bp_th.zeropoint is None, \ "Zeropoint erroneously preserved after thinning with preserve_zp=False" bp_tr = bp.truncate(preserve_zp = False) assert bp_tr.zeropoint is None, \ "Zeropoint erroneously preserved after truncating with preserve_zp=False" bp_tr = bp.truncate(red_limit = 600.) assert bp_tr.zeropoint is None, \ "Zeropoint erroneously preserved after truncating with explicit red_limit" bp_tr = bp.truncate(blue_limit = 550.) assert bp_tr.zeropoint is None, \ "Zeropoint erroneously preserved after truncating with explicit blue_limit" with assert_raises(galsim.GalSimValueError): bp_tr = bp.truncate(preserve_zp = 'False') with assert_raises(galsim.GalSimValueError): bp_tr = bp.truncate(preserve_zp = 43) with assert_raises(galsim.GalSimIncompatibleValuesError): galsim.Bandpass('1', 'nm', 400, 550).truncate(relative_throughput=1.e-4)
def test_Bandpass_mul(): """Check that Bandpasses multiply like I think they should... """ a = galsim.Bandpass(galsim.LookupTable([1,2,3,4,5], [1,2,3,4,5]), 'nm') b = galsim.Bandpass(galsim.LookupTable([1.1,2.2,3.0,4.4,5.5], [1.11,2.22,3.33,4.44,5.55]), 'nm') # Bandpass * Bandpass c = a*b np.testing.assert_almost_equal(c.blue_limit, 1.1, 10, err_msg="Found wrong blue limit in Bandpass.__mul__") np.testing.assert_almost_equal(c.red_limit, 5.0, 10, err_msg="Found wrong red limit in Bandpass.__mul__") np.testing.assert_almost_equal(c(3.0), 3.0 * 3.33, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_almost_equal(c(1.1), a(1.1)*1.11, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_almost_equal(c(5.0), b(5.0)*5, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(c.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") # Bandpass * fn d = lambda w: w**2 e = c*d np.testing.assert_almost_equal(e(3.0), 3.0 * 3.33 * 3.0**2, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(e.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") # fn * Bandpass e = d*c np.testing.assert_almost_equal(e(3.0), 3.0 * 3.33 * 3.0**2, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(e.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") # Bandpass * scalar f = b * 1.21 np.testing.assert_almost_equal(f(3.0), 3.33 * 1.21, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(f.wave_list, [1.1, 2.2, 3, 4.4, 5.5], err_msg="wrong wave_list in Bandpass.__mul__") do_pickle(f) # scalar * Bandpass f = 1.21 * a np.testing.assert_almost_equal(f(3.0), 3.0 * 1.21, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(f.wave_list, [1, 2, 3, 4, 5], err_msg="wrong wave_list in Bandpass.__mul__") do_pickle(f)
def test_Bandpass_div(): """Check that Bandpasses multiply like I think they should... """ a_lt = galsim.Bandpass(galsim.LookupTable([1,2,3,4,5], [1,2,3,4,5]), 'nm') a_fn = galsim.Bandpass('wave', 'nm', blue_limit=1, red_limit=5) b = galsim.Bandpass(galsim.LookupTable([1.1,2.2,3.0,4.4,5.5], [1.11,2.22,3.33,4.44,5.55]), 'nm') for a in [a_lt, a_fn]: # Bandpass / Bandpass c = a/b np.testing.assert_almost_equal(c.blue_limit, 1.1, 10, err_msg="Found wrong blue limit in Bandpass.__div__") np.testing.assert_almost_equal(c.red_limit, 5.0, 10, err_msg="Found wrong red limit in Bandpass.__div__") np.testing.assert_almost_equal(c(3.0), 3.0 / 3.33, 10, err_msg="Found wrong value in Bandpass.__div__") np.testing.assert_almost_equal(c(1.1), a(1.1)/1.11, 10, err_msg="Found wrong value in Bandpass.__div__") np.testing.assert_almost_equal(c(5.0), 5/b(5.0), 10, err_msg="Found wrong value in Bandpass.__div__") if a is a_lt: combined_wave_list = [1.1, 2, 2.2, 3, 4., 4.4, 5] else: combined_wave_list = [1.1, 2.2, 3, 4.4, 5] np.testing.assert_array_almost_equal(c.wave_list, combined_wave_list, err_msg="wrong wave_list in Bandpass.__div__") # Bandpass / fn d = lambda w: w**2 e = c/d np.testing.assert_almost_equal(e(3.0), c(3.0) / 3.0**2, 10, err_msg="Found wrong value in Bandpass.__div__") np.testing.assert_array_almost_equal(e.wave_list, combined_wave_list, err_msg="wrong wave_list in Bandpass.__div__") # Bandpass / scalar f = a / 1.21 np.testing.assert_almost_equal(f(3.0), a(3.0)/1.21, 10, err_msg="Found wrong value in Bandpass.__div__") if a is a_lt: np.testing.assert_array_almost_equal(f.wave_list, [1, 2, 3, 4, 5], err_msg="wrong wave_list in Bandpass.__div__") do_pickle(f) else: np.testing.assert_array_almost_equal(f.wave_list, [], err_msg="wrong wave_list in Bandpass.__div__") sed = galsim.SED('1', wave_type='nm', flux_type='1') assert_raises(TypeError, a_lt.__div__, sed) assert_raises(TypeError, a_fn.__div__, sed)
def test_Bandpass_div(): """Check that Bandpasses multiply like I think they should... """ import time t1 = time.time() a = galsim.Bandpass(galsim.LookupTable([1,2,3,4,5], [1,2,3,4,5])) b = galsim.Bandpass(galsim.LookupTable([1.1,2.2,3.0,4.4,5.5], [1.11,2.22,3.33,4.44,5.55])) # Bandpass / Bandpass c = a/b np.testing.assert_almost_equal(c.blue_limit, 1.1, 10, err_msg="Found wrong blue limit in Bandpass.__mul__") np.testing.assert_almost_equal(c.red_limit, 5.0, 10, err_msg="Found wrong red limit in Bandpass.__mul__") np.testing.assert_almost_equal(c(3.0), 3.0 / 3.33, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_almost_equal(c(1.1), a(1.1)/1.11, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_almost_equal(c(5.0), 5/b(5.0), 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(c.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") # Bandpass / fn d = lambda w: w**2 e = c/d np.testing.assert_almost_equal(e(3.0), 3.0 / 3.33 / 3.0**2, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(e.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") # fn / Bandpass e = d/c np.testing.assert_almost_equal(e(3.0), 3.0**2 / (3.0 / 3.33), 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(e.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") # Bandpass / scalar f = e / 1.21 np.testing.assert_almost_equal(f(3.0), (3.0**2 / (3.0 / 3.33)) / 1.21, 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(f.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") # scalar / Bandpass f = 1.21 / e np.testing.assert_almost_equal(f(3.0), 1.21 / (3.0**2 / (3.0 / 3.33)), 10, err_msg="Found wrong value in Bandpass.__mul__") np.testing.assert_array_almost_equal(f.wave_list, [1.1, 2, 2.2, 3, 4, 4.4, 5], err_msg="wrong wave_list in Bandpass.__mul__") t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)
def meas_cg_bias(gal, row, f_name, rt_g, f_type, npix=360): """Computes bias due to color gradient on sahpe measuremnt. For an input chromatic galaxy with cg, gal an equilvalent galaxy with no cg is created and the shear recovered from each (with ring test) is measured. @gal input galaxy with cg. @row astropy table row to save measured shear. @rt_g shaer applied to the galaxy. @type string to identify the column of row to save measured shear. """ print " Measuring CG bias" filt = galsim.Bandpass('data/baseline/total_%s.dat'%f_name, wave_type='nm').thin(rel_err=1e-4) meas_args = cg_fn.meas_args(rt_g=rt_g, npix=npix) meas_args.bp = filt psf_args = cg_fn.psf_params() gcg, gnocg = cg_fn.calc_cg_crg(gal, meas_args, psf_args) print " Measured CG bias" if (gcg == "Fail") or (gnocg == "Fail"): print "HSM FAILED" g_f = np.ones([2, len(rt_g)]) * -10 gcg, gnocg = g_f, g_f row[f_type + '_g_cg'] = gcg.T row[f_type + '_g_no_cg'] = gnocg.T
def calculateFlux(self, bandpass): """ Return the flux (photons/cm^2/s) of the SED through the bandpass. @param bandpass A Bandpass object representing a filter, or None to compute the bolometric flux. For the bolometric flux the integration limits will be set to (0, infinity), which implies that the SED needs to be evaluable over this entire range. @returns the flux through the bandpass. """ if self.dimensionless: raise TypeError("Cannot calculate flux of dimensionless SED.") if bandpass is None: # do bolometric flux from galsim.deprecated import depr depr('Using calculateFlux(bandpass=None) to compute a bolometric flux', 1.5, '', "If you need this functionality, you can use a pseudo-bolometric Bandpass created " "with: bp = Bandpass('1', 'nm', blue_limit=sed.blue_limit, " "red_limit=sed.red_limit)") bp = galsim.Bandpass('1', 'nm', self.blue_limit, self.red_limit) return self.calculateFlux(bp) else: # do flux through bandpass if len(bandpass.wave_list) > 0 or len(self.wave_list) > 0: slop = 1e-6 # nm if (self.blue_limit > bandpass.blue_limit + slop or self.red_limit < bandpass.red_limit - slop): raise ValueError("SED undefined within Bandpass") x, _, _ = galsim.utilities.combine_wave_list(self, bandpass) return np.trapz(bandpass(x) * self(x), x) else: return galsim.integ.int1d(lambda w: bandpass(w)*self(w), bandpass.blue_limit, bandpass.red_limit)
def test_SED_calculateDCRMomentShifts(): import time t1 = time.time() # compute some moment shifts sed = galsim.SED(os.path.join(datapath, 'CWW_E_ext.sed')) bandpass = galsim.Bandpass(os.path.join(datapath, 'LSST_r.dat')) Rbar, V = sed.calculateDCRMomentShifts(bandpass, zenith_angle=45 * galsim.degrees) # now rotate parallactic angle 180 degrees, and see if the output makes sense. Rbar2, V2 = sed.calculateDCRMomentShifts(bandpass, zenith_angle=45 * galsim.degrees, parallactic_angle=180 * galsim.degrees) np.testing.assert_array_almost_equal(Rbar, -Rbar2, 15) np.testing.assert_array_almost_equal(V, V2, 25) # now rotate parallactic angle 90 degrees. Rbar3, V3 = sed.calculateDCRMomentShifts(bandpass, zenith_angle=45 * galsim.degrees, parallactic_angle=90 * galsim.degrees) np.testing.assert_almost_equal(Rbar[0], Rbar3[1], 15) np.testing.assert_almost_equal(V[1, 1], V3[0, 0], 25) # and now test against an external known result. np.testing.assert_almost_equal(V[1, 1] * (180.0 / np.pi * 3600)**2, 0.0065, 4) t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_SED_calculateDCRMomentShifts(): # compute some moment shifts sed = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), 'nm', 'flambda') bandpass = galsim.Bandpass(os.path.join(bppath, 'LSST_r.dat'), 'nm') Rbar, V = sed.calculateDCRMomentShifts(bandpass, zenith_angle=45*galsim.degrees) # now rotate parallactic angle 180 degrees, and see if the output makes sense. Rbar2, V2 = sed.calculateDCRMomentShifts(bandpass, zenith_angle=45*galsim.degrees, parallactic_angle=180*galsim.degrees) np.testing.assert_array_almost_equal(Rbar, -Rbar2, 15) np.testing.assert_array_almost_equal(V, V2, 25) # now rotate parallactic angle 90 degrees. Rbar3, V3 = sed.calculateDCRMomentShifts(bandpass, zenith_angle=45*galsim.degrees, parallactic_angle=90*galsim.degrees) np.testing.assert_almost_equal(Rbar[0], Rbar3[1], 15) np.testing.assert_almost_equal(V[1,1], V3[0,0], 25) # and now do the integral right here to compare. # \bar{R} = \frac{\int{sed(\lambda) * bandpass(\lambda) * R(\lambda) d\lambda}} # {\int{sed(\lambda) * bandpass(\lambda) d\lambda}} # where sed is in units of photons/nm (which is the default) waves = np.union1d(sed.wave_list, bandpass.wave_list) R = galsim.dcr.get_refraction(waves, 45.*galsim.degrees) Rnum = np.trapz(sed(waves) * bandpass(waves) * R, waves) den = np.trapz(sed(waves) * bandpass(waves), waves) rad2arcsec = galsim.radians / galsim.arcsec np.testing.assert_almost_equal(Rnum/den*rad2arcsec, Rbar[1]*rad2arcsec, 4) # and for the second moment, V, the numerator is: # \int{sed(\lambda) * bandpass(\lambda) * (R(\lambda) - Rbar)^2 d\lambda} Vnum = np.trapz(sed(waves) * bandpass(waves) * (R - Rnum/den)**2, waves) np.testing.assert_almost_equal(Vnum/den, V[1,1], 5)
def test_thin(): s = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), wave_type='ang', flux_type='flambda', fast=False) bp = galsim.Bandpass('1', 'nm', blue_limit=s.blue_limit, red_limit=s.red_limit) flux = s.calculateFlux(bp) print("Original number of SED samples = ",len(s.wave_list)) for err in [1.e-2, 1.e-3, 1.e-4, 1.e-5]: print("Test err = ",err) thin_s = s.thin(rel_err=err, preserve_range=True, fast_search=False) thin_flux = thin_s.calculateFlux(bp) thin_err = (flux-thin_flux)/flux print("num samples with preserve_range = True, fast_search = False: ",len(thin_s.wave_list)) print("realized error = ",(flux-thin_flux)/flux) thin_s = s.thin(rel_err=err, preserve_range=True) thin_flux = thin_s.calculateFlux(bp) thin_err = (flux-thin_flux)/flux print("num samples with preserve_range = True: ",len(thin_s.wave_list)) print("realized error = ",(flux-thin_flux)/flux) assert np.abs(thin_err) < err, "Thinned SED failed accuracy goal, preserving range." thin_s = s.thin(rel_err=err, preserve_range=False) thin_flux = thin_s.calculateFlux(bp.truncate(thin_s.blue_limit, thin_s.red_limit)) thin_err = (flux-thin_flux)/flux print("num samples with preserve_range = False: ",len(thin_s.wave_list)) print("realized error = ",(flux-thin_flux)/flux) assert np.abs(thin_err) < err, "Thinned SED failed accuracy goal, w/ range shrinkage." assert_raises(ValueError, s.thin, rel_err=-0.5) assert_raises(ValueError, s.thin, rel_err=1.5) # These errors aren't accessible from the SED or Bandpass calls. assert_raises(ValueError, galsim.utilities.thin_tabulated_values, s.wave_list[3:], s._spec.getVals()) assert_raises(ValueError, galsim.utilities.thin_tabulated_values, s.wave_list[-1::-1], s._spec.getVals()) # Check some pathalogical spectra to stress the thinning algorithm s = galsim.SED(galsim.LookupTable(range(6), [0,0,1,1,0,0]),'nm','1').thin() print('s = ',s) np.testing.assert_equal(s.wave_list, range(1,5)) s = galsim.SED(galsim.LookupTable(range(6), [0,0,1,1,0,0]),'nm','1').thin(trim_zeros=False) print('s = ',s) np.testing.assert_equal(s.wave_list, range(6)) s = galsim.SED(galsim.LookupTable(range(8), [1.e-8,1.e-6,1,1,1,1.e-6,1.e-10,1.e-100]), 'nm','1').thin(preserve_range=False) print('s = ',s) np.testing.assert_equal(s.wave_list, range(1,6)) s = galsim.SED(galsim.LookupTable(range(8), np.zeros(8)),'nm','1').thin() print('s = ',s) np.testing.assert_equal(s.wave_list, [0,7]) s = galsim.SED(galsim.LookupTable(range(2), [1,1], interpolant='linear'),'nm','1').thin() print('s = ',s) np.testing.assert_equal(s.wave_list, [0,1]) s = galsim.SED(galsim.LookupTable(range(3), [1, 1.e-20, 0], interpolant='linear'), 'nm','1').thin(preserve_range=False) print('s = ',s) np.testing.assert_equal(s.wave_list, [0,1])
def Bandpass_rdiv(self, other): depr( '__rdiv__', 1.3, "Bandpass(throughput=lambda wave:other/bandpass(wave))", "We removed this function because we don't know of any clear use case. " + "If you have one, please open an issue, and we can add this function back." ) blue_limit = self.blue_limit red_limit = self.red_limit wave_list = self.wave_list if isinstance(other, galsim.Bandpass): if len(other.wave_list) > 0: wave_list = np.union1d(wave_list, other.wave_list) blue_limit = max([self.blue_limit, other.blue_limit]) red_limit = min([self.red_limit, other.red_limit]) wave_list = wave_list[(wave_list >= blue_limit) & (wave_list <= red_limit)] if hasattr(other, '__call__'): tp = lambda w: other(w) / self.func(w) else: tp = lambda w: other / self.func(w) return galsim.Bandpass(tp, 'nm', blue_limit, red_limit, _wave_list=wave_list)
def test_SED_atRedshift(): """Check that SEDs redshift correctly. """ a = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), wave_type='ang', flux_type='flambda') bolo_bp = galsim.Bandpass('1', blue_limit=a.blue_limit, red_limit=a.red_limit, wave_type='nm') bolo_flux = a.calculateFlux(bolo_bp) print('bolo_flux = ',bolo_flux) for z1, z2 in zip([-0.01, -0.02, 0.5, 1.0, 1.4], [-0.2, 0.2, 1.0, 1.0, 1.0]): b = a.atRedshift(z1) c = b.atRedshift(z1) # same redshift, so should be no change d = c.atRedshift(z2) # do a relative redshifting from z1 to z2 e = b.thin(rel_err=1.e-5) # effectively tests that wave_list is handled correctly. # (Issue #520) for w in [350, 500, 650]: print('a(w) = ',a(w)) print('b(w(1+z)) = ',b(w*(1.+z1))) print('c(w(1+z)) = ',c(w*(1.+z1))) print('d(w(1+z)) = ',d(w*(1.+z2))) print('e(w(1+z)) = ',e(w*(1.+z1))) np.testing.assert_almost_equal(a(w)/bolo_flux, b(w*(1.0+z1))/bolo_flux, 15, err_msg="error redshifting SED") np.testing.assert_almost_equal(a(w)/bolo_flux, c(w*(1.0+z1))/bolo_flux, 15, err_msg="error redshifting SED") np.testing.assert_almost_equal(a(w)/bolo_flux, d(w*(1.0+z2))/bolo_flux, 15, err_msg="error redshifting SED") np.testing.assert_almost_equal(a(w)/bolo_flux, e(w*(1.0+z1))/bolo_flux, 5, err_msg="error redshifting and thinning SED") with assert_raises(ValueError): a.atRedshift(-1.1)
def cg_other_est(): """Test all HSM shear estimators give same value as REGAUSS (default)""" in_p = cg_fn.LSST_Args() filt = galsim.Bandpass('data/baseline/total_r.dat', wave_type='nm').thin(rel_err=1e-4) in_p.b_SED, in_p.d_SED, in_p.c_SED = cg_fn.get_template_seds(in_p) gal = cg_fn.get_gal_cg(in_p) psf_args = cg_fn.psf_params() meas_args = cg_fn.meas_args(shear_est='KSB') meas_args.bp = filt gcg, gnocg = cg_fn.calc_cg_crg(gal, meas_args, psf_args) # Previously measured value at default galaxy parameters np.testing.assert_array_almost_equal((gcg / gnocg - 1).T[0], [0.00106263, 0.00106594], decimal=5) meas_args.shear_est = 'BJ' gcg, gnocg = cg_fn.calc_cg_crg(gal, meas_args, psf_args) # Previously measured value at default galaxy parameters np.testing.assert_array_almost_equal((gcg / gnocg - 1).T[0], [0.00106263, 0.00106594], decimal=5) meas_args.shear_est = 'LINEAR' gcg, gnocg = cg_fn.calc_cg_crg(gal, meas_args, psf_args) # Previously measured value at default galaxy parameters np.testing.assert_array_almost_equal((gcg / gnocg - 1).T[0], [0.00106263, 0.00106594], decimal=5)
def test_cosmos_fluxnorm(): """Check for flux normalization properties of COSMOSCatalog class.""" # Check that if we make a RealGalaxy catalog, and a COSMOSCatalog, and draw the real object, the # fluxes should match very well. These correspond to 1s exposures. test_ind = 54 rand_seed = 12345 cat = galsim.COSMOSCatalog( file_name='real_galaxy_catalog_23.5_example.fits', dir=datapath, exclusion_level='none') rgc = galsim.RealGalaxyCatalog( file_name='real_galaxy_catalog_23.5_example.fits', dir=datapath) final_psf = galsim.Airy(diam=1.2, lam=800.) # PSF twice as big as HST in F814W. gal1 = cat.makeGalaxy(test_ind, gal_type='real', rng=galsim.BaseDeviate(rand_seed)) gal2 = galsim.RealGalaxy(rgc, index=test_ind, rng=galsim.BaseDeviate(rand_seed)) gal1 = galsim.Convolve(gal1, final_psf) gal2 = galsim.Convolve(gal2, final_psf) im1 = gal1.drawImage(scale=0.05) im2 = gal2.drawImage(scale=0.05) # Then check that if we draw a parametric representation that is achromatic, that the flux # matches reasonably well (won't be exact because model isn't perfect). gal1_param = cat.makeGalaxy(test_ind, gal_type='parametric', chromatic=False) gal1_param_final = galsim.Convolve(gal1_param, final_psf) im1_param = gal1_param_final.drawImage(scale=0.05) # Then check the same for a chromatic parametric representation that is drawn into the same # band. bp_file = os.path.join(galsim.meta_data.share_dir, 'bandpasses', 'ACS_wfc_F814W.dat') bandpass = galsim.Bandpass(bp_file, wave_type='nm').withZeropoint(25.94) #34.19) gal1_chrom = cat.makeGalaxy(test_ind, gal_type='parametric', chromatic=True) gal1_chrom = galsim.Convolve(gal1_chrom, final_psf) im1_chrom = gal1_chrom.drawImage(bandpass, scale=0.05) ref_val = [im1.array.sum(), im1.array.sum(), im1.array.sum()] test_val = [im2.array.sum(), im1_param.array.sum(), im1_chrom.array.sum()] np.testing.assert_allclose( ref_val, test_val, rtol=0.1, err_msg='Flux normalization problem in COSMOS galaxies') # Finally, check that the original COSMOS info is stored properly after transformations, for # both Sersic galaxies (like galaxy 0 in the catalog) and the one that is gal1_param above. gal0_param = cat.makeGalaxy(0, gal_type='parametric', chromatic=False) assert hasattr(gal0_param.shear(g1=0.05).original, 'index'), \ 'Sersic galaxy does not retain index information after transformation' assert hasattr(gal1_param.shear(g1=0.05).original, 'index'), \ 'Bulge+disk galaxy does not retain index information after transformation'
def test_thin(): """Test that bandpass thinning works with the requested accuracy.""" s = galsim.SED('1', wave_type='nm', flux_type='fphotons') bp = galsim.Bandpass(os.path.join(datapath, 'LSST_r.dat'), 'nm') flux = s.calculateFlux(bp) print("Original number of bandpass samples = ", len(bp.wave_list)) for err in [1.e-2, 1.e-3, 1.e-4, 1.e-5]: print("Test err = ", err) thin_bp = bp.thin(rel_err=err, preserve_range=True, fast_search=False) thin_flux = s.calculateFlux(thin_bp) thin_err = (flux - thin_flux) / flux print("num samples with preserve_range = True, fast_search = False: ", len(thin_bp.wave_list)) print("realized error = ", (flux - thin_flux) / flux) thin_bp = bp.thin(rel_err=err, preserve_range=True) thin_flux = s.calculateFlux(thin_bp) thin_err = (flux - thin_flux) / flux print("num samples with preserve_range = True: ", len(thin_bp.wave_list)) print("realized error = ", (flux - thin_flux) / flux) assert np.abs( thin_err ) < err, "Thinned bandpass failed accuracy goal, preserving range." thin_bp = bp.thin(rel_err=err, preserve_range=False) thin_flux = s.calculateFlux(thin_bp) thin_err = (flux - thin_flux) / flux print("num samples with preserve_range = False: ", len(thin_bp.wave_list)) print("realized error = ", (flux - thin_flux) / flux) assert np.abs( thin_err ) < err, "Thinned bandpass failed accuracy goal, w/ range shrinkage."
def get_HST_Bandpass(band): """Returns a Bandpass object for the catalog. Using similar code from real.py in Galsim """ # Currently, have bandpasses available for HST COSMOS, AEGIS, and CANDELS. # ACS zeropoints (AB magnitudes) from # http://www.stsci.edu/hst/acs/analysis/zeropoints/old_page/localZeropoints#tablestart # WFC3 zeropoints (AB magnitudes) from # http://www.stsci.edu/hst/wfc3/phot_zp_lbn bps = { 'F275W': ('WFC3_uvis_F275W.dat', 24.1305), 'F336W': ('WFC3_uvis_F336W.dat', 24.6682), 'F435W': ('ACS_wfc_F435W.dat', 25.65777), 'F606W': ('ACS_wfc_F606W.dat', 26.49113), 'F775W': ('ACS_wfc_F775W.dat', 25.66504), 'F814W': ('ACS_wfc_F814W.dat', 25.94333), 'F850LP': ('ACS_wfc_F850LP.dat', 24.84245), 'F105W': ('WFC3_ir_F105W.dat', 26.2687), 'F125W': ('WFC3_ir_F125W.dat', 26.2303), 'F160W': ('WFC3_ir_F160W.dat', 25.9463) } try: bp = bps[band.upper()] except KeyError: raise ValueError("Unknown bandpass {0}".format(band)) fn = os.path.join(galsim.meta_data.share_dir, "bandpasses", bp[0]) bandpass = galsim.Bandpass(fn, wave_type='nm', zeropoint=bp[1]) return bandpass.thin(rel_err=1e-4)
def test_dep_bandpass(): """Test the deprecated methods in galsim/deprecated/bandpass.py. """ b = galsim.Bandpass( galsim.LookupTable([1.1, 2.2, 3.0, 4.4, 5.5], [1.11, 2.22, 3.33, 4.44, 5.55]), 'nm') d = lambda w: w**2 # fn / Bandpass #e = d/b e = check_dep(b.__rdiv__, d) np.testing.assert_almost_equal( e(3.0), 3.0**2 / 3.33, 10, err_msg="Found wrong value in Bandpass.__rdiv__") np.testing.assert_array_almost_equal( e.wave_list, [1.1, 2.2, 3.0, 4.4, 5.5], err_msg="wrong wave_list in Bandpass.__rdiv__") # scalar / Bandpass #f = 1.21 / b f = check_dep(b.__rdiv__, 1.21) np.testing.assert_almost_equal( f(3.0), 1.21 / 3.33, 10, err_msg="Found wrong value in Bandpass.__rdiv__") np.testing.assert_array_almost_equal( f.wave_list, [1.1, 2.2, 3.0, 4.4, 5.5], err_msg="wrong wave_list in Bandpass.__rdiv__")
def test_thin(): import time t1 = time.time() s = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), wave_type='ang', flux_type='flambda') bp = galsim.Bandpass('1', 'nm', blue_limit=s.blue_limit, red_limit=s.red_limit) flux = s.calculateFlux(bp) print "Original number of SED samples = ",len(s.wave_list) for err in [1.e-2, 1.e-3, 1.e-4, 1.e-5]: print "Test err = ",err thin_s = s.thin(rel_err=err, preserve_range=True, fast_search=False) thin_flux = thin_s.calculateFlux(bp) thin_err = (flux-thin_flux)/flux print "num samples with preserve_range = True, fast_search = False: ",len(thin_s.wave_list) print "realized error = ",(flux-thin_flux)/flux thin_s = s.thin(rel_err=err, preserve_range=True) thin_flux = thin_s.calculateFlux(bp) thin_err = (flux-thin_flux)/flux print "num samples with preserve_range = True: ",len(thin_s.wave_list) print "realized error = ",(flux-thin_flux)/flux assert np.abs(thin_err) < err, "Thinned SED failed accuracy goal, preserving range." thin_s = s.thin(rel_err=err, preserve_range=False) thin_flux = thin_s.calculateFlux(bp) thin_err = (flux-thin_flux)/flux print "num samples with preserve_range = False: ",len(thin_s.wave_list) print "realized error = ",(flux-thin_flux)/flux assert np.abs(thin_err) < err, "Thinned SED failed accuracy goal, w/ range shrinkage." t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2-t1)
def test_dep_chromatic(): """Test the deprecated methods in galsim/deprecated/chromatic.py """ import time t1 = time.time() g = galsim.Gaussian(sigma=0.34) sed = galsim.SED('wave**3') obj = g * sed band = galsim.Bandpass('1-((wave-700)/100)**2', blue_limit=600., red_limit=800.) im1 = check_dep(obj.draw, bandpass=band) im2 = obj.drawImage(band, method='no_pixel') np.testing.assert_almost_equal(im1.scale, im2.scale) np.testing.assert_equal(im1.bounds, im2.bounds) np.testing.assert_array_almost_equal(im1.array, im2.array) im1 = check_dep(obj.draw, bandpass=band, normalization='sb') im2 = obj.drawImage(band, method='sb') np.testing.assert_almost_equal(im1.scale, im2.scale) np.testing.assert_equal(im1.bounds, im2.bounds) np.testing.assert_array_almost_equal(im1.array, im2.array) t2 = time.time() print 'time for %s = %.2f'%(funcname(),t2-t1)
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_photon_io(): """Test the ability to read and write photons to a file """ nphotons = 1000 obj = galsim.Exponential(flux=1.7, scale_radius=2.3) rng = galsim.UniformDeviate(1234) image = obj.drawImage(method='phot', n_photons=nphotons, save_photons=True, rng=rng) photons = image.photons assert photons.size() == len(photons) == nphotons with assert_raises(galsim.GalSimIncompatibleValuesError): obj.drawImage(method='phot', n_photons=nphotons, save_photons=True, maxN=1.e5) file_name = 'output/photons1.dat' photons.write(file_name) photons1 = galsim.PhotonArray.read(file_name) assert photons1.size() == nphotons assert not photons1.hasAllocatedWavelengths() assert not photons1.hasAllocatedAngles() np.testing.assert_array_equal(photons1.x, photons.x) np.testing.assert_array_equal(photons1.y, photons.y) np.testing.assert_array_equal(photons1.flux, photons.flux) sed = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), 'nm', 'flambda').thin() bandpass = galsim.Bandpass(os.path.join(bppath, 'LSST_r.dat'), 'nm').thin() wave_sampler = galsim.WavelengthSampler(sed, bandpass, rng) angle_sampler = galsim.FRatioAngles(1.3, 0.3, rng) ops = [wave_sampler, angle_sampler] for op in ops: op.applyTo(photons) file_name = 'output/photons2.dat' photons.write(file_name) photons2 = galsim.PhotonArray.read(file_name) assert photons2.size() == nphotons assert photons2.hasAllocatedWavelengths() assert photons2.hasAllocatedAngles() np.testing.assert_array_equal(photons2.x, photons.x) np.testing.assert_array_equal(photons2.y, photons.y) np.testing.assert_array_equal(photons2.flux, photons.flux) np.testing.assert_array_equal(photons2.dxdz, photons.dxdz) np.testing.assert_array_equal(photons2.dydz, photons.dydz) np.testing.assert_array_equal(photons2.wavelength, photons.wavelength)
def readInLSST(datapath, filter_names): filters = {} for name in filter_names: filename = os.path.join(datapath, 'LSST_{}.dat'.format(name)) filters[name] = galsim.Bandpass(filename) filters[name] = filters[name].withZeropoint("AB", 640.0, 15.0) filters[name] = filters[name].thin(rel_err=1e-4) return filters
def test_cosmos_fluxnorm(): """Check for flux normalization properties of COSMOSCatalog class.""" import time t1 = time.time() # Check that if we make a RealGalaxy catalog, and a COSMOSCatalog, and draw the real object, the # fluxes should match very well. These correspond to 1s exposures. test_ind = 54 rand_seed = 12345 cat = galsim.COSMOSCatalog(file_name='real_galaxy_catalog_example.fits', dir=datapath, exclude_fail=False, exclude_bad=False) rgc = galsim.RealGalaxyCatalog( file_name='real_galaxy_catalog_example.fits', dir=datapath) final_psf = galsim.Airy(diam=1.2, lam=800.) # PSF twice as big as HST in F814W. gal1 = cat.makeGalaxy(test_ind, gal_type='real', rng=galsim.BaseDeviate(rand_seed)) gal2 = galsim.RealGalaxy(rgc, index=test_ind, rng=galsim.BaseDeviate(rand_seed)) gal1 = galsim.Convolve(gal1, final_psf) gal2 = galsim.Convolve(gal2, final_psf) im1 = gal1.drawImage(scale=0.05) im2 = gal2.drawImage(scale=0.05) # Then check that if we draw a parametric representation that is achromatic, that the flux # matches reasonably well (won't be exact because model isn't perfect). gal1_param = cat.makeGalaxy(test_ind, gal_type='parametric', chromatic=False) gal1_param = galsim.Convolve(gal1_param, final_psf) im1_param = gal1_param.drawImage(scale=0.05) # Then check the same for a chromatic parametric representation that is drawn into the same # band. bp_file = os.path.join(galsim.meta_data.share_dir, 'wfc_F814W.dat.gz') bandpass = galsim.Bandpass(bp_file, wave_type='ang').thin().withZeropoint( 25.94) #34.19) gal1_chrom = cat.makeGalaxy(test_ind, gal_type='parametric', chromatic=True) gal1_chrom = galsim.Convolve(gal1_chrom, final_psf) im1_chrom = gal1_chrom.drawImage(bandpass, scale=0.05) ref_val = [im1.array.sum(), im1.array.sum(), im1.array.sum()] test_val = [im2.array.sum(), im1_param.array.sum(), im1_chrom.array.sum()] np.testing.assert_allclose( ref_val, test_val, rtol=0.1, err_msg='Flux normalization problem in COSMOS galaxies') t2 = time.time() print 'time for %s = %.2f' % (funcname(), t2 - t1)
def test_truncate_inputs(): """Test that bandpass truncation respects certain sanity constraints on the inputs.""" # Don't allow truncation via two different methods. bp = galsim.Bandpass(os.path.join(datapath, 'LSST_r.dat'), 'nm') assert_raises(ValueError, bp.truncate, relative_throughput=1.e-4, blue_limit=500.) # If blue_limit or red_limit is supplied, don't allow values that are outside the original # wavelength range. assert_raises(ValueError, bp.truncate, blue_limit=0.9*bp.blue_limit) assert_raises(ValueError, bp.truncate, red_limit=1.1*bp.red_limit)
def test_lsst_y_focus(): # Check that applying reasonable focus depth (from O'Connor++06) indeed leads to smaller spot # size for LSST y-band. rng = galsim.BaseDeviate(9876543210) bandpass = galsim.Bandpass("LSST_y.dat", wave_type='nm') sed = galsim.SED("1", wave_type='nm', flux_type='flambda') obj = galsim.Gaussian(fwhm=1e-5) oversampling = 32 photon_ops0 = [ galsim.WavelengthSampler(sed, bandpass, rng=rng), galsim.FRatioAngles(1.234, 0.606, rng=rng), galsim.FocusDepth(0.0), galsim.Refraction(3.9) ] img0 = obj.drawImage( sensor=galsim.SiliconSensor(), method='phot', n_photons=100000, photon_ops=photon_ops0, scale=0.2/oversampling, nx=32*oversampling, ny=32*oversampling, rng=rng ) T0 = img0.calculateMomentRadius() T0 *= 10*oversampling/0.2 # arcsec => microns # O'Connor finds minimum spot size when the focus depth is ~ -12 microns. Our sensor isn't # necessarily the same as the one there though; our minimum seems to be around -6 microns. # That could be due to differences in the design of the sensor though. We just use -6 microns # here, which is still useful to test the sign of the `depth` parameter and the interaction of # the 4 different surface operators required to produce this effect, and is roughly consistent # with O'Connor. depth1 = -6. # microns, negative means surface is intrafocal depth1 /= 10 # microns => pixels photon_ops1 = [ galsim.WavelengthSampler(sed, bandpass, rng=rng), galsim.FRatioAngles(1.234, 0.606, rng=rng), galsim.FocusDepth(depth1), galsim.Refraction(3.9) ] img1 = obj.drawImage( sensor=galsim.SiliconSensor(), method='phot', n_photons=100000, photon_ops=photon_ops1, scale=0.2/oversampling, nx=32*oversampling, ny=32*oversampling, rng=rng ) T1 = img1.calculateMomentRadius() T1 *= 10*oversampling/0.2 # arcsec => microns np.testing.assert_array_less(T1, T0)
def test_wavelength_sampler(): nphotons = 1000 obj = galsim.Exponential(flux=1.7, scale_radius=2.3) rng = galsim.UniformDeviate(1234) photon_array = obj.SBProfile.shoot(nphotons, rng) bppath = os.path.abspath(os.path.join(path, "../examples/data/")) sedpath = os.path.abspath(os.path.join(path, "../share/")) sed = galsim.SED(os.path.join(sedpath, 'CWW_E_ext.sed'), 'nm', 'flambda').thin() bandpass = galsim.Bandpass(os.path.join(bppath, 'LSST_r.dat'), 'nm').thin() sampler = galsim.WavelengthSampler(sed, bandpass, rng) sampler.applyTo(photon_array) # Note: the underlying functionality of the sampleWavelengths function is tested # in test_sed.py. So here we are really just testing that the wrapper class is # properly writing to the photon_array.wavelengths array. assert photon_array.hasAllocatedWavelengths() assert not photon_array.hasAllocatedAngles() print('mean wavelength = ',np.mean(photon_array.wavelength)) print('min wavelength = ',np.min(photon_array.wavelength)) print('max wavelength = ',np.max(photon_array.wavelength)) assert np.min(photon_array.wavelength) > bandpass.blue_limit assert np.max(photon_array.wavelength) < bandpass.red_limit # This is a regression test based on the value at commit 0b0cc764a9 np.testing.assert_almost_equal(np.mean(photon_array.wavelength), 616.92072, decimal=3) # Test that using this as a surface op work properly. # First do the shooting and clipping manually. im1 = galsim.Image(64,64,scale=1) im1.setCenter(0,0) photon_array.flux[photon_array.wavelength < 600] = 0. photon_array.addTo(im1.image.view()) # Make a dummy surface op that clips any photons with lambda < 600 class Clip600(object): def applyTo(self, photon_array): photon_array.flux[photon_array.wavelength < 600] = 0. # Use (a new) sampler and clip600 as surface_ops in drawImage im2 = galsim.Image(64,64,scale=1) im2.setCenter(0,0) clip600 = Clip600() rng2 = galsim.BaseDeviate(1234) sampler2 = galsim.WavelengthSampler(sed, bandpass, rng2) obj.drawImage(im2, method='phot', n_photons=nphotons, use_true_center=False, surface_ops=[sampler2,clip600], rng=rng2) print('sum = ',im1.array.sum(),im2.array.sum()) np.testing.assert_array_equal(im1.array, im2.array)
def make_Euclid_filter(res=1.0): """ Make a Euclid-like filter (eye-balling Semboloni++13). @param res Resolution in nanometers. @return galsim.Bandpass object. """ x = [550.0, 750.0, 850.0, 900.0] y = [0.3, 0.3, 0.275, 0.2] tab = galsim.LookupTable(x, y, interpolant='linear') w = np.arange(550.0, 900.01, res) return galsim.Bandpass(galsim.LookupTable(w, tab(w), interpolant='linear'))