def test_ne(): objs = [ batoid.ConstMedium(1.0), batoid.ConstMedium(1.1), batoid.TableMedium([1, 2, 3], [3, 4, 3]), batoid.SellmeierMedium([ 0.6961663, 0.4079426, 0.8974794, 0.0684043**2, 0.1162414**2, 9.896161**2 ]), batoid.SellmeierMedium([ 0.4079426, 0.6961663, 0.8974794, 0.0684043**2, 0.1162414**2, 9.896161**2 ]), batoid.SumitaMedium([ 2.2705778, -0.010059376, 0.010414999, 0.00028872517, -2.2214495e-5, 1.4258559e-6 ]), batoid.SumitaMedium([ -0.010059376, 2.2705778, 0.010414999, 0.00028872517, -2.2214495e-5, 1.4258559e-6 ]), batoid.Air(), batoid.Air(pressure=100) ] all_obj_diff(objs)
def test_rSplit(): rng = np.random.default_rng(5) for _ in range(100): R = rng.normal(0.7, 0.8) conic = rng.uniform(-2.0, 1.0) ncoef = rng.integers(0, 5) coefs = [rng.normal(0, 1e-10) for i in range(ncoef)] asphere = batoid.Asphere(R, conic, coefs) theta_x = rng.normal(0.0, 1e-8) theta_y = rng.normal(0.0, 1e-8) rays = batoid.RayVector.asPolar( backDist=10.0, medium=batoid.Air(), wavelength=500e-9, outer=0.25*R, theta_x=theta_x, theta_y=theta_y, nrad=10, naz=10 ) coating = batoid.SimpleCoating(0.9, 0.1) reflectedRays = asphere.reflect(rays.copy(), coating=coating) m1 = batoid.Air() m2 = batoid.ConstMedium(1.1) refractedRays = asphere.refract(rays.copy(), m1, m2, coating=coating) refractedRays2, reflectedRays2 = asphere.rSplit(rays, m1, m2, coating) rays_allclose(reflectedRays, reflectedRays2) rays_allclose(refractedRays, refractedRays2)
def test_air(): # Just spot check some comparisons with GalSim. ws = [0.3, 0.5, 0.7, 0.9, 1.1] gsn = [1.00019563, 1.00018713, 1.00018498, 1.00018412, 1.00018369] air = batoid.Air() for w, n in zip(ws, gsn): np.testing.assert_allclose(n, air.getN(w * 1e-6), rtol=0, atol=1e-8) do_pickle(air)
def test_rSplit(): for i in range(100): R = np.random.normal(0.7, 0.8) conic = np.random.uniform(-2.0, 1.0) ncoef = np.random.randint(0, 4) coefs = [np.random.normal(0, 1e-10) for i in range(ncoef)] asphere = batoid.Asphere(R, conic, coefs) rays = batoid.rayGrid(10, 2*R, 0.0, 0.0, -1.0, 16, 500e-9, 1.0, batoid.Air()) coating = batoid.SimpleCoating(0.9, 0.1) reflectedRays = asphere.reflect(rays, coating) m1 = batoid.Air() m2 = batoid.ConstMedium(1.1) refractedRays = asphere.refract(rays, m1, m2, coating) reflectedRays2, refractedRays2 = asphere.rSplit(rays, m1, m2, coating) assert reflectedRays == reflectedRays2 assert refractedRays == refractedRays2
def test_refraction_chromatic(): import random random.seed(577215664) wavelength1 = 500e-9 wavelength2 = 600e-9 flux = 1.0 plane = batoid.Plane() filename = os.path.join(batoid.datadir, "media", "silica_dispersion.txt") wave, n = np.genfromtxt(filename).T wave *= 1e-6 # micron -> meters table = batoid.Table(wave, n, batoid.Table.Interpolant.linear) silica = batoid.TableMedium(table) air = batoid.Air() thx, thy = 0.001, 0.0001 dirCos = batoid.utils.gnomonicToDirCos(thx, thy) rv1 = batoid.rayGrid(10.0, 1., dirCos[0], dirCos[1], -dirCos[2], 2, wavelength1, flux, silica) rv2 = batoid.rayGrid(10.0, 1., dirCos[0], dirCos[1], -dirCos[2], 2, wavelength2, flux, silica) rays = [] for ray in rv1: rays.append(ray) for ray in rv2: rays.append(ray) rvCombined = batoid.RayVector(rays) rv1r = plane.refract(rv1, silica, air) rv2r = plane.refract(rv2, silica, air) assert rv1r != rv2r rays = [] for ray in rv1r: rays.append(ray) for ray in rv2r: rays.append(ray) rvrCombined1 = batoid.RayVector(rays) rvrCombined2 = plane.refract(rvCombined, silica, air) assert rvrCombined1 == rvrCombined2 # Check in-place plane.refractInPlace(rv1, silica, air) plane.refractInPlace(rv2, silica, air) assert rv1 != rv2 plane.refractInPlace(rvCombined, silica, air) rays = [] for ray in rv1: rays.append(ray) for ray in rv2: rays.append(ray) rvCombined2 = batoid.RayVector(rays) assert rvCombined == rvCombined2
def test_ne(): filename = os.path.join(batoid.datadir, "media", "silica_dispersion.txt") wave, n = np.genfromtxt(filename).T wave *= 1e-6 # microns -> meters table = batoid.Table(wave, n, batoid.Table.Interpolant.linear) table2 = batoid.Table(wave * 1.01, n, batoid.Table.Interpolant.linear) objs = [ batoid.ConstMedium(1.0), batoid.ConstMedium(1.1), batoid.TableMedium(table), batoid.TableMedium(table2), batoid.SellmeierMedium(0.6961663, 0.4079426, 0.8974794, 0.0684043**2, 0.1162414**2, 9.896161**2), batoid.SellmeierMedium(0.4079426, 0.6961663, 0.8974794, 0.0684043**2, 0.1162414**2, 9.896161**2), batoid.Air(), batoid.Air(pressure=100) ] all_obj_diff(objs)
def test_decam_psf(): # Just testing that doesn't crash for the moment fn = os.path.join(batoid.datadir, "DECam", "DECam.yaml") config = yaml.load(open(fn)) telescope = batoid.parse.parse_optic(config['opticalSystem']) stampSize = 1.0 # arcsec nx = 64 focalLength = 10.0 # guess if __name__ == '__main__': thetas = [0.0, 1800.0, 3960.0] # arcsec else: thetas = [3960.0] for theta in thetas: print(theta / 3600.0) dirCos = batoid.utils.gnomicToDirCos(0.0, theta / 206265) rays = batoid.circularGrid(10.0, 1.95, 0.5, dirCos[0], dirCos[1], -dirCos[2], 10, 100, 620e-9, 1.0, batoid.Air()) telescope.traceInPlace(rays) rays.trimVignettedInPlace() xs = rays.x - np.mean(rays.x) ys = rays.y - np.mean(rays.y) xs *= 206265 / focalLength # meters to arcsec ys *= 206265 / focalLength # Need to add half-pixel offset xs += stampSize / nx / 2 ys += stampSize / nx / 2 dx = stampSize / nx * focalLength / 206265 # meters psf = batoid.huygensPSF(telescope, 0.0, theta / 206265, 620e-9, nx=nx, dx=dx, dy=dx) if __name__ == '__main__': import matplotlib.pyplot as plt fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111) ax.imshow(psf.array, extent=np.r_[-1, 1, -1, 1] * stampSize / 2) ax.scatter(xs, ys, s=5, c='r', alpha=0.5) ax.set_title("DECam PSF field={:5.2f}".format(theta / 3600.0)) ax.set_xlabel("arcsec") ax.set_ylabel("arcsec") fig.tight_layout() plt.show()
def test_lsst_psf(): # Just testing that doesn't crash for the moment telescope = batoid.Optic.fromYaml("LSST_r.yaml") stampSize = 0.5 # arcsec nx = 64 focalLength = 1.234 * 8.36 # meters if __name__ == '__main__': thetas = [0.0, 1200.0, 3600.0, 6300.0] # arcsec else: thetas = [6300.0] for theta in thetas: print(theta / 3600.0) dirCos = batoid.utils.gnomonicToDirCos(0.0, theta / 206265) rays = batoid.circularGrid(10.0, 4.2, 2.55, dirCos[0], dirCos[1], dirCos[2], 10, 100, 620e-9, 1.0, batoid.Air()) telescope.traceInPlace(rays) rays.trimVignettedInPlace() xs = rays.x - np.mean(rays.x) ys = rays.y - np.mean(rays.y) xs *= 206265 / focalLength ys *= 206265 / focalLength # Need to add half-pixel offset xs += stampSize / nx / 2 ys += stampSize / nx / 2 dx = stampSize / nx * focalLength / 206265 # meters psf = batoid.huygensPSF(telescope, 0.0, theta / 206265, 620e-9, nx=64, dx=dx, dy=dx) if __name__ == '__main__': import matplotlib.pyplot as plt fig = plt.figure(figsize=(12, 8)) ax = fig.add_subplot(111) ax.imshow(psf.array, extent=np.r_[-1, 1, -1, 1] * stampSize / 2) ax.scatter(xs, ys, s=5, c='r', alpha=0.5) ax.set_title("LSST PSF field={:5.2f}".format(theta / 3600.0)) ax.set_xlabel("arcsec") ax.set_ylabel("arcsec") fig.tight_layout() plt.show()
def parse_medium(value): from numbers import Real if isinstance(value, batoid.Medium): return value elif isinstance(value, Real): return batoid.ConstMedium(value) elif isinstance(value, str): if value == 'air': return batoid.Air() elif value == 'silica': return batoid.SellmeierMedium(0.6961663, 0.4079426, 0.8974794, 0.0684043**2, 0.1162414**2, 9.896161**2) elif value == 'hsc_air': return batoid.ConstMedium(1.0) w = [0.4, 0.6, 0.75, 0.9, 1.1] w = [w_ * 1e-6 for w_ in w] if value == 'hsc_silica': return batoid.TableMedium( batoid.Table(w, [ 1.47009272, 1.45801158, 1.45421013, 1.45172729, 1.44917721 ], batoid.Table.Interpolant.linear)) elif value == 'hsc_bsl7y': return batoid.TableMedium( batoid.Table(w, [ 1.53123287, 1.51671428, 1.51225242, 1.50939738, 1.50653251 ], batoid.Table.Interpolant.linear)) elif value == 'hsc_pbl1y': return batoid.TableMedium( batoid.Table(w, [ 1.57046066, 1.54784671, 1.54157395, 1.53789058, 1.53457169 ], batoid.Table.Interpolant.linear)) elif value == 'NLAK10': return batoid.SellmeierMedium(1.72878017, 0.169257825, 1.19386956, 0.00886014635, 0.0363416509, 82.9009069) elif value == 'PFK85': return batoid.SumitaMedium(2.1858326, -0.0050155632, 0.0075107775, 0.00017770562, -1.2164148e-05, 6.1341005e-07) elif value == 'BK7': return batoid.SellmeierMedium(1.03961212, 0.231792344, 1.01046945, 0.00600069867, 0.0200179144, 103.560653) else: raise RuntimeError("Unknown medium {}".format(value))
def parse_medium(value): from numbers import Real if isinstance(value, batoid.Medium): return value elif isinstance(value, Real): return batoid.ConstMedium(value) elif isinstance(value, str): if value == 'air': return batoid.Air() elif value == 'silica': return batoid.SellmeierMedium(0.6961663, 0.4079426, 0.8974794, 0.0684043**2, 0.1162414**2, 9.896161**2) elif value == 'hsc_air': return batoid.ConstMedium(1.0) w = [0.4, 0.6, 0.75, 0.9, 1.1] w = [w_ * 1e-6 for w_ in w] w_desi = [ 365.015, 435.835, 486.133, 587.562, 656.273, 852.110, 1013.98 ] w_desi = [w_ * 1e-9 for w_ in w_desi] if value == 'hsc_silica': return batoid.TableMedium( batoid.Table(w, [ 1.47009272, 1.45801158, 1.45421013, 1.45172729, 1.44917721 ], batoid.Table.Interpolant.linear)) elif value == 'hsc_bsl7y': return batoid.TableMedium( batoid.Table(w, [ 1.53123287, 1.51671428, 1.51225242, 1.50939738, 1.50653251 ], batoid.Table.Interpolant.linear)) elif value == 'hsc_pbl1y': return batoid.TableMedium( batoid.Table(w, [ 1.57046066, 1.54784671, 1.54157395, 1.53789058, 1.53457169 ], batoid.Table.Interpolant.linear)) elif value == 'desi_C1': # Use melt data from DESI-2880-v2 return batoid.TableMedium( batoid.Table(w_desi, [ 1.474580, 1.466730, 1.463162, 1.458499, 1.456402, 1.452500, 1.450278 ], batoid.Table.Interpolant.linear)) elif value == 'desi_C2': # Use melt data from DESI-2880-v2 return batoid.TableMedium( batoid.Table(w_desi, [ 1.474641, 1.466791, 1.463223, 1.458561, 1.45646, 1.452563, 1.450342 ], batoid.Table.Interpolant.linear)) elif value == 'desi_ADC1': # Use melt data from DESI-2880-v2 return batoid.TableMedium( batoid.Table(w_desi, [ 1.536945, 1.527374, 1.523070, 1.517498, 1.515022, 1.510508, 1.508023 ], batoid.Table.Interpolant.linear)) elif value == 'desi_ADC2': # Use melt data from DESI-2880-v2 return batoid.TableMedium( batoid.Table(w_desi, [ 1.536225, 1.526635, 1.522325, 1.516746, 1.514267, 1.509743, 1.507246 ], batoid.Table.Interpolant.linear)) elif value == 'desi_C3': # Use generic fused silica until melt data is available. return batoid.TableMedium( batoid.Table(w_desi, [ 1.474555, 1.466701, 1.463132, 1.458467, 1.45637, 1.452469, 1.450245 ], batoid.Table.Interpolant.linear)) elif value == 'desi_C4': # Use generic fused silica until melt data is available. return batoid.TableMedium( batoid.Table(w_desi, [ 1.474555, 1.466701, 1.463132, 1.458467, 1.45637, 1.452469, 1.450245 ], batoid.Table.Interpolant.linear)) elif value == 'NLAK10': return batoid.SellmeierMedium(1.72878017, 0.169257825, 1.19386956, 0.00886014635, 0.0363416509, 82.9009069) elif value == 'PFK85': return batoid.SumitaMedium(2.1858326, -0.0050155632, 0.0075107775, 0.00017770562, -1.2164148e-05, 6.1341005e-07) elif value == 'BK7': return batoid.SellmeierMedium(1.03961212, 0.231792344, 1.01046945, 0.00600069867, 0.0200179144, 103.560653) else: raise RuntimeError("Unknown medium {}".format(value))