Esempio n. 1
0
def get_ctd_profile():
    """
    Load the ASCII CTD Data into an 'ambient.Profile' object.
    
    This function performs the steps in ./profile_from_ctd.py to read in the
    CTD data and create a Profile object.  This is the data set that will be
    used to demonstrate how to append data to a Profiile object.
    
    """
    # Get the path to the input file
    __location__ = os.path.realpath(os.path.join(os.getcwd(),
                                    os.path.dirname(__file__), 
                                    '../../tamoc/data'))
    dat_file = os.path.join(__location__,'ctd_BM54.cnv')
    
    # Load in the data using numpy.loadtxt
    raw = np.loadtxt(dat_file, comments = '#', skiprows = 175, 
                     usecols = (0, 1, 3, 8, 9, 10, 12))
    
    # Describe the organization of the data in raw.  
    var_names = ['temperature', 'pressure', 'wetlab_fluorescence', 'z', 
                 'salinity', 'density', 'oxygen']
    var_units = ['deg C', 'db', 'mg/m^3', 'm', 'psu', 'kg/m^3', 'mg/l']
    z_col = 3
    
    # Clean the profile to remove reversals in the depth coordinate
    data = ambient.extract_profile(raw, z_col, 50.0)
    
    # Convert the profile data to standard units in TAMOC
    profile, units = ambient.convert_units(data, var_units)
    
    # Create an empty netCDF4-classic dataset to store this CTD data
    __location__ = os.path.realpath(os.path.join(os.getcwd(),
                                    os.path.dirname(__file__), 
                                    '../../test/output'))
    nc_file = os.path.join(__location__,'BM54.nc')
    summary = 'Dataset created by profile_from_ctd in the ./bin directory' \
              + ' of TAMOC'
    source = 'R/V Brooks McCall, station BM54'
    sea_name = 'Gulf of Mexico'
    p_lat = 28.0 + 43.945 / 60.0
    p_lon = 360 - (88.0 + 22.607 / 60.0) 
    p_time = date2num(datetime(2010, 5, 30, 18, 22, 12), 
                      units = 'seconds since 1970-01-01 00:00:00 0:00', 
                      calendar = 'julian')
    nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, 
                              p_lon, p_time)
    
    # Insert the CTD data into the netCDF dataset
    comments = ['measured'] * len(var_names)
    nc = ambient.fill_nc_db(nc, profile, var_names, units, comments, z_col)
    
    # Create an ambient.Profile object for this dataset
    bm54 = ambient.Profile(nc, chem_names=['oxygen'])
    
    # Return the Profile object
    return bm54
Esempio n. 2
0
def build_profile(fname, z, T, S, ua):
    """
    docstring for build_profile
    
    """
    # Prepare the data for insertion in the netCDF database
    data = np.zeros((z.shape[0], 4))
    names = ['z', 'temperature', 'salinity', 'ua']
    units = ['m', 'K', 'psu', 'm/s']
    data[:,0] = z.transpose()
    data[:,1] = T.transpose()
    data[:,2] = S.transpose()
    data[:,3] = ua.transpose()
    
    # Create the netCDF file to store the data
    nc_file = fname
    summary = 'Test case for jet in crossflow'
    source = 'Laboratory data'
    sea_name = 'Laboratory'
    p_lat = 0.
    p_lon = 0.
    p_time = date2num(datetime(2014, 10, 15, 16, 0, 0), 
                      units = 'seconds since 1970-01-01 00:00:00 0:00',
                      calendar = 'julian')
    nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat,
                              p_lon, p_time)
    
    # Insert the data into the netCDF dataset
    comments = ['measured', 'measured', 'measured', 'measured']
    nc = ambient.fill_nc_db(nc, data, names, units, comments, 0)
    
    # Compute the pressure and insert into the netCDF dataset
    P = ambient.compute_pressure(data[:,0], data[:,1], data[:,2], 0)
    P_data = np.vstack((data[:,0], P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'], 
                            ['measured', 'computed'], 0)
    
    # Create an ambient.Profile object from this dataset
    profile = ambient.Profile(nc, chem_names='all')
    profile.close_nc()
    
    return profile
Esempio n. 3
0
def build_profile(fname, z, T, S, ua):
    """
    docstring for build_profile
    
    """
    # Prepare the data for insertion in the netCDF database
    data = np.zeros((z.shape[0], 4))
    names = ['z', 'temperature', 'salinity', 'ua']
    units = ['m', 'K', 'psu', 'm/s']
    data[:, 0] = z.transpose()
    data[:, 1] = T.transpose()
    data[:, 2] = S.transpose()
    data[:, 3] = ua.transpose()

    # Create the netCDF file to store the data
    nc_file = fname
    summary = 'Test case for jet in crossflow'
    source = 'Laboratory data'
    sea_name = 'Laboratory'
    p_lat = 0.
    p_lon = 0.
    p_time = date2num(datetime(2014, 10, 15, 16, 0, 0),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
    nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, p_lon,
                              p_time)

    # Insert the data into the netCDF dataset
    comments = ['measured', 'measured', 'measured', 'measured']
    nc = ambient.fill_nc_db(nc, data, names, units, comments, 0)

    # Compute the pressure and insert into the netCDF dataset
    P = ambient.compute_pressure(data[:, 0], data[:, 1], data[:, 2], 0)
    P_data = np.vstack((data[:, 0], P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'],
                            ['measured', 'computed'], 0)

    # Create an ambient.Profile object from this dataset
    profile = ambient.Profile(nc, chem_names='all')
    profile.close_nc()

    return profile
Esempio n. 4
0
def get_filled_nc_db(nc, data, symbols, units, comments, z_col, 
                     long_names, std_names):
    """
    Check that data written to a netCDF dataset has been stored correctly.
    
    """
    # Store the data in the netCDF dataset
    z_len = nc.variables['z'][:].shape
    nc = ambient.fill_nc_db(nc, data, symbols, units, comments, z_col)
    
    # Check that data and metadata were stored properly
    if len(symbols) == 1:
        data = np.atleast_2d(data).transpose()
    for i in range(len(symbols)):
        assert_array_almost_equal(nc.variables[symbols[i]][:], 
                                  data[:,i], decimal = 6)
        assert nc.variables[symbols[i]].long_name == long_names[i]
        assert nc.variables[symbols[i]].standard_name == std_names[i]
        assert nc.variables[symbols[i]].units == units[i]
        assert nc.variables[symbols[i]].comment == comments[i]
    
    # Send back the correctly-filled dataset
    return nc
Esempio n. 5
0
def get_filled_nc_db(nc, data, symbols, units, comments, z_col, 
                     long_names, std_names):
    """
    Check that data written to a netCDF dataset has been stored correctly.
    
    """
    # Store the data in the netCDF dataset
    z_len = nc.variables['z'][:].shape
    nc = ambient.fill_nc_db(nc, data, symbols, units, comments, z_col)
    
    # Check that data and metadata were stored properly
    if len(symbols) == 1:
        data = np.atleast_2d(data).transpose()
    for i in range(len(symbols)):
        assert_array_almost_equal(nc.variables[symbols[i]][:], 
                                  data[:,i], decimal = 6)
        assert nc.variables[symbols[i]].long_name == long_names[i]
        assert nc.variables[symbols[i]].standard_name == std_names[i]
        assert nc.variables[symbols[i]].units == units[i]
        assert nc.variables[symbols[i]].comment == comments[i]
    
    # Send back the correctly-filled dataset
    return nc
Esempio n. 6
0
def test_from_calcs():
    """
    Test the ambient data methods on synthetic profiles.
    
    This unit test creates synthetic data (e.g., profiles matching laboratory
    idealized conditions) and then uses this data to test the data 
    manipulation and storage methods in ambient.py.
    
    """
    # Create the synthetic temperature and salinity profiles
    z = np.array([0.0, 2.4])
    T = np.array([21.0, 20.0])
    S = np.array([0.0, 30.0])
    
    # Create an empty netCDF4-classic dataset to store the CTD information
    __location__ = os.path.realpath(os.path.join(os.getcwd(),
                                    os.path.dirname(__file__), 
                                    'output'))
    nc_file = os.path.join(__location__,'test_Lab.nc')
    summary = 'Py.Test test file'
    source = 'Synthetic profiles for idealized laboratory conditions'
    sea_name = 'None'
    p_lat = -999
    p_lon = -999 
    p_time = date2num(datetime(2013, 7, 12, 11, 54, 0), 
                      units = 'seconds since 1970-01-01 00:00:00 0:00', 
                      calendar = 'julian')
    nc = check_nc_db(nc_file, summary, source, sea_name, p_lat, 
                     p_lon, p_time)
    
    # Convert the temperature units
    T, T_units = get_units(T, ['deg C'], 1, 2, ['K'])
    
    # Fill the netCDF4-classic dataset with the data in these variables
    nc = get_filled_nc_db(nc, z, ['z'], ['m'], ['synthetic'], 0, 
                          ['depth below the water surface'], ['depth'])
    
    # Check that we cannot overwrite this existing z-data
    try:
        nc = ambient.fill_nc_db(nc, z, 'z', 'm', 'synthetic', 0)
    except ValueError:
        assert True is True
    else:
        assert True is False
    
    # Fill in the remaining data
    data = np.zeros((2, 3))
    data[:,0] = z
    data[:,1] = T
    data[:,2] = S
    nc = get_filled_nc_db(nc, data, ['z', 'temperature', 'salinity'], 
                          ['m', 'K', 'psu'], 
                          ['synthetic', 'synthetic', 'synthetic'], 0, 
                          ['depth below the water surface', 
                           'Absolute temperature', 'Practical salinity'], 
                          ['depth', 'temperature', 'salinity'])
    
    # Calculate and insert the pressure data
    P = ambient.compute_pressure(data[:,0], data[:,1], data[:,2], 0)
    P_data = np.vstack((data[:,0], P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'], 
                            ['measured', 'computed'], 0)
    
    # Create and test a Profile object for this dataset.
    lab = get_profile_obj(nc, [], [])
    
    # Close down the pipes to the netCDF dataset files
    lab.nc.close()
Esempio n. 7
0
def test_from_txt():
    """
    Test the ambient data methods on simple text files.  
    
    This unit test reads in the text files ./data/C.dat and 
    ./data/T.dat using `numpy.loadtxt` and then uses this data to test 
    the data manipulation and storage methods in ambient.py.
    
    """
    # Get a platform-independent path to the datafile
    __location__ = os.path.realpath(os.path.join(os.getcwd(),
                                    os.path.dirname(__file__), 
                                    '../tamoc/data'))
    cdat_file = os.path.join(__location__,'C.dat')
    tdat_file = os.path.join(__location__,'T.dat')
    
    # Load in the raw data using np.loadtxt
    C_raw = np.loadtxt(cdat_file, comments = '%')
    T_raw = np.loadtxt(tdat_file, comments = '%')
    
    # Clean the profile to remove depth reversals
    C_data = get_profile(C_raw, 1, 25, None, 0., 1.0256410e+01, 8.0000000e+02, 
        34, 2)
    T_data = get_profile(T_raw, 1, 25, None, 0., 1.0831721e+01, 7.9922631e+02, 
        34, 2)
    
    # Convert the data to standard units
    C_data, C_units = get_units(C_data, ['psu', 'm'], 34, 2, ['psu', 'm'])
    T_data, T_units = get_units(T_data, ['deg C', 'm'], 34, 2, ['K', 'm'])
    
    # Create an empty netCDF4-classic dataset to store the CTD information
    __location__ = os.path.realpath(os.path.join(os.getcwd(),
                                    os.path.dirname(__file__), 
                                    'output'))
    nc_file = os.path.join(__location__,'test_DS.nc')
    summary = 'Py.Test test file'
    source = 'Profiles from the SINTEF DeepSpill Report'
    sea_name = 'Norwegian Sea'
    p_lat = 64.99066
    p_lon = 4.84725 
    p_time = date2num(datetime(2000, 6, 27, 12, 0, 0), 
                      units = 'seconds since 1970-01-01 00:00:00 0:00', 
                      calendar = 'julian')
    nc = check_nc_db(nc_file, summary, source, sea_name, p_lat, 
                     p_lon, p_time)
    
    # Fill the netCDF4-classic dataset with the data in the salinity profile
    symbols = ['salinity', 'z']
    comments = ['measured', 'measured']
    long_names = ['Practical salinity', 'depth below the water surface']
    std_names = ['salinity', 'depth']
    nc = get_filled_nc_db(nc, C_data, symbols, C_units, comments, 1, 
                            long_names, std_names)
    
    # Because the temperature data will be interpolated to the vertical 
    # coordinates in the salinity profile, insert the data and test that 
    # insertion worked correctly by hand    
    symbols = ['temperature', 'z']
    comments = ['measured', 'measured']
    long_names = ['Absolute temperature', 'depth below the water surface']
    std_names = ['temperature', 'depth']
    nc = ambient.fill_nc_db(nc, T_data, symbols, T_units, comments, 1)
    assert_array_almost_equal(nc.variables['z'][:], 
        C_data[:,1], decimal = 6)
    z = nc.variables['z'][:]
    T = nc.variables['temperature'][:]
    f = interp1d(z, T)
    for i in range(T_data.shape[0]):
        assert_approx_equal(T_data[i,0], f(T_data[i,1]), significant = 5)
    assert nc.variables['temperature'].comment == comments[0]
    
    # Calculate and insert the pressure data
    z = nc.variables['z'][:]
    T = nc.variables['temperature'][:]
    S = nc.variables['salinity'][:]
    P = ambient.compute_pressure(z, T, S, 0)
    P_data = np.vstack((z, P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'], 
                            ['measured', 'computed'], 0)
    
    # Test the Profile object 
    ds = get_profile_obj(nc, [], [])
    
    # Close down the pipes to the netCDF dataset files
    ds.nc.close()
Esempio n. 8
0
    def get_profile(self, nc_name, fname, u_a, v_a, w_a, depths):
        """
        Read in the ambient CTD data

        Read in the CTD data specified by API for all test cases.  Append the
        velocity information to the CTD file.

        Parameters
        ----------
        nc_name : str
        Name to call the netCDF4 dataset.
        u_a : float
        Crossflow velocity for this test case (m/s).

        Returns
        -------
        profile : `ambient.Profile` object
        Returns an `ambient.Profile` object of the ambient CTD and velocity
        information

        """
        # Get the ambient CTD data
        names = ['z', 'temperature', 'salinity', 'oxygen']
        units = ['m', 'deg C', 'psu', 'mmol/m^3']
        data = np.loadtxt(fname, comments='%')

        # Convert the data to standard units
        M_o2 = 31.9988 / 1000.  # kg/mol
        data[:, 3] = data[:, 3] / 1000. * M_o2
        units[3] = 'kg/m^3'
        data, units = ambient.convert_units(data, units)

        # Create an empty netCDF4 dataset to store the CTD dat
        summary = 'Global horizontal mean hydrographic and oxygen data'
        source = 'Taken from page 226 of Sarmiento and Gruber'
        sea_name = 'Global'
        p_lat = 0.
        p_lon = 0.
        p_time = date2num(datetime(1998, 1, 1, 1, 0, 0),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
        nc = ambient.create_nc_db(nc_name, summary, source, sea_name, p_lat,
                                  p_lon, p_time)

        # Insert the data into the netCDF dataset
        comments = ['average', 'average', 'average', 'average']
        nc = ambient.fill_nc_db(nc, data, names, units, comments, 0)

        # Compute the pressure and insert into the netCDF dataset
        P = ambient.compute_pressure(data[:, 0], data[:, 1], data[:, 2], 0)
        P_data = np.vstack((data[:, 0], P)).transpose()
        nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'],
                                              ['average', 'computed'], 0)

        # Create an ambient.Profile object from this dataset
        profile = ambient.Profile(nc, chem_names='all')

        # Force the max depth to model
#        depths[-1] = profile.z_max

        # Add the crossflow velocity

        print '******************'
        print depths
        print '******************'

        u_crossflow = np.zeros((len(depths), 2))
        u_crossflow[:, 0] = depths
        if u_a.shape != depths.shape:
            u_crossflow[:, 1] = np.linspace(u_a[0], u_a[-1], len(depths))
        else:
            u_crossflow[:, 1] = u_a
        symbols = ['z', 'ua']
        units = ['m', 'm/s']
        comments = ['provided', 'provided']
        profile.append(u_crossflow, symbols, units, comments, 0)

        v_crossflow = np.zeros((len(depths), 2))
        v_crossflow[:, 0] = depths
        if v_a.shape != depths.shape:
            v_crossflow[:, 1] = np.linspace(v_a[0], v_a[-1], len(depths))
        else:
            v_crossflow[:, 1] = v_a
        symbols = ['z', 'va']
        units = ['m', 'm/s']
        comments = ['provided', 'provided']
        profile.append(v_crossflow, symbols, units, comments, 0)

        w_crossflow = np.zeros((len(depths), 2))
        w_crossflow[:, 0] = depths
        if w_a.shape != depths.shape:
            w_crossflow[:, 1] = np.linspace(w_a[0], w_a[-1], len(depths))
        else:
            w_crossflow[:, 1] = w_a
        symbols = ['z', 'wa']
        units = ['m', 'm/s']
        comments = ['provided', 'provided']
        profile.append(w_crossflow, symbols, units, comments, 0)

        # Finalize the profile (close the nc file)
        profile.close_nc()

        # Return the final profile
        return profile
Esempio n. 9
0
 nc_file = os.path.join(__location__,'BM54.nc')
 summary = 'Dataset created by profile_from_ctd in the ./bin directory' \
           + ' of TAMOC'
 source = 'R/V Brooks McCall, station BM54'
 sea_name = 'Gulf of Mexico'
 p_lat = 28.0 + 43.945 / 60.0
 p_lon = 360 - (88.0 + 22.607 / 60.0) 
 p_time = date2num(datetime(2010, 5, 30, 18, 22, 12), 
                   units = 'seconds since 1970-01-01 00:00:00 0:00', 
                   calendar = 'julian')
 nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, 
                           p_lon, p_time)
 
 # Insert the CTD data into the netCDF dataset
 comments = ['measured'] * len(var_names)
 nc = ambient.fill_nc_db(nc, profile, var_names, units, comments, z_col)
 
 # Create an ambient.Profile object for this dataset
 bm54 = ambient.Profile(nc, chem_names=['oxygen'], err=0.00001)
 
 # Close the netCDF dataset
 bm54.nc.close()
 
 # Since the netCDF file is now fully stored on the hard drive in the 
 # correct format, we can initialize an ambient.Profile object directly
 # from the netCDF file
 bm54 = ambient.Profile(nc_file, chem_names='all')
 
 # Plot the density profile using the interpolation function
 z = np.linspace(bm54.nc.variables['z'].valid_min, 
                 bm54.nc.variables['z'].valid_max, 250)
Esempio n. 10
0
    summary = 'Dataset created by profile_from_txt in the ./bin directory' \
              + ' of TAMOC'
    source = 'Digitized data from the average CTD profile in the SINTEF ' + \
             'DeepSpill Report'
    sea_name = 'Norwegian Sea'
    p_lat = 64.99066
    p_lon = 4.84725
    p_time = date2num(datetime(2000, 6, 27, 12, 0, 0),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
    nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, p_lon,
                              p_time)

    # Insert the CTD data into the netCDF dataset
    comments = ['digitized', 'digitized']
    nc = ambient.fill_nc_db(nc, C_profile, ['salinity', 'z'], C_units,
                            comments, 1)
    nc = ambient.fill_nc_db(nc, T_profile, ['temperature', 'z'], T_units,
                            comments, 1)

    # Calculate and insert the pressure data
    z = nc.variables['z'][:]
    T = nc.variables['temperature'][:]
    S = nc.variables['salinity'][:]
    P = ambient.compute_pressure(z, T, S, 0)
    P_data = np.vstack((z, P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'],
                            ['measured', 'computed'], 0)

    # Create an ambient.Profile object for this dataset
    ds = ambient.Profile(nc)
Esempio n. 11
0
def get_lake_data():
    """
    Create the netCDF dataset of CTD data for a lake simulation
    
    Creates the ambient.Profile object and netCDF dataset of CTD data for 
    a lake simualtion from the `./data/lake.dat` text file, digitized from
    the data in McGinnis et al. (2002) for Lake Hallwil.
    
    """
    
    # Read in the lake CTD data
    fname = '../../tamoc/data/lake.dat'
    raw = np.loadtxt(fname, skiprows=9)
    variables = ['z', 'temperature', 'salinity', 'oxygen']
    units = ['m', 'deg C', 'psu', 'kg/m^3']
    
    # Convert the units to mks
    profile, units = ambient.convert_units(raw, units)
    
    # Calculate the pressure data
    P = ambient.compute_pressure(profile[:,0], profile[:,1], profile[:,2], 0)
    profile = np.hstack((profile, np.atleast_2d(P).transpose()))
    variables = variables + ['pressure']
    units = units + ['Pa']
    
    # Set up a netCDF dataset object
    summary = 'Default lake.dat dataset provided by TAMOC'
    source = 'Lake CTD data digitized from figures in McGinnis et al. 2004'
    sea_name = 'Lake Hallwil, Switzerland'
    lat = 47.277166666666666
    lon = 8.217294444444445
    date = datetime(2002, 7, 18)
    t_units = 'seconds since 1970-01-01 00:00:00 0:00'
    calendar = 'julian'
    time = date2num(date, units=t_units, calendar=calendar)
    nc = ambient.create_nc_db('../../test/output/lake.nc', summary, source, 
                              sea_name, lat, lon, time)
    
    # Insert the measured data
    comments = ['digitized from measured data'] * 4
    comments = comments + ['computed from z, T, S']
    nc = ambient.fill_nc_db(nc, profile, variables, units, comments, 0)
    
    # Insert an additional column with data for nitrogen and argon equal to 
    # their saturation concentrations at the free surface.
    composition = ['nitrogen', 'oxygen', 'argon']
    yk = np.array([0.78084, 0.209476, 0.009684])
    air = dbm.FluidMixture(composition)
    m = air.masses(yk)
    Cs = air.solubility(m, profile[0,1], 101325., profile[0,2])
    N2 = np.zeros((profile.shape[0], 1))
    Ar = np.zeros((profile.shape[0], 1))
    N2 = N2 + Cs[0,0]
    Ar = Ar + Cs[0,2]
    z = np.atleast_2d(profile[:,0]).transpose()
    comments = ['calculated potential saturation value']*3
    nc = ambient.fill_nc_db(nc, np.hstack((z, N2, Ar)), 
                           ['z', 'nitrogen', 'argon'], 
                           ['m', 'kg/m^3', 'kg/m^3'], 
                           comments, 0)
    
    # Create an ambient.Profile object
    lake = ambient.Profile(nc, chem_names=['oxygen', 'nitrogen', 'argon'])
    lake.close_nc()
    
    # Return the Profile object
    return lake
Esempio n. 12
0
def get_ctd_profile():
    """
    Load the ASCII CTD Data into an `ambient.Profile` object.
    
    This function performs the steps in ./profile_from_ctd.py to read in the
    CTD data and create a Profile object.  This is the data set that will be
    used to demonstrate how to append data to a Profile object.
    
    """
    # Get the path to the input file
    __location__ = os.path.realpath(
        os.path.join(os.getcwd(), os.path.dirname(__file__),
                     '../../tamoc/data'))
    dat_file = os.path.join(__location__, 'ctd_BM54.cnv')

    # Load in the data using numpy.loadtxt
    raw = np.loadtxt(dat_file,
                     comments='#',
                     skiprows=175,
                     usecols=(0, 1, 3, 8, 9, 10, 12))

    # Describe the organization of the data in raw.
    var_names = [
        'temperature', 'pressure', 'wetlab_fluorescence', 'z', 'salinity',
        'density', 'oxygen'
    ]
    var_units = ['deg C', 'db', 'mg/m^3', 'm', 'psu', 'kg/m^3', 'mg/l']
    z_col = 3

    # Clean the profile to remove reversals in the depth coordinate
    data = ambient.extract_profile(raw, z_col, 50.0)

    # Convert the profile data to standard units in TAMOC
    profile, units = ambient.convert_units(data, var_units)

    # Create an empty netCDF4-classic dataset to store this CTD data
    __location__ = os.path.realpath(
        os.path.join(os.getcwd(), os.path.dirname(__file__),
                     '../../test/output'))
    nc_file = os.path.join(__location__, 'BM54.nc')
    summary = 'Dataset created by profile_from_ctd in the ./bin directory' \
              + ' of TAMOC'
    source = 'R/V Brooks McCall, station BM54'
    sea_name = 'Gulf of Mexico'
    p_lat = 28.0 + 43.945 / 60.0
    p_lon = 360 - (88.0 + 22.607 / 60.0)
    p_time = date2num(datetime(2010, 5, 30, 18, 22, 12),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
    nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, p_lon,
                              p_time)

    # Insert the CTD data into the netCDF dataset
    comments = ['measured'] * len(var_names)
    nc = ambient.fill_nc_db(nc, profile, var_names, units, comments, z_col)

    # Create an ambient.Profile object for this dataset
    bm54 = ambient.Profile(nc, chem_names=['oxygen'])

    # Return the Profile object
    return bm54
Esempio n. 13
0
 summary = 'Dataset created by profile_from_txt in the ./bin directory' \
           + ' of TAMOC'
 source = 'Digitized data from the average CTD profile in the SINTEF ' + \
          'DeepSpill Report'
 sea_name = 'Norwegian Sea'
 p_lat = 64.99066
 p_lon = 4.84725 
 p_time = date2num(datetime(2000, 6, 27, 12, 0, 0), 
                   units = 'seconds since 1970-01-01 00:00:00 0:00', 
                   calendar = 'julian')
 nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, 
                           p_lon, p_time)
 
 # Insert the CTD data into the netCDF dataset
 comments = ['digitized', 'digitized']
 nc = ambient.fill_nc_db(nc, C_profile, ['salinity', 'z'], C_units, 
                         comments, 1)
 nc = ambient.fill_nc_db(nc, T_profile, ['temperature', 'z'], T_units, 
                         comments, 1)
 
 # Calculate and insert the pressure data
 z = nc.variables['z'][:]
 T = nc.variables['temperature'][:]
 S = nc.variables['salinity'][:]
 P = ambient.compute_pressure(z, T, S, 0)
 P_data = np.vstack((z, P)).transpose()
 nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'], 
                         ['measured', 'computed'], 0)
 
 # Create an ambient.Profile object for this dataset
 ds = ambient.Profile(nc)
 
Esempio n. 14
0
    nc_file = os.path.join(__location__, 'BM54.nc')
    summary = 'Dataset created by profile_from_ctd in the ./bin directory' \
              + ' of TAMOC'
    source = 'R/V Brooks McCall, station BM54'
    sea_name = 'Gulf of Mexico'
    p_lat = 28.0 + 43.945 / 60.0
    p_lon = 360 - (88.0 + 22.607 / 60.0)
    p_time = date2num(datetime(2010, 5, 30, 18, 22, 12),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
    nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, p_lon,
                              p_time)

    # Insert the CTD data into the netCDF dataset
    comments = ['measured'] * len(var_names)
    nc = ambient.fill_nc_db(nc, profile, var_names, units, comments, z_col)

    # Create an ambient.Profile object for this dataset
    bm54 = ambient.Profile(nc, chem_names=['oxygen'], err=0.00001)

    # Close the netCDF dataset
    bm54.nc.close()

    # Since the netCDF file is now fully stored on the hard drive in the
    # correct format, we can initialize an ambient.Profile object directly
    # from the netCDF file
    bm54 = ambient.Profile(nc_file, chem_names='all')

    # Plot the density profile using the interpolation function
    z = np.linspace(bm54.nc.variables['z'].valid_min,
                    bm54.nc.variables['z'].valid_max, 250)
Esempio n. 15
0
def get_lake_data():
    """
    Create the netCDF dataset of CTD data for a lake simulation
    
    Creates the ambient.Profile object and netCDF dataset of CTD data for 
    a lake simualtion from the `./data/lake.dat` text file, digitized from
    the data in McGinnis et al. (2002) for Lake Hallwil.
    
    """

    # Read in the lake CTD data
    fname = '../../tamoc/data/lake.dat'
    raw = np.loadtxt(fname, skiprows=9)
    variables = ['z', 'temperature', 'salinity', 'oxygen']
    units = ['m', 'deg C', 'psu', 'kg/m^3']

    # Convert the units to mks
    profile, units = ambient.convert_units(raw, units)

    # Calculate the pressure data
    P = ambient.compute_pressure(profile[:, 0], profile[:, 1], profile[:, 2],
                                 0)
    profile = np.hstack((profile, np.atleast_2d(P).transpose()))
    variables = variables + ['pressure']
    units = units + ['Pa']

    # Set up a netCDF dataset object
    summary = 'Default lake.dat dataset provided by TAMOC'
    source = 'Lake CTD data digitized from figures in McGinnis et al. 2004'
    sea_name = 'Lake Hallwil, Switzerland'
    lat = 47.277166666666666
    lon = 8.217294444444445
    date = datetime(2002, 7, 18)
    t_units = 'seconds since 1970-01-01 00:00:00 0:00'
    calendar = 'julian'
    time = date2num(date, units=t_units, calendar=calendar)
    nc = ambient.create_nc_db('../../test/output/lake.nc', summary, source,
                              sea_name, lat, lon, time)

    # Insert the measured data
    comments = ['digitized from measured data'] * 4
    comments = comments + ['computed from z, T, S']
    nc = ambient.fill_nc_db(nc, profile, variables, units, comments, 0)

    # Insert an additional column with data for nitrogen and argon equal to
    # their saturation concentrations at the free surface.
    composition = ['nitrogen', 'oxygen', 'argon']
    yk = np.array([0.78084, 0.209476, 0.009684])
    air = dbm.FluidMixture(composition)
    m = air.masses(yk)
    Cs = air.solubility(m, profile[0, 1], 101325., profile[0, 2])
    N2 = np.zeros((profile.shape[0], 1))
    Ar = np.zeros((profile.shape[0], 1))
    N2 = N2 + Cs[0, 0]
    Ar = Ar + Cs[0, 2]
    z = np.atleast_2d(profile[:, 0]).transpose()
    comments = ['calculated potential saturation value'] * 3
    nc = ambient.fill_nc_db(nc, np.hstack(
        (z, N2, Ar)), ['z', 'nitrogen', 'argon'], ['m', 'kg/m^3', 'kg/m^3'],
                            comments, 0)

    # Create an ambient.Profile object
    lake = ambient.Profile(nc, chem_names=['oxygen', 'nitrogen', 'argon'])
    lake.close_nc()

    # Return the Profile object
    return lake
Esempio n. 16
0
def test_from_txt():
    """
    Test the ambient data methods on simple text files.

    This unit test reads in the text files ./data/C.dat and
    ./data/T.dat using `numpy.loadtxt` and then uses this data to test
    the data manipulation and storage methods in ambient.py.

    """
    cdat_file = os.path.join(DATA_DIR, 'C.dat')
    tdat_file = os.path.join(DATA_DIR, 'T.dat')

    # Load in the raw data using np.loadtxt
    C_raw = np.loadtxt(cdat_file, comments='%')
    T_raw = np.loadtxt(tdat_file, comments='%')

    # Clean the profile to remove depth reversals
    C_data = get_profile(C_raw, 1, 25, None, 0., 1.0256410e+01, 8.0000000e+02,
                         34, 2)
    T_data = get_profile(T_raw, 1, 25, None, 0., 1.0831721e+01, 7.9922631e+02,
                         34, 2)

    # Convert the data to standard units
    C_data, C_units = get_units(C_data, ['psu', 'm'], 34, 2, ['psu', 'm'])
    T_data, T_units = get_units(T_data, ['deg C', 'm'], 34, 2, ['K', 'm'])

    # Create an empty netCDF4-classic dataset to store the CTD information
    nc_file = os.path.join(OUTPUT_DIR, 'test_DS.nc')
    summary = 'Py.Test test file'
    source = 'Profiles from the SINTEF DeepSpill Report'
    sea_name = 'Norwegian Sea'
    p_lat = 64.99066
    p_lon = 4.84725
    p_time = date2num(datetime(2000, 6, 27, 12, 0, 0),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
    nc = check_nc_db(nc_file, summary, source, sea_name, p_lat, p_lon, p_time)

    # Fill the netCDF4-classic dataset with the data in the salinity profile
    symbols = ['salinity', 'z']
    comments = ['measured', 'measured']
    long_names = ['Practical salinity', 'depth below the water surface']
    std_names = ['salinity', 'depth']
    nc = get_filled_nc_db(nc, C_data, symbols, C_units, comments, 1,
                          long_names, std_names)

    # Because the temperature data will be interpolated to the vertical
    # coordinates in the salinity profile, insert the data and test that
    # insertion worked correctly by hand
    symbols = ['temperature', 'z']
    comments = ['measured', 'measured']
    long_names = ['Absolute temperature', 'depth below the water surface']
    std_names = ['temperature', 'depth']
    nc = ambient.fill_nc_db(nc, T_data, symbols, T_units, comments, 1)
    assert_array_almost_equal(nc.variables['z'][:], C_data[:, 1], decimal=6)
    z = nc.variables['z'][:]
    T = nc.variables['temperature'][:]
    f = interp1d(z, T)
    for i in range(T_data.shape[0]):
        assert_approx_equal(T_data[i, 0], f(T_data[i, 1]), significant=5)
    assert nc.variables['temperature'].comment == comments[0]

    # Calculate and insert the pressure data
    z = nc.variables['z'][:]
    T = nc.variables['temperature'][:]
    S = nc.variables['salinity'][:]
    P = ambient.compute_pressure(z, T, S, 0)
    P_data = np.vstack((z, P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'],
                            ['measured', 'computed'], 0)

    # Test the Profile object
    ds = get_profile_obj(nc, [], [])

    # Close down the pipes to the netCDF dataset files
    ds.nc.close()

    return ds
Esempio n. 17
0
def test_from_calcs():
    """
    Test the ambient data methods on synthetic profiles.

    This unit test creates synthetic data (e.g., profiles matching laboratory
    idealized conditions) and then uses this data to test the data
    manipulation and storage methods in ambient.py.

    """
    # Create the synthetic temperature and salinity profiles
    z = np.array([0.0, 2.4])
    T = np.array([21.0, 20.0])
    S = np.array([0.0, 30.0])

    # Create an empty netCDF4-classic dataset to store the CTD information
    nc_file = os.path.join(OUTPUT_DIR, 'test_Lab.nc')
    summary = 'Py.Test test file'
    source = 'Synthetic profiles for idealized laboratory conditions'
    sea_name = 'None'
    p_lat = -999
    p_lon = -999
    p_time = date2num(datetime(2013, 7, 12, 11, 54, 0),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
    nc = check_nc_db(nc_file, summary, source, sea_name, p_lat, p_lon, p_time)

    # Convert the temperature units
    T, T_units = get_units(T, ['deg C'], 1, 2, ['K'])

    # Fill the netCDF4-classic dataset with the data in these variables
    nc = get_filled_nc_db(nc, z, ['z'], ['m'], ['synthetic'], 0,
                          ['depth below the water surface'], ['depth'])

    # Check that we cannot overwrite this existing z-data
    try:
        nc = ambient.fill_nc_db(nc, z, 'z', 'm', 'synthetic', 0)
    except ValueError:
        assert True is True
    else:
        assert True is False

    # Fill in the remaining data
    data = np.zeros((2, 3))
    data[:, 0] = z
    data[:, 1] = T
    data[:, 2] = S
    nc = get_filled_nc_db(nc, data, ['z', 'temperature', 'salinity'],
                          ['m', 'K', 'psu'],
                          ['synthetic', 'synthetic', 'synthetic'], 0, [
                              'depth below the water surface',
                              'Absolute temperature', 'Practical salinity'
                          ], ['depth', 'temperature', 'salinity'])

    # Calculate and insert the pressure data
    P = ambient.compute_pressure(data[:, 0], data[:, 1], data[:, 2], 0)
    P_data = np.vstack((data[:, 0], P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'],
                            ['measured', 'computed'], 0)

    # Create and test a Profile object for this dataset.
    lab = get_profile_obj(nc, [], [])

    # Close down the pipes to the netCDF dataset files
    lab.nc.close()
Esempio n. 18
0
def create_ambient_profile(data,
                           labels,
                           units,
                           comments,
                           nc_name,
                           summary,
                           source,
                           sea_name,
                           p_lat,
                           p_lon,
                           p_time,
                           ca=[]):
    """
    Create an ambient Profile object from given data

    Create an ambient.Profile object using the given CTD and current data.
    This function performs some standard operations to this data (unit
    conversion, computation of pressure, insertion of concentrations for
    dissolved gases, etc.) and returns the working ambient.Profile object.
    The idea behind this function is to separate data manipulation and
    creation of the ambient.Profile object from fetching of the data itself.

    Parameters
    ----------
    data : np.array
        Array of the ambient ocean data to write to the CTD file.  The
        contents and dimensions of this data are specified in the labels
        and units lists, below.
    labels : list
        List of string names of each variable in the data array.
    units : list
        List of units as strings for each variable in the data array.
    comments : list
        List of comments as strings that explain the types of data in the
        data array.  Typical comments include 'measured', 'modeled', or
        'computed'.
    nc_name : str
        String containing the file path and file name to use when creating
        the netCDF4 dataset that will contain this data.
    summary : str
        String describing the simulation for which this data will be used.
    source : str
        String documenting the source of the ambient ocean data provided.
    sea_name : str
        NC-compliant name for the ocean water body as a string.
    p_lat : float
        Latitude (deg)
    p_lon : float
        Longitude, negative is west of 0 (deg)
    p_time : netCDF4 time format
        Date and time of the CTD data using netCDF4.date2num().
    ca : list, default=[]
        List of gases for which to compute a standard dissolved gas profile;
        choices are 'nitrogen', 'oxygen', 'argon', and 'carbon_dioxide'.

    Returns
    -------
    profile : ambient.Profile
        Returns an ambient.Profile object for manipulating ambient water
        column data in TAMOC.

    """
    # Convert the data to standard units
    data, units = ambient.convert_units(data, units)

    # Create an empty netCDF4-classic datast to store this CTD data
    nc = ambient.create_nc_db(nc_name, summary, source, sea_name, p_lat, p_lon,
                              p_time)

    # Put the CTD and current profile data into the ambient netCDF file
    nc = ambient.fill_nc_db(nc, data, labels, units, comments, 0)

    # Compute and insert the pressure data
    z = nc.variables['z'][:]
    T = nc.variables['temperature'][:]
    S = nc.variables['salinity'][:]
    P = ambient.compute_pressure(z, T, S, 0)
    P_data = np.vstack((z, P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'],
                            ['measured', 'computed'], 0)

    # Use this netCDF file to create an ambient object
    profile = ambient.Profile(
        nc, ztsp=['z', 'temperature', 'salinity', 'pressure', 'ua', 'va'])

    # Compute dissolved gas profiles to add to this dataset
    if len(ca) > 0:

        # Create a gas mixture object for air
        gases = ['nitrogen', 'oxygen', 'argon', 'carbon_dioxide']
        air = dbm.FluidMixture(gases)
        yk = np.array([0.78084, 0.20946, 0.009340, 0.00036])
        m = air.masses(yk)

        # Set atmospheric conditions
        Pa = 101325.

        # Compute the desired concentrations
        for i in range(len(ca)):

            # Initialize a dataset of concentration data
            conc = np.zeros(len(profile.z))

            # Compute the concentrations at each depth
            for j in range(len(conc)):

                # Get the local water column properties
                T, S, P = profile.get_values(
                    profile.z[j], ['temperature', 'salinity', 'pressure'])

                # Compute the gas solubility at this temperature and salinity
                # at the sea surface
                Cs = air.solubility(m, T, Pa, S)[0, :]

                # Adjust the solubility to the present depth
                Cs = Cs * seawater.density(T, S, P) / \
                    seawater.density(T, S, 101325.)

                # Extract the right chemical
                conc[j] = Cs[gases.index(ca[i])]

            # Add this computed dissolved gas to the Profile dataset
            data = np.vstack((profile.z, conc)).transpose()
            symbols = ['z', ca[i]]
            units = ['m', 'kg/m^3']
            comments = ['measured', 'computed from CTD data']
            profile.append(data, symbols, units, comments, 0)

    # Close the netCDF dataset
    profile.close_nc()

    # Return the profile object
    return profile
Esempio n. 19
0
    nc_file = os.path.join(__location__, 'Lab.nc')
    summary = 'Dataset created by profile_from_txt in the ./bin directory' \
              + ' of TAMOC'
    source = 'Synthetic data for idealized laboratory conditions'
    sea_name = 'None'
    p_lat = -999
    p_lon = -999
    p_time = date2num(datetime(2013, 7, 15, 20, 24, 0),
                      units='seconds since 1970-01-01 00:00:00 0:00',
                      calendar='julian')
    nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, p_lon,
                              p_time)

    # Insert the CTD data into the netCDF dataset
    comments = ['synthetic'] * 3
    nc = ambient.fill_nc_db(nc, profile, ['z', 'temperature', 'salinity'],
                            ['m', 'K', 'psu'], comments, 0)

    # Calculate and insert the pressure data
    z = nc.variables['z'][:]
    T = nc.variables['temperature'][:]
    S = nc.variables['salinity'][:]
    P = ambient.compute_pressure(z, T, S, 0)
    P_data = np.vstack((z, P)).transpose()
    nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'],
                            ['measured', 'computed'], 0)

    # Create an ambient.Profile object for this dataset
    lab = ambient.Profile(nc)

    # Close the netCDF dataset
    lab.nc.close()
Esempio n. 20
0
 nc_file = os.path.join(__location__,'Lab.nc')
 summary = 'Dataset created by profile_from_txt in the ./bin directory' \
           + ' of TAMOC'
 source = 'Synthetic data for idealized laboratory conditions'
 sea_name = 'None'
 p_lat = -999
 p_lon = -999 
 p_time = date2num(datetime(2013, 7, 15, 20, 24, 0), 
                   units = 'seconds since 1970-01-01 00:00:00 0:00', 
                   calendar = 'julian')
 nc = ambient.create_nc_db(nc_file, summary, source, sea_name, p_lat, 
                           p_lon, p_time)
 
 # Insert the CTD data into the netCDF dataset
 comments = ['synthetic'] * 3
 nc = ambient.fill_nc_db(nc, profile, ['z', 'temperature', 'salinity'], 
                         ['m', 'K', 'psu'], comments, 0)
 
 # Calculate and insert the pressure data
 z = nc.variables['z'][:]
 T = nc.variables['temperature'][:]
 S = nc.variables['salinity'][:]
 P = ambient.compute_pressure(z, T, S, 0)
 P_data = np.vstack((z, P)).transpose()
 nc = ambient.fill_nc_db(nc, P_data, ['z', 'pressure'], ['m', 'Pa'], 
                         ['measured', 'computed'], 0)
 
 # Create an ambient.Profile object for this dataset
 lab = ambient.Profile(nc)
 
 # Close the netCDF dataset
 lab.nc.close()