コード例 #1
0
ファイル: test_blowout.py プロジェクト: changks/tamoc
def get_ctd():
    """
    Provide the ambient CTD data
    
    Load the required CTD data from the ./test/output/test_BM54.nc dataset
    and include water currents.
    
    Returns
    -------
    profile : `ambient.Profile` object
        An `ambient.Profile` object containing the required CTD data and 
        currents for a `bent_plume_model` simulation.
    
    """
    # Get the CTD data from the requested file
    nc = test_sbm.make_ctd_file()
    profile = ambient.Profile(nc, chem_names='all')
    
    # Add the ambient currents
    z = profile.nc.variables['z'][:]
    ua = np.zeros(z.shape) + 0.09
    data = np.vstack((z, ua)).transpose()
    symbols = ['z', 'ua']
    units = ['m', 'm/s']
    comments = ['measured', 'arbitrary crossflow velocity']
    profile.append(data, symbols, units, comments, 0)
    profile.close_nc()
    
    # Return the profile object
    return profile
コード例 #2
0
ファイル: test_bpm.py プロジェクト: TonggangHan/tamoc
def get_profile():
    """
    Create an `ambient.Profile` object from a netCDF file

    Create the `ambient.Profile` object needed by the `bent_plume_model`
    simulation from the netCDF file `./test/output/test_bm54.nc`.  This
    function calls `test_sbm.make_ctd_file` to create the netCDF dataset
    before using it to create the `ambient.Profile` object.

    Returns
    -------
    profile : `ambient.Profile` object
        Return a profile object from the BM54 CTD data

    """
    # Get the netCDF file
    nc = test_sbm.make_ctd_file()

    # Create profile object
    profile = ambient.Profile(nc, chem_names='all')

    # Add crossflow
    ua = np.zeros(len(profile.z))
    for i in range(len(profile.z)):
        ua[i] = 0.15

    # Add this crossflow profile to the Profile dataset
    data = np.vstack((profile.z, ua)).transpose()
    symbols = ['z', 'ua']
    units = ['m', 'm/s']
    comments = ['measured', 'synthetic']
    profile.append(data, symbols, units, comments, 0)

    # Return a profile object
    return profile
コード例 #3
0
ファイル: model_share.py プロジェクト: changks/tamoc
def profile_from_model_savefile(nc, fname, ctdname=None):
    """
    Load the `ambient.Profile` data pointed to by the netCDF file
    
    Each netCDF model save file for the TAMOC suite models stores the file
    name and path to the ambient CTD data used in the simulation.  This 
    prevents the save files from having to encapsulate all of the ambient 
    CTD data with results for every simulation run.  This block of code
    looks for the ambient data and loads it into memory if found.
    
    Parameters
    ----------
    nc : `netCDF4.Dataset` object
        The netCDF dataset object containing the saved model simulation
    
    fname : str
        File name of the netCDF file.  This is used to get the complete
        path to the current directory so that the Profile data can be found.
    
    Returns
    -------
    profile : `ambient.Profile` object
        The profile data as an `ambient.Profile` object.
    
    See Also
    --------
    single_bubble_model.Model.save_sim, stratified_plume_model.Mode.save_sim,
    bent_plume_model.Model.save_sim
    
    Notes
    -----
    If the profile data are not found, a message is echoed to the command
    line.  No other warnings or errors are thrown.
    
    """
    try:
        # Try to locate and load in the profile data
        nc_path = os.path.normpath(os.path.join(os.getcwd(), \
                                   os.path.dirname(fname)))
        if ctdname is not None:
            prf_path = os.path.normpath(os.path.join(nc_path, ctdname))
        else:
            prf_path = os.path.normpath(os.path.join(nc_path, nc.summary))
        amb_data = Dataset(prf_path)
        profile = ambient.Profile(amb_data, chem_names='all')
        profile.close_nc()

    except RuntimeError:
        # Tell user that profile data read failed
        message = ['File not found: %s' % prf_path]
        message.append(' ... Continuing without profile data')
        warn(''.join(message))
        profile = None

    # Send back the final profile object
    return profile
コード例 #4
0
ファイル: test_ambient.py プロジェクト: changks/tamoc
def test_profile_deeper():
    """
    Test the methods to compute buoyancy_frequency and to extend a CTD profile
    to greater depths.  We just test the data from ctd_bm54.cnv since these
    methods are independent of the source of data.
    
    """
    # Make sure the netCDF file for the ctd_BM54.cnv is already created by 
    # running the test file that creates it.  
    test_from_ctd()
    
    # Get a Profile object from this dataset
    __location__ = os.path.realpath(os.path.join(os.getcwd(),
                                    os.path.dirname(__file__), 
                                    'output'))
    nc_file = os.path.join(__location__,'test_BM54.nc')
    ctd = ambient.Profile(nc_file, chem_names=['oxygen'])
    
    # Compute the buoyancy frequency at 1500 m and verify that the result is 
    # correct
    N = ctd.buoyancy_frequency(1529.789, h=0.01)
    assert_approx_equal(N, 0.00061463758327116565, significant=6)
    
    # Record a few values to check after running the extension method
    T0, S0, P0, o20 = ctd.get_values(1000., ['temperature', 'salinity', 
                                     'pressure', 'oxygen'])
    z0 = ctd.data[:,0]
    
    # Extend the profile to 2500 m
    nc_file = os.path.join(__location__,'test_BM54_deeper.nc')
    ctd.extend_profile_deeper(2500., nc_file)
    
    # Check if the original data is preserved
    T1, S1, P1, o21 = ctd.get_values(1000., ['temperature', 'salinity', 
                                     'pressure', 'oxygen'])
    z1 = ctd.data[:,0]
    
    # Make sure the results are still right
    assert_approx_equal(T1, T0, significant=6)
    assert_approx_equal(S1, S0, significant=6)
    assert_approx_equal(P1, P0, significant=6)
    assert_approx_equal(o21, o20, significant=6)
    assert z1.shape[0] > z0.shape[0]
    assert z1[-1] == 2500.
    # Note that the buoyancy frequency shifts very slightly because density
    # is not linearly proportional to salinity.  Nonetheless, the results are
    # close to what we want, so this method of extending the profile works
    # adequately.
    N = ctd.buoyancy_frequency(1500.)
    assert_approx_equal(N, 0.0006377576016247663, significant=6)
    N = ctd.buoyancy_frequency(2500.)
    assert_approx_equal(N, 0.0006146292892002274, significant=6)
    
    ctd.close_nc()
コード例 #5
0
ファイル: test_psm.py プロジェクト: TonggangHan/tamoc
def get_blowout_model():
    """
    Compute the inputs defining a synthetic blowout

    Create the `ambient.Profile` object, `dbm.FluidMixture` object, and
    other parameters defining a synthetic blowout scenario.

    Returns
    -------
    profile : `ambient.Profile` object
        Profile containing ambient CTD data
    oil : `dbm.FluidMixture` object
        A `dbm.FluidMixture` object that contains the chemical description
        of an oil mixture.
    mass_flux : ndarray
        An array of mass fluxes (kg/s) of each pseudo-component in the live-
        oil composition.
    z0 : float
        Release point of a synthetic blowout (m)
    Tj : float
        Temperature of the released fluids (K)

    """
    # Get the CTD data from the requested file
    nc = test_sbm.make_ctd_file()
    profile = ambient.Profile(nc, chem_names='all')
    profile.close_nc()

    # Define an oil substance to use
    substance = {
        'composition': [
            'n-hexane', '2-methylpentane', '3-methylpentane', 'neohexane',
            'n-heptane', 'benzene', 'toluene', 'ethylbenzene', 'n-decane'
        ],
        'masses':
        np.array([0.04, 0.07, 0.08, 0.09, 0.11, 0.12, 0.15, 0.18, 0.16])
    }

    # Define the atmospheric gases to track
    ca = ['oxygen']

    # Define the oil flow rate, gas to oil ratio, and orifice size
    q_oil = 20000.  # bbl/d
    gor = 500.  # ft^3/bbl at standard conditions
    z0 = 100.  # release depth (m)
    Tj = profile.get_values(z0, 'temperature')  # release temperature (K)

    # Import the oil with the desired gas to oil ratio
    oil, mass_flux = dbm_utilities.get_oil(substance, q_oil, gor, ca)

    return (profile, oil, mass_flux, z0, Tj)
コード例 #6
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
コード例 #7
0
ファイル: test_spm.py プロジェクト: changks/tamoc
def get_profile():
    """
    Create an `ambient.Profile` object from a netCDF file
    
    Create the `ambient.Profile` object needed by the `stratified_plume_model`
    simulation from the netCDF file `./test/output/test_bm54.nc`.  This 
    function calls `test_sbm.make_ctd_file` to create the netCDF dataset 
    before using it to create the `ambient.Profile` object.
    
    Returns
    -------
    profile : `ambient.Profile` object
        Return a profile object from the BM54 CTD data
    
    """
    # Get the netCDF file
    nc = test_sbm.make_ctd_file()

    # Return a profile object with all available chemicals in the CTD data
    return ambient.Profile(nc, chem_names='all')
コード例 #8
0
def test_using_numpy():
    """
    Test the ambient data methods using only numpy

    This unit test repeats the tests in `test_from_txt()`, but using only
    the `numpy` array part of the `Profile` object instead of a netCDF
    dataset.

    """
    # Get the profile objuect using netCDF datasets
    net_profile = test_from_txt()

    # Get a platform-independent path to the datafile
    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 numpy array to hold depth and salinity
    var_names = ['depth', 'salinity']
    var_units = ['m', 'psu']
    data = np.zeros((C_data.shape[0], 3))
    data[:, 0] = C_data[:, 1]
    data[:, 2] = C_data[:, 0]

    # Add the temperature data using the existing depth data
    data = ambient.add_data(data, 1, 'temperature', T_data,
                            ['temperature', 'z'], T_units,
                            ['measured', 'measured'], 1)

    z = data[:, 0]
    T = data[:, 1]
    S = data[:, 2]
    P = ambient.compute_pressure(z, T, S, 0)
    P_data = np.vstack((z, P)).transpose()
    data = ambient.add_data(data, 3, 'pressure', P_data, ['z', 'pressure'],
                            ['m', 'Pa'], ['measured', 'measured'], 0)

    # Create the profile object
    ztsp = ['z', 'temperature', 'salinity', 'pressure']
    ztsp_units = ['m', 'K', 'psu', 'Pa']
    ds = ambient.Profile(data,
                         ztsp,
                         None,
                         0.01,
                         ztsp_units,
                         None,
                         current=np.array([0., 0.]),
                         current_units=['m/s', 'm/s'])

    # Add currents
    currents = np.array([[0, 0.1, 0.05], [500, 0.1, 0.05]])
    var_names = ['z', 'u', 'v']
    var_units = ['m', 'm/s', 'm/s']
    ds.append(currents, var_names, var_units, 0)

    # Check if the two objects are equal
    check_net_numpy(net_profile, ds, currents)

    return ds
コード例 #9
0
def get_profile_obj(nc, chem_names, chem_units):
    """
    Check that an ambient.Profile object is created correctly and that the
    methods operate as expected.

    """
    if isinstance(chem_names, str):
        chem_names = [chem_names]
    if isinstance(chem_units, str):
        chem_units = [chem_units]

    # Create the profile object
    prf = ambient.Profile(nc, chem_names=chem_names)

    # Check the chemical names and units are correct
    for i in range(len(chem_names)):
        assert prf.chem_names[i] == chem_names[i]
    assert prf.nchems == len(chem_names)

    # Check the error criteria on the interpolator
    assert prf.err == 0.01

    # Check the get_units method
    name_list = ['temperature', 'salinity', 'pressure'] + chem_names
    unit_list = ['K', 'psu', 'Pa'] + chem_units
    for i in range(len(name_list)):
        assert prf.get_units(name_list[i])[0] == unit_list[i]
    units = prf.get_units(name_list)
    for i in range(len(name_list)):
        assert units[i] == unit_list[i]

    # Check the interpolator function ...
    # Pick a point in the middle of the raw dataset and read off the depth
    # and the values of all the variables
    nz = prf.nc.variables['z'].shape[0] // 2
    z = prf.z[nz]
    y = prf.y[nz, :]
    # Get an interpolated set of values at this same elevation
    yp = prf.f(z)
    # Check if the results are within the level of error expected by err
    for i in range(len(name_list)):
        assert np.abs((yp[i] - y[i]) / yp[i]) <= prf.err

    # Next, check that the variables returned by the get_values function are
    # the variables we expect
    Tp, Sp, Pp = prf.get_values(z, ['temperature', 'salinity', 'pressure'])
    T = prf.nc.variables['temperature'][nz]
    S = prf.nc.variables['salinity'][nz]
    P = prf.nc.variables['pressure'][nz]
    assert np.abs((Tp - T) / T) <= prf.err
    assert np.abs((Sp - S) / S) <= prf.err
    assert np.abs((Pp - P) / P) <= prf.err
    if prf.nchems > 0:
        c = np.zeros(prf.nchems)
        cp = np.zeros(prf.nchems)
        for i in range(prf.nchems):
            c[i] = prf.nc.variables[chem_names[i]][nz]
            cp[i] = prf.get_values(z, chem_names[i])
            assert np.abs((cp[i] - c[i]) / c[i]) <= prf.err

    # Test the append() method by inserting the temperature data as a new
    # profile, this time in degrees celsius using the variable name temp
    n0 = prf.nchems
    z = prf.nc.variables['z'][:]
    T = prf.nc.variables['temperature'][:]
    T_degC = T - 273.15
    assert_array_almost_equal(T_degC + 273.15, T, decimal=6)
    data = np.vstack((z, T_degC)).transpose()
    symbols = ['z', 'temp']
    units = ['m', 'deg C']
    comments = ['measured', 'identical to temperature, but in deg C']
    prf.append(data, symbols, units, comments, 0)

    # Check that the data were inserted correctly
    Tnc = prf.nc.variables['temp'][:]
    assert_array_almost_equal(Tnc, T_degC, decimal=6)
    assert prf.nc.variables['temp'].units == 'deg C'

    # Check that get_values works correctly with vector inputs for depth
    depths = np.linspace(prf.nc.variables['z'].valid_min,
                         prf.nc.variables['z'].valid_max, 100)
    Temps = prf.get_values(depths, ['temperature', 'temp'])
    for i in range(len(depths)):
        assert_approx_equal(Temps[i, 0], Temps[i, 1] + 273.15, significant=6)

    # Make sure the units are returned correctly
    assert prf.get_units('temp')[0] == 'deg C'
    assert prf.nc.variables['temp'].units == 'deg C'

    # Check that temp is now listed as a chemical
    assert prf.nchems == n0 + 1
    assert prf.chem_names[-1] == 'temp'

    # Test the API for calculating the buoyancy frequency (note that we do
    # not check the result, just that the function call does not raise an
    # error)
    N = prf.buoyancy_frequency(depths)
    N = prf.buoyancy_frequency(depths[50], h=0.1)

    # Send back the Profile object
    return prf
コード例 #10
0
ファイル: lake_bub.py プロジェクト: dissanayakeal/tamoc
    # Create an ambient.Profile object
    lake = ambient.Profile(nc, chem_names=['oxygen', 'nitrogen', 'argon'])
    lake.close_nc()

    # Return the Profile object
    return lake


if __name__ == '__main__':

    # Get the ambient CTD profile data
    nc = '../../test/output/lake.nc'
    try:
        # Open the lake dataset as a Profile object if it exists
        lake = ambient.Profile(nc, chem_names=['oxygen', 'nitrogen', 'argon'])

    except RuntimeError:
        # Create the lake netCDF dataset and get the Profile object
        lake = get_lake_data()

    # Create the stratified plume model object
    spm = stratified_plume_model.Model(lake)

    # Create the dispersed phase particles
    composition = ['oxygen', 'nitrogen', 'argon']
    yk = np.array([1.0, 0., 0.])
    o2 = dbm.FluidParticle(composition, isair=True)
    z0 = 46.
    bubbles = []
コード例 #11
0
def get_sim_data():
    """
    Get the input data to the `params.Scales` object
    
    Create an `ambient.Profile` object and a list of 
    `stratified_plume_model.Particle` objects as the required input for 
    the `params.Scales` object.  
    
    Returns
    -------
    profile : `ambient.Profile` object
        profile object from the BM54 CTD data
    disp_phases: list
        list of `stratified_plume_model.Particle` objects describing the 
        blowout dispersed phases.
    z0 : float
        depth at the plume model origin (m)
    
    """
    # Get the netCDF file
    nc = test_sbm.make_ctd_file()

    # Create a profile object with all available chemicals in the CTD data
    profile = ambient.Profile(nc, chem_names='all')

    # Create the stratified plume model object
    spm = stratified_plume_model.Model(profile)

    # Set the release conditions
    T0 = 273.15 + 35.  # Release temperature in K
    R = 0.15  # Radius of leak source in m

    # Create the gas phase particles
    composition = ['methane', 'ethane', 'propane', 'oxygen']
    yk = np.array([0.93, 0.05, 0.02, 0.0])
    gas = dbm.FluidParticle(composition)
    z0 = 1000.
    disp_phases = []

    # Larger free gas bubbles
    mb0 = 8.  # total mass flux in kg/s
    de = 0.025  # bubble diameter in m
    lambda_1 = 0.85
    disp_phases.append(
        stratified_plume_model.particle_from_mb0(profile, z0, gas, yk, mb0, de,
                                                 lambda_1, T0))

    # Smaller free gas bubbles (note, it is not necessary to have more than
    # one bubble size)
    mb0 = 2.  # total mass flux in kg/s
    de = 0.0075  # bubble diameter in m
    lambda_1 = 0.9
    disp_phases.append(
        stratified_plume_model.particle_from_mb0(profile, z0, gas, yk, mb0, de,
                                                 lambda_1, T0))

    # Liquid hydrocarbon.  This could either be a dissolving phase (mixture
    # of liquid phases) or an inert phase.  We demonstrate here the simple
    # case of an inert oil phase
    oil = dbm.InsolubleParticle(True,
                                True,
                                rho_p=890.,
                                gamma=30.,
                                beta=0.0007,
                                co=2.90075e-9)
    mb0 = 10.  # total mass flux in kg/s
    de = 0.004  # bubble diameter in m
    lambda_1 = 0.9
    disp_phases.append(
        stratified_plume_model.particle_from_mb0(profile, z0, oil,
                                                 np.array([1.]), mb0, de,
                                                 lambda_1, T0))

    # Return the simulation data
    return (profile, disp_phases, z0)
コード例 #12
0
ファイル: blowout.py プロジェクト: TonggangHan/tamoc
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
コード例 #13
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
コード例 #14
0
    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)

    rho = np.zeros(z.shape)
    T = np.zeros(z.shape)
コード例 #15
0
ファイル: lake_bub.py プロジェクト: dissanayakeal/tamoc
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
コード例 #16
0
    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)

    # Close the netCDF dataset
    ds.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
    ds = ambient.Profile(nc_file, chem_names='all')

    # Plot the density profile using the interpolation function
    z = np.linspace(ds.nc.variables['z'].valid_min,
                    ds.nc.variables['z'].valid_max, 250)
    rho = np.zeros(z.shape)
    tsp = ds.get_values(z, ['temperature', 'salinity', 'pressure'])
    for i in range(len(z)):
コード例 #17
0
ファイル: blowout.py プロジェクト: TonggangHan/tamoc
def get_ambient_profile(water, current, **kwargs):
    """
    Create an `ambient.Profile` object from the given ambient data

    Based on the water column information provided, make an appropriate
    choice and create the `ambient.Profile` object required for a `tamoc`
    simulation.

    Parameters
    ----------
    water : various
        Data describing the ambient water temperature and salinity profile.
        See Notes below for details.
    current : various
        Data describing the ambient current velocity profile.  See Notes
        below for details.
    **kwargs : dict
        Dictionary of optional keyword arguments that can be used when
        creating an ambient.Profile object from a text file.  Optional
        arguments include:

        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 dissolved atmospheric gases to include in the ambient
            ocean data as a derived concentration; choices are 'nitrogen',
            'oxygen', 'argon', and 'carbon_dioxide'.

        If any of these arguments are not passed, default values will be
        assigned by this function.

    Notes
    -----
    The `water` variable contains information about the ambient temperature
    and salinity profile.  Possible choices for `water` include the following:

    water : None
        Indicates that we have no information about the ambient temperature
        or salinity.  In this case, the model will import data for the
        world-ocean average.
    water : dict
        If we only know the water temperature and salinity at the surface,
        this may be passed through a dictionary with keywords `temperature`
        and `salinity`.  In this case, the model will import data for the
        world-ocean average and adjust the data to have the given temperature
        and salinity at the surface.
    water : 'netCDF4.Dataset' object
        If a 'netCDF4.Dataset' object already contains the ambient CTD
        data in a format appropriate for the `ambient.Profile` object, then
        this can be passed.  In this case, it is assumed that the dataset
        includes the currents; hence, the `currents` variable will be
        ignored.
    water : `ambient.Profile` object
        If we already created our own ambient Profile object, then this
        object can be used directly.
    water = str
        If we stored the water column profile in a file, we may provide the
        file path to this file via the string stored in water. If this string
        ends in '.nc', it is assumed that this file contains a netCDF4
        dataset. Otherwise, this file should contain columns in the following
        order: depth (m), temperature (deg C), salinity (psu), velocity in
        the x-direction (m/s), velocity in the y-direction (m/s). Since this
        option includes the currents, the current variable will be ignored in
        this case. A comment string of `#` may be used in the text file.

    The `current` variable contains information about the ambient current
    profile.  Possible choices for `current` include the following:

    current : float
        This is assumed to be the current velocity along the x-axis and will
        be uniform over the depth
    current : ndarray
        This is assumed to contain the current velocity in the x- and y- (and
        optionally also z-) directions. If this is a one-dimensional array,
        then these currents will be assumed to be uniform over the depth. If
        this is a multi-dimensional array, then these values as assumed to
        contain a profile of data, with the depth (m) as the first column of
        data.

    """
    NoneType = type(None)
    done = False

    # Extract the temperature and salinity data
    if isinstance(water, NoneType):

        # Use the world-ocean average T(z) and S(z)
        data = None

    if isinstance(water, dict):

        # Get the water temperature and salinity at the surface
        Ts = water['temperature']
        Ss = water['salinity']

        # Create a data array of depth, temperature, and salinity
        data = np.array([0., Ts, Ss])

    if isinstance(water, Dataset):

        # A netCDF4 Dataset containing all of the profile data is stored
        # in water.  Use that to create the Profile object
        profile = ambient.Profile(water)
        done = True

    if isinstance(water, ambient.Profile):
        profile = water
        done = True

    elif isinstance(water, str) or isinstance(water, unicode):

        if water[-3:] == '.nc':

            # Water contains a path to a netCDF4 dataset.  Use this to
            # create the Profile object
            profile = ambient.Profile(water)
            done = True

        else:

            # This must be a relative path to a text file
            fname = water
            x0 = np.array([0., 0.])
            try:
                ca = kwargs['ca']
            except:
                ca = []
            try:
                summary = kwargs['summary']
            except:
                summary = 'CTD text file stored in:  ' + water
            try:
                source = kwargs['source']
            except:
                source = 'tamoc.blowout.get_ctd_from_txt()'
            try:
                sea_name = kwargs['sea_name']
            except:
                sea_name = 'Text File'
            try:
                p_lon = kwargs['p_lon']
            except:
                p_lon = x0[0]
            try:
                p_lat = kwargs['p_lat']
            except:
                p_lat = x0[1]
            try:
                p_time = kwargs['p_time']
            except:
                p_time = date2num(
                    datetime.now(),
                    units='seconds since 1970-01-01 00:00:00 0:00',
                    calendar='julian')

            profile = get_ctd_from_txt(fname, summary, source, sea_name, p_lat,
                                       p_lon, p_time, ca)
            done = True

    # Create the `ambient.Profile` object
    if not done:
        profile = ambient.Profile(data, current=current, current_units='m/s')

    # Returen the profile
    return profile
コード例 #18
0
ファイル: profile_from_lab.py プロジェクト: changks/tamoc
    # 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()

    # 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
    lab = ambient.Profile(nc_file)

    # Plot the density profile using the interpolation function
    z = np.linspace(lab.nc.variables['z'].valid_min,
                    lab.nc.variables['z'].valid_max, 250)
    rho = np.zeros(z.shape)
    tsp = lab.get_values(z, ['temperature', 'salinity', 'pressure'])
    for i in range(len(z)):
コード例 #19
0
ファイル: spm_blowout_sim.py プロジェクト: changks/tamoc
from tamoc import ambient
from tamoc import dbm
from tamoc import stratified_plume_model

from datetime import datetime
from netCDF4 import date2num

import numpy as np

if __name__ == '__main__':

    # Get the ambient CTD profile data
    nc = '../../test/output/test_BM54.nc'
    try:
        # Open the lake dataset as a Profile object if it exists
        ctd = ambient.Profile(nc, chem_names='all')

    except RuntimeError:
        # Tell the user to create the dataset
        print('CTD data not available; run test cases in ./test first.')

    # Create the stratified plume model object
    spm = stratified_plume_model.Model(ctd)

    # Set the release conditions
    T0 = 273.15 + 35.  # Release temperature in K
    R = 0.15  # Radius of leak source in m

    # Create the gas phase particles
    composition = ['methane', 'ethane', 'propane', 'oxygen']
    yk = np.array([0.93, 0.05, 0.02, 0.0])
コード例 #20
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
コード例 #21
0
    nc_file = os.path.join(__location__, 'roms.nc')

    # Select the indices to the point in the ROMS output where we want to
    # extract the profile
    t_idx = 0
    j_idx = 400
    i_idx = 420

    # Open the ROMS output file and create the TAMOC input file
    (nc, dat_file) = ambient.get_nc_db_from_roms(dat_file, nc_file, t_idx,
                                                 j_idx, i_idx,
                                                 ['dye_01', 'dye_02'])
    dat_file.close()

    # Create an ambient.Profile object for this dataset
    roms = ambient.Profile(nc, chem_names=['dye_01', 'dye_02'])

    # Close the netCDF dataset
    roms.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
    roms = ambient.Profile(nc_file, chem_names='all')

    # Plot the density profile using the interpolation function
    z = np.linspace(roms.nc.variables['z'].valid_min,
                    roms.nc.variables['z'].valid_max, 250)
    rho = np.zeros(z.shape)
    tsp = roms.get_values(z, ['temperature', 'salinity', 'pressure'])
    for i in range(len(z)):
コード例 #22
0
ファイル: blowout_jet.py プロジェクト: changks/tamoc
warnings.filterwarnings("ignore")

if __name__ == '__main__':

    print('\n---------------------------------------------------------------')
    print('Demonstration using the Model class in the')
    print('particle_size_models module of TAMOC for a ')
    print('synthetic subsea accidental blowout case')
    print('---------------------------------------------------------------')

    # The inputs for a particle_size_models.Model simulation are similar to
    # those of the bent_plume_model.  We start by defining the ambient CTD
    # data.  Here, we will use the world-ocean average data distributed with
    # TAMOC.  Since the particle_size_models do not use ambient current data,
    # we will ignore that.
    profile = ambient.Profile(None)

    # For the particle_size_models.Model object, we need to create a
    # dbm.FluidMixture object.  Here, we make use of the dbm_utilities
    # to create synthetic blowout data.

    # Start by defining a substance
    substance = {
        'composition': [
            'n-hexane', '2-methylpentane', '3-methylpentane', 'neohexane',
            'n-heptane', 'benzene', 'toluene', 'ethylbenzene', 'n-decane'
        ],
        'masses':
        np.array([0.04, 0.07, 0.08, 0.09, 0.11, 0.12, 0.15, 0.18, 0.16])
    }