class CastTests(unittest.TestCase): def setUp(self): p = np.arange(1, 1001, 2) temp = 10. * np.exp(-.008*p) - 15. * np.exp(-0.005*(p+100)) + 2. sal = -14. * np.exp(-.01*p) + 34. self.p = p self.temp = temp self.sal = sal self.cast = CTDCast(p, sal, temp) return def test_numerical_indexing(self): r = self.cast[40] self.assertTrue(r["pressure"] == 81) self.assertTrue(r["salinity"] == 27.771987072878822) self.assertTrue(r["temperature"] == 1.1627808544797258) r = self.cast[100] self.assertTrue(r["pressure"] == 201) self.assertTrue(r["salinity"] == 32.124158554636729) self.assertTrue(r["temperature"] == 0.67261848597249019) r = self.cast[400] self.assertTrue(r["pressure"] == 801) self.assertTrue(r["salinity"] == 33.995350253934227) self.assertTrue(r["temperature"] == 1.8506793256302907) return def test_kw_indexing(self): self.assertTrue(np.all(self.cast["pressure"] == self.p)) self.assertTrue(np.all(self.cast["salinity"] == self.sal)) self.assertTrue(np.all(self.cast["temperature"] == self.temp)) return def test_kw_property_indexing(self): cast = Cast(pressure=self.p, temp=self.temp, sal=self.sal, name="Cruise station 7") self.assertEqual(cast.p["name"], "Cruise station 7") return def test_concatenation(self): p = np.arange(1, 1001, 2) temp = 12. * np.exp(-.007*p) - 14. * np.exp(-0.005*(p+100)) + 1.8 sal = -13. * np.exp(-.01*p) + 34.5 cast2 = Cast(pres=p, temp=temp, sal=sal) cc = self.cast + cast2 self.assertTrue(isinstance(cc, CastCollection)) self.assertEqual(len(cc), 2) return def test_interpolate(self): self.assertEqual(np.round(self.cast.interpolate("temperature", "pressure", 4.0), 8), 2.76745605) self.assertEqual(np.round(self.cast.interpolate("temperature", "salinity", 33.0), 8), 0.77935861) # temp not monotonic, which screws up the simple interpolation scheme #self.assertEqual(np.round(self.cast.interpolate("pres", "temp", 1.5), 8), # 2.7674560521632685) return def test_add_property_using_alias(self): cast = Cast(pres=self.p, temp=self.temp, sal=self.sal) cast.p["comment"] = "performed bottle cast #23" self.assertEqual(cast.properties["comment"][-2:], "23") return def test_read_property_using_alias(self): cast = Cast(pressure=self.p, temp=self.temp, sal=self.sal, time="late") self.assertEqual(cast.p["time"], "late") return def test_add_density(self): p = np.arange(10) t = 20.0 * 0.2 * p s = 30.0 * 0.25 * p x = [-20.0 for _ in p] y = [50.0 for _ in p] sa = gsw.sa_from_sp(s, p, x, y) ct = gsw.ct_from_t(sa, t, p) rho = gsw.rho(sa, ct, p) cast = CTDCast(p, s, t, coordinates=(-20, 50)) cast.add_density() self.assertTrue(np.allclose(rho, cast["density"])) return def test_add_buoyancy_freq_squared(self): # This is a fairly lousy test, merely ensuring that an N^2 field was # calculated, and that it's not wildly different than the direct # calculation. p = np.arange(10) t = 20.0 * 0.2 * p s = 30.0 * 0.25 * p x = [-20.0 for _ in p] y = [50.0 for _ in p] sa = gsw.sa_from_sp(s, p, x, y) ct = gsw.ct_from_t(sa, t, p) rho = np.asarray(gsw.rho(sa, ct, p)) cast = CTDCast(p, s, t, coordinates=(-20, 50), density=rho) cast.add_depth() cast.add_Nsquared(depthkey="depth") # Calculate the buoyancy frequency directly z = cast["depth"].values drhodz = -np.r_[rho[1]-rho[0], rho[2:]-rho[:-2], rho[-1]-rho[-2]] / \ np.r_[z[1]-z[0], z[2:]-z[:-2], z[-1]-z[-2]] N2_direct = -9.81 / rho * drhodz self.assertTrue(np.mean(np.abs(cast["N2"][1:] - N2_direct[1:])) < 0.0004) return def test_LADCP_shear(self): z = np.arange(0, 300) u = z**1.01 - z v = z**1.005 - z u_ans = 1.01 * z**0.01 - 1 v_ans = 1.005 * z**0.005 - 1 lad = narwhal.LADCP(z, u, v) lad.add_shear() self.assertTrue(np.max(abs(lad["dudz"][1:-1] - u_ans[1:-1])) < 0.005) self.assertTrue(np.max(abs(lad["dvdz"][1:-1] - v_ans[1:-1])) < 0.005) return
class CastTests(unittest.TestCase): def setUp(self): p = np.arange(1, 1001, 2) temp = 10. * np.exp(-.008 * p) - 15. * np.exp(-0.005 * (p + 100)) + 2. sal = -14. * np.exp(-.01 * p) + 34. self.p = p self.temp = temp self.sal = sal self.cast = CTDCast(p, sal, temp) return def test_numerical_indexing(self): r = self.cast[40] self.assertTrue(r["pressure"] == 81) self.assertTrue(r["salinity"] == 27.771987072878822) self.assertTrue(r["temperature"] == 1.1627808544797258) r = self.cast[100] self.assertTrue(r["pressure"] == 201) self.assertTrue(r["salinity"] == 32.124158554636729) self.assertTrue(r["temperature"] == 0.67261848597249019) r = self.cast[400] self.assertTrue(r["pressure"] == 801) self.assertTrue(r["salinity"] == 33.995350253934227) self.assertTrue(r["temperature"] == 1.8506793256302907) return def test_kw_indexing(self): self.assertTrue(np.all(self.cast["pressure"] == self.p)) self.assertTrue(np.all(self.cast["salinity"] == self.sal)) self.assertTrue(np.all(self.cast["temperature"] == self.temp)) return def test_kw_property_indexing(self): cast = Cast(pressure=self.p, temp=self.temp, sal=self.sal, name="Cruise station 7") self.assertEqual(cast.p["name"], "Cruise station 7") return def test_concatenation(self): p = np.arange(1, 1001, 2) temp = 12. * np.exp(-.007 * p) - 14. * np.exp(-0.005 * (p + 100)) + 1.8 sal = -13. * np.exp(-.01 * p) + 34.5 cast2 = Cast(pres=p, temp=temp, sal=sal) cc = self.cast + cast2 self.assertTrue(isinstance(cc, CastCollection)) self.assertEqual(len(cc), 2) return def test_interpolate(self): self.assertEqual( np.round(self.cast.interpolate("temperature", "pressure", 4.0), 8), 2.76745605) self.assertEqual( np.round(self.cast.interpolate("temperature", "salinity", 33.0), 8), 0.77935861) # temp not monotonic, which screws up the simple interpolation scheme #self.assertEqual(np.round(self.cast.interpolate("pres", "temp", 1.5), 8), # 2.7674560521632685) return def test_add_property_using_alias(self): cast = Cast(pres=self.p, temp=self.temp, sal=self.sal) cast.p["comment"] = "performed bottle cast #23" self.assertEqual(cast.properties["comment"][-2:], "23") return def test_read_property_using_alias(self): cast = Cast(pressure=self.p, temp=self.temp, sal=self.sal, time="late") self.assertEqual(cast.p["time"], "late") return def test_add_density(self): p = np.arange(10) t = 20.0 * 0.2 * p s = 30.0 * 0.25 * p x = [-20.0 for _ in p] y = [50.0 for _ in p] sa = gsw.sa_from_sp(s, p, x, y) ct = gsw.ct_from_t(sa, t, p) rho = gsw.rho(sa, ct, p) cast = CTDCast(p, s, t, coordinates=(-20, 50)) cast.add_density() self.assertTrue(np.allclose(rho, cast["density"])) return def test_add_buoyancy_freq_squared(self): # This is a fairly lousy test, merely ensuring that an N^2 field was # calculated, and that it's not wildly different than the direct # calculation. p = np.arange(10) t = 20.0 * 0.2 * p s = 30.0 * 0.25 * p x = [-20.0 for _ in p] y = [50.0 for _ in p] sa = gsw.sa_from_sp(s, p, x, y) ct = gsw.ct_from_t(sa, t, p) rho = np.asarray(gsw.rho(sa, ct, p)) cast = CTDCast(p, s, t, coordinates=(-20, 50), density=rho) cast.add_depth() cast.add_Nsquared(depthkey="depth") # Calculate the buoyancy frequency directly z = cast["depth"].values drhodz = -np.r_[rho[1]-rho[0], rho[2:]-rho[:-2], rho[-1]-rho[-2]] / \ np.r_[z[1]-z[0], z[2:]-z[:-2], z[-1]-z[-2]] N2_direct = -9.81 / rho * drhodz self.assertTrue( np.mean(np.abs(cast["N2"][1:] - N2_direct[1:])) < 0.0004) return def test_LADCP_shear(self): z = np.arange(0, 300) u = z**1.01 - z v = z**1.005 - z u_ans = 1.01 * z**0.01 - 1 v_ans = 1.005 * z**0.005 - 1 lad = narwhal.LADCP(z, u, v) lad.add_shear() self.assertTrue(np.max(abs(lad["dudz"][1:-1] - u_ans[1:-1])) < 0.005) self.assertTrue(np.max(abs(lad["dvdz"][1:-1] - v_ans[1:-1])) < 0.005) return