Example #1
0
 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
Example #2
0
 def test_three_sources1(self):
     c = CTDCast(np.arange(10), 3.6*np.ones(10), 22.1*np.ones(10))
     r1, r2, r3 = [1, 5, 8], [25, 20, 18], [1, 1, 1]
     r1, r2, r3 = [1, 25], [5, 20], [8, 18]
     (f1, f2, f3) = c.water_fractions((r1, r2, r3))
     self.assertTrue(np.allclose(f1, 0.5*np.ones(10)))
     self.assertTrue(np.allclose(f2, 0.3*np.ones(10)))
     self.assertTrue(np.allclose(f3, 0.2*np.ones(10)))
     return
Example #3
0
    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
Example #4
0
    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
Example #5
0
 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
Example #6
0
 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
     dt = datetime.datetime(1993, 8, 18, 14, 42, 36)
     self.cast = Cast(pres=self.p, temp=self.temp, sal=self.sal, date=dt)
     self.ctd = CTDCast(self.p, self.sal, self.temp, date=dt)
     self.collection = CastCollection(self.ctd, self.ctd)
     return
Example #7
0
    def test_three_sources2(self):
        print("test incomplete")
        source1 = (10.0, 34.0)
        source2 = (2.0, 32.0)
        source3 = (17.0, 34.5)

        p = np.arange(0, 2000, 2)
        S = 34.3 - 2.0 * np.exp(-p/300.0)
        T = 15.0 * np.exp(-p/150.0) - 2e-3 * p
        cast = CTDCast(p, S, T)
        partitions = cast.water_fractions([source1, source2, source3])

        # import matplotlib.pyplot as plt
        # import seaborn
        # for partition in partitions:
        #     plt.plot(partition, p)
        # plt.show()
        
        # temporary
        self.assertTrue(partitions is not None)
        return
Example #8
0
    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
Example #9
0
 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
     dt = datetime.datetime(1993, 8, 18, 14, 42, 36)
     self.cast = Cast(self.p, temp=self.temp, sal=self.sal, date=dt)
     self.ctd = CTDCast(self.p, temp=self.temp, sal=self.sal, date=dt)
     self.xbt = XBTCast(self.p, temp=self.temp, sal=self.sal, date=dt)
     self.collection = CastCollection(self.ctd, self.xbt, self.ctd)
     return
Example #10
0
    def test_three_sources_constant(self):
        ans = np.array([0.3, 0.2, 0.5])
        sources = [(34.0, 2.0), (34.5, 7.0), (34.6, 5.0)]
        s = np.array(sources)
        x = np.ones(10, dtype=np.float64)
        sal = x * np.dot(ans, s[:, 0])
        tmp = x * np.dot(ans, s[:, 1])

        c = CTDCast(np.arange(10), sal, tmp)
        (chi1, chi2, chi3) = narwhal.analysis.water_fractions(c, sources)
        self.assertTrue(np.allclose(chi1, 0.3 * np.ones(10)))
        self.assertTrue(np.allclose(chi2, 0.2 * np.ones(10)))
        self.assertTrue(np.allclose(chi3, 0.5 * np.ones(10)))
        return
Example #11
0
    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
Example #12
0
    def test_three_sources_varying(self):
        ans_chi1 = np.linspace(0.2, 0.35, 10)
        ans_chi2 = np.linspace(0.6, 0.1, 10)
        ans_chi3 = 1.0 - (ans_chi1 + ans_chi2)
        ans = np.c_[ans_chi1, ans_chi2, ans_chi3]

        sources = [(34.0, 2.0), (34.5, 7.0), (34.6, 5.0)]
        s = np.array(sources)
        x = np.ones(10, dtype=np.float64)
        sal = x * np.dot(ans, s[:, 0])
        tmp = x * np.dot(ans, s[:, 1])

        c = CTDCast(np.arange(10), sal, tmp)
        (chi1, chi2, chi3) = narwhal.analysis.water_fractions(c, sources)
        self.assertTrue(np.allclose(chi1, ans_chi1))
        self.assertTrue(np.allclose(chi2, ans_chi2))
        self.assertTrue(np.allclose(chi3, ans_chi3))
        return
Example #13
0
    def test_four_sources_varying(self):
        ans_chi1 = np.linspace(0.2, 0.35, 10)
        ans_chi2 = np.linspace(0.6, 0.1, 10)
        ans_chi3 = np.linspace(0.05, 0.12, 10)
        ans_chi4 = 1.0 - (ans_chi1 + ans_chi2 + ans_chi3)
        ans = np.c_[ans_chi1, ans_chi2, ans_chi3, ans_chi4]

        sources = [(34.0, 2.0, 280.0), (34.5, 70.0, 250.0), (34.6, 5.0, 330.0),
                   (33.9, 18.0, 390.0)]
        s = np.array(sources)
        x = np.ones(10, dtype=np.float64)
        sal = x * np.dot(ans, s[:, 0])
        tmp = x * np.dot(ans, s[:, 1])
        oxy = x * np.dot(ans, s[:, 2])

        c = CTDCast(np.arange(10), sal, tmp, oxygen=oxy)
        (chi1, chi2, chi3, chi4) = narwhal.analysis.water_fractions(
            c, sources, tracers=["salinity", "temperature", "oxygen"])
        self.assertTrue(np.allclose(chi1, ans_chi1))
        self.assertTrue(np.allclose(chi2, ans_chi2))
        self.assertTrue(np.allclose(chi3, ans_chi3))
        self.assertTrue(np.allclose(chi4, ans_chi4))
        return
Example #14
0
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
Example #15
0
class IOTests(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
        dt = datetime.datetime(1993, 8, 18, 14, 42, 36)
        self.cast = Cast(self.p, temp=self.temp, sal=self.sal, date=dt)
        self.ctd = CTDCast(self.p, temp=self.temp, sal=self.sal, date=dt)
        self.xbt = XBTCast(self.p, temp=self.temp, sal=self.sal, date=dt)
        self.collection = CastCollection(self.ctd, self.xbt, self.ctd)
        return

    def assertFilesEqual(self, f1, f2):
        f1.seek(0)
        f2.seek(0)
        s1 = f1.read()
        s2 = f2.read()
        self.assertEqual(s1, s2)
        return

    def test_save_text(self):
        try:
            f = StringIO()
            self.cast.save(f, binary=False)
        finally:
            f.close()

        try:
            f = StringIO()
            self.ctd.save(f, binary=False)
        finally:
            f.close()

        try:
            f = StringIO()
            self.xbt.save(f, binary=False)
        finally:
            f.close()
        return

    def test_save_binary(self):
        try:
            f = BytesIO()
            self.cast.save(f)
        finally:
            f.close()

        try:
            f = BytesIO()
            self.ctd.save(f)
        finally:
            f.close()

        try:
            f = BytesIO()
            self.xbt.save(f)
        finally:
            f.close()
        return

    def test_save_collection_text(self):
        try:
            f = StringIO()
            self.collection.save(f, binary=False)
        finally:
            f.close()
        return

    def test_save_collection_binary(self):
        try:
            f = BytesIO()
            self.collection.save(f)
        finally:
            f.close()
        return

    def test_save_zprimarykey(self):
        cast = Cast(np.arange(len(self.p)), temp=self.temp, sal=self.sal,
                    primarykey="z", properties={})
        f = BytesIO()
        try:
            cast.save(f)
        finally:
            f.close()
        return

    def test_load_text(self):
        cast = narwhal.read(os.path.join(DATADIR, "reference_cast_test.nwl"))
        ctd = narwhal.read(os.path.join(DATADIR, "reference_ctd_test.nwl"))
        xbt = narwhal.read(os.path.join(DATADIR, "reference_xbt_test.nwl"))
        self.assertEqual(cast, self.cast)
        self.assertEqual(ctd, self.ctd)
        self.assertEqual(xbt, self.xbt)
        return

    def test_load_binary(self):
        cast = narwhal.read(os.path.join(DATADIR, "reference_cast_test.nwz"))
        ctd = narwhal.read(os.path.join(DATADIR, "reference_ctd_test.nwz"))
        xbt = narwhal.read(os.path.join(DATADIR, "reference_xbt_test.nwz"))
        self.assertEqual(cast, self.cast)
        self.assertEqual(ctd, self.ctd)
        self.assertEqual(xbt, self.xbt)
        return

    def test_load_collection_text(self):
        coll = narwhal.read(os.path.join(DATADIR, "reference_coll_test.nwl"))
        self.assertEqual(coll, self.collection)
        return

    def test_load_collection_binary(self):
        coll = narwhal.read(os.path.join(DATADIR, "reference_coll_test.nwz"))
        self.assertEqual(coll, self.collection)
        return
Example #16
0
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