コード例 #1
0
def extract_sbe43(netCDFfile):
    ds = Dataset(netCDFfile, 'r')
    ds.set_auto_mask(False)

    var_temp = ds.variables["TEMP"]
    var_psal = ds.variables["PSAL"]
    var_pres = ds.variables["PRES"]

    # the SBE43 voltage
    var_v0 = ds.variables["V0"]

    dep_code = ds.deployment_code

    print('deployment', dep_code)

    out_file = dep_code + "-SBE43.nc"
    ds_out = Dataset(out_file, 'w', data_model='NETCDF4_CLASSIC')

    ds_out.createDimension("TIME", len(ds.variables['TIME']))
    ncVarIn = ds.variables['TIME']
    ncTimesOut = ds_out.createVariable('TIME', "f8", ("TIME", ), zlib=True)
    for a in ncVarIn.ncattrs():
        if a != '_FillValue':
            ncTimesOut.setncattr(a, ncVarIn.getncattr(a))
    ncTimesOut[:] = ds.variables['TIME'][:]

    # copy old variables into new file
    in_vars = set([x for x in ds.variables])

    z = in_vars.intersection([
        'TEMP', 'PSAL', 'PRES', 'V0', 'TEMP_quality_control',
        'PSAL_quality_control', 'PRES_quality_control', 'V0_quality_control',
        'LATITUDE', 'LONGITUDE', 'NOMINAL_DEPTH'
    ])

    for v in z:
        print('copying', v, 'dimensions', ncVarIn.dimensions)
        ncVarIn = ds.variables[v]
        if '_FillValue' in ncVarIn.ncattrs():
            fill = ncVarIn._FillValue
        else:
            fill = None

        ncVarOut = ds_out.createVariable(
            v, ncVarIn.dtype, ncVarIn.dimensions, fill_value=fill,
            zlib=True)  # fill_value=nan otherwise defaults to max
        for a in ncVarIn.ncattrs():
            if a != '_FillValue':
                if a == 'ancillary_variables':
                    ncVarOut.setncattr(
                        a, v + '_quality_control'
                    )  # only copying main quality control, not all individual flags
                else:
                    ncVarOut.setncattr(a, ncVarIn.getncattr(a))
        ncVarOut[:] = ncVarIn[:]

    if 'DOX2' in ds.variables:
        ncVarIn = ds.variables['DOX2']
        ncVarOut = ds_out.createVariable(
            'DOX2_SBE', "f4", ("TIME", ), fill_value=np.nan,
            zlib=True)  # fill_value=nan otherwise defaults to max
        for a in ncVarIn.ncattrs():
            if a not in ['_FillValue', 'ancillary_variables']:
                ncVarOut.setncattr(a, ncVarIn.getncattr(a))
        ncVarOut[:] = ncVarIn[:]

    T = var_temp[:]
    calibration_Soc = float(var_v0.calibration_Soc)
    calibration_offset = float(var_v0.calibration_offset)
    calibration_A = float(var_v0.calibration_A)
    calibration_B = float(var_v0.calibration_B)
    calibration_C = float(var_v0.calibration_C)
    calibration_E = float(var_v0.calibration_E)
    slope_correction = 1.0
    if 'oxygen_correction_slope' in var_v0.ncattrs():
        slope_correction = float(var_v0.oxygen_correction_slope)

    lat = -47
    lon = 142
    try:
        lat = ds.variables["LATITUDE"][0]
        lon = ds.variables["LONGITUDE"][0]
    except:
        pass

    SP = var_psal[:]
    p = var_pres[:]
    SA = gsw.SA_from_SP(SP, p, lon, lat)
    pt = gsw.pt0_from_t(SA, T, p)
    CT = gsw.CT_from_t(SA, T, p)
    sigma_t0 = gsw.sigma0(SA, CT)

    # calc oxygen solubility
    # 0.01 % difference to sea bird calculation
    #oxsol = gsw.O2sol_SP_pt(SP, pt) # umol/kg returned

    # calc OXSOL in ml/l as per seabird application note 64
    # this method gives a 0.2 % difference to what is calculated by sea bird (and what is calculated by TEOS-10)
    A0 = 2.00907
    A1 = 3.22014
    A2 = 4.0501
    A3 = 4.94457
    A4 = -0.256847
    A5 = 3.88767
    B0 = -0.00624523
    B1 = -0.00737614
    B2 = -0.010341
    B3 = -0.00817083
    C0 = -0.000000488682
    ts = np.log((298.15 - T) / (273.15 + T))

    oxsol = np.exp(A0 + A1 * ts + A2 * (ts**2) + A3 * (ts**3) + A4 * (ts**4) +
                   A5 * (ts**5) +
                   SP * [B0 + B1 * (ts) + B2 * (ts**2) + B3 *
                         (ts**3)] + C0 * (SP**2))
    #
    # # calculate oxygen from V0
    dox = slope_correction * calibration_Soc * (
        var_v0[:] + calibration_offset) * oxsol * (
            1 + calibration_A * T + calibration_B * T**2 +
            calibration_C * T**3) * np.exp(calibration_E * p / (T + 273.15))
    #
    # # create SBE43 oxygen ml/l
    # # ncVarOut = ds_out.createVariable("DOX", "f4", ("TIME",), fill_value=np.nan, zlib=True)  # fill_value=nan otherwise defaults to max
    # #
    # # ncVarOut[:] = dox
    # # ncVarOut.long_name = "volume_concentration_of_dissolved_molecular_oxygen_in_sea_water"
    # # ncVarOut.valid_min = 0
    # # ncVarOut.valid_max = 40
    # # ncVarOut.units = "ml/l"
    # # ncVarOut.equation_1 = "Ox(ml/l)=Soc.(V+Voffset).(1+A.T+B.T^2+V.T^3).OxSOL(T,S).exp(E.P/K) ... SeaBird (AN64-2)"

    # create SBE43 oxygen in umol/kg
    ncVarOut = ds_out.createVariable(
        "DOX2", "f4", ("TIME", ), fill_value=np.nan,
        zlib=True)  # fill_value=nan otherwise defaults to max

    ncVarOut[:] = dox * 44600 / (1000 + sigma_t0)

    #ncVarOut[:] = dox * 44.6

    ncVarOut.standard_name = "moles_of_oxygen_per_unit_mass_in_sea_water"
    ncVarOut.long_name = "moles_of_oxygen_per_unit_mass_in_sea_water"
    ncVarOut.coordinates = 'TIME LATITUDE LONGITUDE NOMINAL_DEPTH'
    ncVarOut.valid_min = 0
    ncVarOut.valid_max = 400
    ncVarOut.units = "umol/kg"
    ncVarOut.equation_1 = "Ox[ml/l]=Soc.(V+Voffset).(1+A.T+B.T^2+C.T^3).OxSOL(T,S)[ml/l].exp(E.P/K) ... SeaBird (AN64)"
    ncVarOut.equation_2 = "Ox[umol/kg]=Ox[ml/l].44660/(sigma-theta(P=0,Theta,S)+1000)"
    #ncVarOut.equation_1 = "Ox[umol/kg]=Soc.(V+Voffset).(1+A.T+B.T^2+C.T^3).OxSOL(T,S)[umol/kg].exp(E.P/K) ... SeaBird (AN64)"
    #ncVarOut.comment = 'OxSOL in umol/kg'
    ncVarOut.ancillary_variables = "DOX2_quality_control DOX2_quality_control_in"

    # quality flags
    ncVarOut_qc = ds_out.createVariable(
        "DOX2_quality_control", "i1", ("TIME", ), fill_value=99, zlib=True
    )  # fill_value=99 otherwise defaults to max, imos-toolbox uses 99
    ncVarOut_qc[:] = np.zeros(ncVarOut_qc.shape)
    if 'V0_quality_control' in ds.variables:
        mx = np.max([ncVarOut_qc[:], ds.variables['V0_quality_control'][:]],
                    axis=0)
        ncVarOut_qc[:] = mx
    if 'TEMP_quality_control' in ds.variables:
        mx = np.max([ncVarOut_qc[:], ds.variables['TEMP_quality_control'][:]],
                    axis=0)
        print('TEMP max', mx)
        ncVarOut_qc[:] = mx
    if 'PSAL_quality_control' in ds.variables:
        mx = np.max([ncVarOut_qc[:], ds.variables['PSAL_quality_control'][:]],
                    axis=0)
        print('PSAL max', mx)
        ncVarOut_qc[:] = mx
    if 'PRES_quality_control' in ds.variables:
        mx = np.max([ncVarOut_qc[:], ds.variables['PRES_quality_control'][:]],
                    axis=0)
        print('PRES max', mx)
        ncVarOut_qc[:] = mx

    ncVarOut_qc.standard_name = ncVarOut.standard_name + " status_flag"
    ncVarOut_qc.quality_control_conventions = "IMOS standard flags"
    ncVarOut_qc.flag_values = np.array([0, 1, 2, 3, 4, 6, 7, 9], dtype=np.int8)
    ncVarOut_qc.flag_meanings = 'unknown good_data probably_good_data probably_bad_data bad_data not_deployed interpolated missing_value'
    ncVarOut_qc.comment = 'maximum of all flags'

    # create a QC flag variable for the input data
    ncVarOut_qc = ds_out.createVariable(
        "DOX2_quality_control_in", "i1", ("TIME", ), fill_value=99, zlib=True
    )  # fill_value=99 otherwise defaults to max, imos-toolbox uses 99
    ncVarOut_qc[:] = mx
    ncVarOut_qc.long_name = "input data flag for moles_of_oxygen_per_unit_mass_in_sea_water"
    ncVarOut_qc.units = "1"
    ncVarOut_qc.comment = "data flagged from input variables TEMP, PSAL, PRES"

    # save the OxSOL
    if 'OXSOL' in ds_out.variables:
        ncVarOut = ds_out.variables['OXSOL']
    else:
        ncVarOut = ds_out.createVariable(
            "OXSOL", "f4", ("TIME", ), fill_value=np.nan,
            zlib=True)  # fill_value=nan otherwise defaults to max

    #ncVarOut[:] = oxsol * 44600 / (1000+sigma_t0)
    ncVarOut[:] = oxsol
    ncVarOut.units = "umol/kg"
    ncVarOut.comment = "calculated using gsw-python https://teos-10.github.io/GSW-Python/index.html function gsw.O2sol_SP_pt"
    ncVarOut.long_name = "moles_of_oxygen_per_unit_mass_in_sea_water_at_saturation"
    ncVarOut.coordinates = 'TIME LATITUDE LONGITUDE NOMINAL_DEPTH'

    for v in ds.ncattrs():
        if not v.startswith('sea_bird'):
            ds_out.setncattr(v, ds.getncattr(v))

    ds_out.instrument = 'Sea-Bird Electronics ; SBE43'
    ds_out.instrument_model = 'SBE43'
    ds_out.instrument_serial_number = '43' + var_v0.calibration_SerialNumber

    ncTimeFormat = "%Y-%m-%dT%H:%M:%SZ"

    attrs = ds.ncattrs()
    for at in attrs:
        if at not in [
                'title', 'instrument', 'instrument_model',
                'instrument_serial_number', 'history', 'date_created', 'title'
        ]:
            #print('copy att', at)
            ds_out.setncattr(at, ds.getncattr(at))

    ds_out.deployment_code = ds.deployment_code
    ds_out.instrument = 'SeaBird Electronics ; SBE43'
    ds_out.instrument_model = 'SBE43'
    ds_out.instrument_serial_number = ds.variables[
        'V0'].calibration_SerialNumber
    ds_out.title = 'Oceanographic mooring data deployment of {platform_code} at latitude {geospatial_lat_max:3.1f} longitude {geospatial_lon_max:3.1f} depth {geospatial_vertical_max:3.0f} (m) instrument {instrument} serial {instrument_serial_number}'

    # add creating and history entry
    ds_out.setncattr("date_created", datetime.utcnow().strftime(ncTimeFormat))

    # update the history attribute
    try:
        hist = ds.history + "\n"
    except AttributeError:
        hist = ""

    # keep the history so we know where it came from
    ds_out.setncattr(
        'history', hist + datetime.utcnow().strftime("%Y-%m-%d") +
        " calculate DOX2 from file " + os.path.basename(netCDFfile))

    ds.close()
    ds_out.close()

    return out_file
コード例 #2
0
def psal2asal(self,
              psal_parameter='PSAL',
              pres_parameter='PRES',
              lon='auto',
              lat='auto',
              inplace=True):
    """
    This function uses the gsw library.
    Adds the parameter Absolute Salinity (ASAL) from Practical Salinity (PSAL).
    Since PSAL is non-negative by definition, this function changes any
    negative input values of SP to be zero.

    Parameters
    ----------
        psal_parameter: str
            Parameter with valus of Practical Salinity
        pres_parameter: str
            Parameter with values of pressure, in dBar
        lon: str
            Parameter with the values of the longitud, in degrees
            If lon is 'auto', the value of lon will be taken from the
            metadata['last_longitude_observation']
        lat: str
            Parameter with the values of the ñatitude, in degrees
            If lat is 'auto', the value of lon will be taken from the
            metadata['last_latitude_observation']

    Returns
    -------
        wf: WaterFrame
    """

    df_copy = self.data.copy()
    if lat == 'auto':
        lat_parameter = 'LATITUDE'
        df_copy['LATITUDE'] = float(self.metadata['last_latitude_observation'])
        df_copy['LATITUDE_QC'] = 1
    else:
        lat_parameter = lat
    if lon == 'auto':
        lon_parameter = 'LONGITUDE'
        df_copy['LONGITUDE'] = float(
            self.metadata['last_longitude_observation'])
        df_copy['LONGITUDE_QC'] = 1
    else:
        lon_parameter = 'lon'

    df_copy['ASAL'] = gsw.SA_from_SP(df_copy[psal_parameter],
                                     df_copy[pres_parameter],
                                     df_copy[lon_parameter],
                                     df_copy[lat_parameter])

    # Add QC
    df_copy['ASAL_QC'] = 1
    # QC=0
    df_copy.loc[df_copy[f'{psal_parameter}_QC'] == 0, 'ASAL_QC'] = 0
    df_copy.loc[df_copy[f'{pres_parameter}_QC'] == 0, 'ASAL_QC'] = 0
    df_copy.loc[df_copy[f'{lon_parameter}_QC'] == 0, 'ASAL_QC'] = 0
    df_copy.loc[df_copy[f'{lat_parameter}_QC'] == 0, 'ASAL_QC'] = 0
    # QC=4
    df_copy.loc[df_copy[f'{psal_parameter}_QC'] == 4, 'ASAL_QC'] = 4
    df_copy.loc[df_copy[f'{pres_parameter}_QC'] == 4, 'ASAL_QC'] = 4
    df_copy.loc[df_copy[f'{lon_parameter}_QC'] == 4, 'ASAL_QC'] = 4
    df_copy.loc[df_copy[f'{lat_parameter}_QC'] == 4, 'ASAL_QC'] = 4

    # Delete lat and lon
    if lat == 'auto':
        del df_copy[f'{lat_parameter}_QC']
        del df_copy[lat_parameter]
    if lon == 'auto':
        del df_copy[f'{lon_parameter}_QC']
        del df_copy[lon_parameter]

    new_wf = self.copy()
    new_wf.data = df_copy.copy()
    # Add vocabulary
    new_wf.vocabulary['ASAL'] = {
        'long_name': 'Absolute Salinity',
        'units': 'g/kg'
    }

    if inplace:
        self.data = df_copy.copy()
        self.vocabulary = new_wf.vocabulary.copy()

    return new_wf
コード例 #3
0
ファイル: template_script.py プロジェクト: rpajela/ctdcal
def process_all_new():

    # Directory and file information
    expocode = settings.cruise['expocode']
    sectionID = settings.cruise['sectionid']
    raw_directory = settings.ctd_processing_dir['raw_data_directory']
    time_directory = settings.ctd_processing_dir['time_data_directory']
    converted_directory = settings.ctd_processing_dir['converted_directory']
    pressure_directory = settings.ctd_processing_dir['pressure_data_directory']
    oxygen_directory = settings.ctd_processing_dir['oxygen_directory']
    btl_directory = settings.ctd_processing_dir['bottle_directory']
    o2flask_file = settings.ctd_processing_dir['o2flask_file']
    log_directory = settings.ctd_processing_dir['log_directory']
    p_log_file = settings.ctd_processing_dir['pressure_log']
    hex_prefix = settings.ctd_processing_dir['hex_prefix']
    hex_postfix = settings.ctd_processing_dir['hex_postfix']
    xml_prefix = settings.ctd_processing_dir['xml_prefix']
    xml_postfix = settings.ctd_processing_dir['xml_postfix']

    # CTD Data Inputs
    p_col = settings.ctd_inputs['p']
    t_col = settings.ctd_inputs['t']
    t1_col = settings.ctd_inputs['t1']
    t2_col = settings.ctd_inputs['t2']
    c_col = settings.ctd_inputs['c']
    c1_col = settings.ctd_inputs['c1']
    c2_col = settings.ctd_inputs['c2']
    sal_col = settings.ctd_inputs['salt']
    dov_col = settings.ctd_inputs['dov']
    lat_col = settings.ctd_inputs['lat']
    lon_col = settings.ctd_inputs['lon']
    time_col = settings.ctd_inputs['scan_datetime']

    # Bottle Data Inputs
    p_btl_col = settings.bottle_inputs['p']
    t_btl_col = settings.bottle_inputs['t']
    t1_btl_col = settings.bottle_inputs['t1']
    t2_btl_col = settings.bottle_inputs['t2']
    c_btl_col = settings.bottle_inputs['c']
    c1_btl_col = settings.bottle_inputs['c1']
    c2_btl_col = settings.bottle_inputs['c2']
    reft_col = settings.bottle_inputs['reft']
    cond_col = settings.bottle_inputs['btl_cond']
    cr_avg = settings.bottle_inputs['cond_ratio']
    bath_temp = settings.bottle_inputs['bath_temp']
    sal_btl_col = settings.bottle_inputs['salt']
    dov_btl_col = settings.bottle_inputs['dov']
    lat_btl_col = settings.bottle_inputs['lat']
    lon_btl_col = settings.bottle_inputs['lon']
    oxy_btl_col = settings.bottle_inputs['btl_oxy']
    time_btl_col = settings.bottle_inputs['scan_datetime']

    # CTD Information
    sample_rate = settings.ctd_processing_constants['sample_rate']
    search_time = settings.ctd_processing_constants['roll_filter_time']
    ctd = settings.ctd_processing_constants['ctd_serial']

    p_column_names = settings.pressure_series_output['column_name']
    p_column_units = settings.pressure_series_output['column_units']

    btl_data_prefix = 'data/bottle/'
    btl_data_postfix = '_btl_mean.pkl'
    time_data_prefix = 'data/time/'
    time_data_postfix = '_time.pkl'
    p_log_file = 'data/logs/ondeck_pressure.csv'

    # Columns from btl and ctd file to be read:
    btl_cols = settings.btl_input_array
    ctd_cols = settings.ctd_input_array

    ssscc = settings.ssscc

    #    time_start = time.perf_counter()
    cnv_dir_list = os.listdir(converted_directory)
    time_dir_list = os.listdir(time_directory)
    btl_dir_list = os.listdir(btl_directory)

    for station in ssscc:
        if '{}.pkl'.format(station) in cnv_dir_list:
            continue
        #convert hex to ctd
        hex_file = hex_prefix + station + hex_postfix
        xml_file = xml_prefix + station + xml_postfix

        sbe_convert.convert_sbe(station, hex_file, xml_file,
                                converted_directory)
        print('Converted_sbe SSSCC: ' + station + ' done')

#    time_convert = time.perf_counter()

    for station in ssscc:
        if '{}_time.pkl'.format(station) in time_dir_list:
            continue
        sbe_convert.sbe_metadata(station)
        print('sbe_metadata SSSCC: ' + station + ' done')

    for station in ssscc:
        if '{}_btl_mean.pkl'.format(station) in btl_dir_list:
            continue
        #process bottle file
        sbe_convert.process_bottle(station)
        print('process_bottle SSSCC: ' + station + ' done')
#    time_bottle = time.perf_counter()

###########################################################################

### File I/O

# Load in all bottle, time, ref_data files into DataFrame

    btl_data_all = process_ctd.load_all_ctd_files(ssscc, btl_data_prefix,
                                                  btl_data_postfix, 'bottle',
                                                  btl_cols)
    time_data_all = process_ctd.load_all_ctd_files(ssscc, time_data_prefix,
                                                   time_data_postfix, 'time',
                                                   ctd_cols)

    ################################################################################

    ### Pressure Calibration

    # Determine Pressure offset from logs

    pressure_log = process_ctd.load_pressure_logs(p_log_file)
    p_off = process_ctd.get_pressure_offset(pressure_log.ondeck_start_p,
                                            pressure_log.ondeck_end_p)

    btl_data_all[p_btl_col] = fit_ctd.apply_pressure_offset(
        btl_data_all[p_btl_col], p_off)
    time_data_all[p_col] = fit_ctd.apply_pressure_offset(
        time_data_all[p_col], p_off)

    ###########################################################################

    df_ques_t1 = pd.DataFrame()
    df_ques_t2 = pd.DataFrame()

    df_ques_c1 = pd.DataFrame()
    df_ques_c2 = pd.DataFrame()

    ### Temperature Calibration
    for x in range(2):

        # Second order calibration

        df_temp_good = process_ctd.prepare_fit_data(btl_data_all, reft_col)

        df_ques_reft = process_ctd.quality_check(df_temp_good[t2_btl_col],
                                                 df_temp_good[t1_btl_col],
                                                 df_temp_good[p_btl_col],
                                                 df_temp_good['SSSCC'],
                                                 df_temp_good['btl_fire_num'],
                                                 'quest')
        df_ques_reft['Parameter'] = 'REF_TEMP'

        if settings.do_primary == 1:
            coef_temp_1, df_ques_t1 = process_ctd.calibrate_param(
                df_temp_good[t1_btl_col],
                df_temp_good[reft_col],
                df_temp_good[p_btl_col],
                'TP',
                2,
                df_temp_good.SSSCC,
                df_temp_good.btl_fire_num,
                xRange='800:6000')
            btl_data_all[t1_btl_col] = fit_ctd.temperature_polyfit(
                btl_data_all[t1_btl_col], btl_data_all[p_btl_col], coef_temp_1)
            time_data_all[t1_col] = fit_ctd.temperature_polyfit(
                time_data_all[t1_col], time_data_all[p_col], coef_temp_1)

        elif settings.do_secondary == 1:
            coef_temp_2, df_ques_t2 = process_ctd.calibrate_param(
                df_temp_good[t2_btl_col],
                df_temp_good[reft_col],
                df_temp_good[p_btl_col],
                'TP',
                2,
                df_temp_good.SSSCC,
                df_temp_good.btl_fire_num,
                xRange='1500:6000')
            btl_data_all[t2_btl_col] = fit_ctd.temperature_polyfit(
                btl_data_all[t2_btl_col], btl_data_all[p_btl_col], coef_temp_2)
            time_data_all[t2_col] = fit_ctd.temperature_polyfit(
                time_data_all[t2_col], time_data_all[p_col], coef_temp_2)

    # Apply fitting coef to data

    # Construct Quality Flag file

        qual_flag_temp = process_ctd.combine_quality_flags(
            [df_ques_reft, df_ques_t1, df_ques_t2])

        ## First order calibtation

        df_temp_good = process_ctd.prepare_fit_data(btl_data_all, reft_col)

        #        df_ques_reft = process_ctd.quality_check(df_temp_good[t2_btl_col], df_temp_good[t1_btl_col], df_temp_good[p_btl_col], df_temp_good['SSSCC'], df_temp_good['btl_fire_num'], 'quest')
        #        df_ques_reft['Parameter'] = 'REF_TEMP'
        if settings.do_primary == 1:
            coef_temp_prim, df_ques_t1 = process_ctd.calibrate_param(
                df_temp_good[t1_btl_col], df_temp_good[reft_col],
                df_temp_good[p_btl_col], 'T', 1, df_temp_good.SSSCC,
                df_temp_good.btl_fire_num)
            btl_data_all[t1_btl_col] = fit_ctd.temperature_polyfit(
                btl_data_all[t1_btl_col], btl_data_all[p_btl_col],
                coef_temp_prim)
            time_data_all[t1_col] = fit_ctd.temperature_polyfit(
                time_data_all[t1_col], time_data_all[p_col], coef_temp_prim)

        elif settings.do_secondary == 1:
            coef_temp_sec, df_ques_t2 = process_ctd.calibrate_param(
                df_temp_good[t2_btl_col], df_temp_good[reft_col],
                df_temp_good[p_btl_col], 'T', 1, df_temp_good.SSSCC,
                df_temp_good.btl_fire_num)
            btl_data_all[t2_btl_col] = fit_ctd.temperature_polyfit(
                btl_data_all[t2_btl_col], btl_data_all[p_btl_col],
                coef_temp_sec)
            time_data_all[t2_col] = fit_ctd.temperature_polyfit(
                time_data_all[t2_col], time_data_all[p_col], coef_temp_sec)

    # Apply fitting coef to data

        qual_flag_temp = process_ctd.combine_quality_flags(
            [df_ques_reft, df_ques_t1, df_ques_t2])

    ###########################################################################

#
### Conductivity Calibration
    for x in range(2):

        btl_data_all[cond_col] = fit_ctd.CR_to_cond(btl_data_all[cr_avg],
                                                    btl_data_all[bath_temp],
                                                    btl_data_all[t1_btl_col],
                                                    btl_data_all[p_btl_col])
        df_cond_good = process_ctd.prepare_fit_data(btl_data_all, cond_col)

        df_ques_refc = process_ctd.quality_check(df_cond_good[c2_btl_col],
                                                 df_temp_good[c1_btl_col],
                                                 df_temp_good[p_btl_col],
                                                 df_temp_good['SSSCC'],
                                                 df_temp_good['btl_fire_num'],
                                                 'quest')
        df_ques_refc['Parameter'] = 'REF_COND'

        # Second Order Calibration
        if settings.do_primary == 1:
            coef_cond_1, df_ques_c1 = process_ctd.calibrate_param(
                df_cond_good[c1_btl_col],
                df_cond_good[cond_col],
                df_cond_good[p_btl_col],
                'CP',
                2,
                df_cond_good['SSSCC'],
                df_cond_good['btl_fire_num'],
                xRange='800:6000')
            btl_data_all[c1_btl_col], btl_data_all[
                sal_btl_col] = fit_ctd.conductivity_polyfit(
                    btl_data_all[c1_btl_col], btl_data_all[t1_btl_col],
                    btl_data_all[p_btl_col], coef_cond_1)
            time_data_all[c1_col], time_data_all[
                sal_col] = fit_ctd.conductivity_polyfit(
                    time_data_all[c1_col], time_data_all[t1_col],
                    time_data_all[p_col], coef_cond_1)

        elif settings.do_secondary == 1:
            coef_cond_2, df_ques_c2 = process_ctd.calibrate_param(
                df_cond_good[c2_btl_col],
                df_cond_good[cond_col],
                df_cond_good[p_btl_col],
                'CP',
                2,
                df_cond_good['SSSCC'],
                df_cond_good['btl_fire_num'],
                xRange='1500:6000')
            btl_data_all[c2_btl_col], sal_2 = fit_ctd.conductivity_polyfit(
                btl_data_all[c2_btl_col], btl_data_all[t2_btl_col],
                btl_data_all[p_btl_col], coef_cond_2)
            time_data_all[c2_btl_col], sal2 = fit_ctd.conductivity_polyfit(
                time_data_all[c2_col], time_data_all[t2_col],
                time_data_all[p_col], coef_cond_2)

        qual_flag_cond = process_ctd.combine_quality_flags(
            [df_ques_c1, df_ques_c2, df_ques_refc])

        btl_data_all[cond_col] = fit_ctd.CR_to_cond(btl_data_all[cr_avg],
                                                    btl_data_all[bath_temp],
                                                    btl_data_all[t1_btl_col],
                                                    btl_data_all[p_btl_col])
        df_cond_good = process_ctd.prepare_fit_data(btl_data_all, cond_col)

        if settings.do_primary == 1:
            coef_cond_prim, df_ques_c1 = process_ctd.calibrate_param(
                df_cond_good[c1_btl_col], df_cond_good[cond_col],
                df_cond_good[p_btl_col], 'C', 2, df_cond_good['SSSCC'],
                df_cond_good['btl_fire_num'])
            btl_data_all[c1_btl_col], btl_data_all[
                sal_btl_col] = fit_ctd.conductivity_polyfit(
                    btl_data_all[c1_btl_col], btl_data_all[t1_btl_col],
                    btl_data_all[p_btl_col], coef_cond_prim)
            time_data_all[c1_col], time_data_all[
                sal_col] = fit_ctd.conductivity_polyfit(
                    time_data_all[c1_col], time_data_all[t1_col],
                    time_data_all[p_col], coef_cond_prim)

        elif settings.do_secondary == 1:
            coef_cond_sec, df_ques_c2 = process_ctd.calibrate_param(
                df_cond_good.CTDCOND2, df_cond_good.BTLCOND,
                df_cond_good.CTDPRS, 'C', 2, df_cond_good.SSSCC,
                df_cond_good.btl_fire_num)
            btl_data_all[c2_btl_col], sal_2 = fit_ctd.conductivity_polyfit(
                btl_data_all[c2_btl_col], btl_data_all[t2_btl_col],
                btl_data_all[p_btl_col], coef_cond_sec)
            time_data_all[c2_col], sal2 = fit_ctd.conductivity_polyfit(
                time_data_all[c2_col], time_data_all[t2_col],
                time_data_all[p_col], coef_cond_sec)

        qual_flag_cond = process_ctd.combine_quality_flags(
            [df_ques_c1, df_ques_c2, df_ques_refc])
    ###########################################################################
#
#    ## Oxygen Calibration

# Calculate Sigma
    btl_data_all['sigma_btl'] = oxy_fitting.sigma_from_CTD(
        btl_data_all[sal_btl_col], btl_data_all[t_btl_col],
        btl_data_all[p_btl_col], btl_data_all[lon_btl_col],
        btl_data_all[lat_btl_col])
    time_data_all['sigma_ctd'] = oxy_fitting.sigma_from_CTD(
        time_data_all[sal_col], time_data_all[t_col], time_data_all[p_col],
        time_data_all[lon_col], time_data_all[lat_col])

    btl_data_all[oxy_btl_col] = oxy_fitting.calculate_bottle_oxygen(
        ssscc, btl_data_all['SSSCC'], btl_data_all['TITR_VOL'],
        btl_data_all['TITR_TEMP'], btl_data_all['FLASKNO'])
    btl_data_all[oxy_btl_col] = oxy_fitting.oxy_ml_to_umolkg(
        btl_data_all[oxy_btl_col], btl_data_all['sigma_btl'])

    # Calculate SA and PT
    btl_data_all['SA'] = gsw.SA_from_SP(btl_data_all[sal_btl_col],
                                        btl_data_all[p_btl_col],
                                        btl_data_all[lon_btl_col],
                                        btl_data_all[lat_btl_col])
    btl_data_all['PT'] = gsw.pt0_from_t(btl_data_all['SA'],
                                        btl_data_all[t_btl_col],
                                        btl_data_all[p_btl_col])

    time_data_all['SA'] = gsw.SA_from_SP(time_data_all[sal_col],
                                         time_data_all[p_col],
                                         time_data_all[lon_col],
                                         time_data_all[lat_col])
    time_data_all['PT'] = gsw.pt0_from_t(time_data_all['SA'],
                                         time_data_all[t_col],
                                         time_data_all[p_col])

    # Calculate OS in µmol/kg

    btl_data_all['OS_btl'] = oxy_fitting.os_umol_kg(btl_data_all['SA'],
                                                    btl_data_all['PT'])
    time_data_all['OS_ctd'] = oxy_fitting.os_umol_kg(time_data_all['SA'],
                                                     time_data_all['PT'])

    oxy_df = pd.DataFrame()
    coef_dict = {}
    for station in ssscc:
        btl_data = btl_data_all[btl_data_all['SSSCC'] == station]
        time_data = time_data_all[time_data_all['SSSCC'] == station]

        hex_file = hex_prefix + station + hex_postfix
        xml_file = xml_prefix + station + xml_postfix
        coef0 = oxy_fitting.get_SB_coef(hex_file, xml_file)
        cfw_coef, df = oxy_fitting.oxy_fit(
            btl_data[p_btl_col], btl_data[oxy_btl_col], btl_data['sigma_btl'],
            time_data['sigma_ctd'], time_data['OS_ctd'], time_data[p_col],
            time_data[t_col], time_data[dov_col], time_data[time_col], coef0)
        df['SSSCC'] = station
        coef_dict[station] = cfw_coef
        oxy_df = pd.concat([oxy_df, df])

        print(station, ' Completed')

    coef_df = oxy_fitting.create_coef_df(coef_dict)
    oxy_df = oxy_fitting.flag_oxy_data(oxy_df)

    # Merge oxygen fitting DF to btl_data_all

    btl_data_all = oxy_fitting.merge_oxy_df(btl_data_all, oxy_df)

    # Apply coef to Time Data

    time_data_all = oxy_fitting.apply_oxygen_coef_ctd(time_data_all, coef_df,
                                                      ssscc)

    ################ Clean and export data #######################
    btl_data_all = process_ctd.merge_cond_flags(btl_data_all, qual_flag_cond)
    btl_data_all = process_ctd.merge_refcond_flags(btl_data_all,
                                                   qual_flag_cond)
    btl_data_all = process_ctd.merged_reftemp_flags(btl_data_all,
                                                    qual_flag_temp)
    ### Export Quality Flags

    qual_flag_temp.to_csv('data/logs/qual_flag_temp_new.csv', index=False)
    qual_flag_cond.to_csv('data/logs/qual_flag_cond_new.csv', index=False)

    ### Clean up Bottle Data by removing rows with no ctd data

    btl_data_all = btl_data_all.dropna(subset=btl_cols)

    ### Add DATE and TIME

    btl_data_all['DATE'] = ''
    btl_data_all['TIME'] = ''
    for station in ssscc:
        df = btl_data_all.loc[btl_data_all['SSSCC'] == station].copy()
        btl_data_all.loc[btl_data_all['SSSCC'] ==
                         station] = process_ctd.get_btl_time(
                             df, 'btl_fire_num', time_col)


### Create CT Files and HY files

    process_ctd.export_btl_data(btl_data_all, expocode, sectionID, expocode)
    process_ctd.export_time_data(time_data_all, ssscc, int(sample_rate),
                                 int(search_time), expocode, sectionID, ctd,
                                 p_column_names, p_column_units)
コード例 #4
0
                                         'salinity')
    salinity.lon, salinity.lat, = lon, lat
    fig, ax = plt_cross_section(salinity, cmap=cm.odv, levels=0.02)
    ax.set_xlabel(u'Seção de Salinidade climatológica (WOA09)'
                  u' no Atlântico (em longitude %3.1f\u00B0)' % longitude)
    fname = 'cross_section_salinity_woa09.%s' % fmt
    fig.savefig(fname, **kfig)
    os.system('convert -trim %s %s' % (fname, fname))

    # Profile.
    fig, ax = salinity[-18.5].plot(label=u'Salinidade Prática (SP)',
                                   linewidth=2,
                                   figsize=(5.5, 6))
    if False:  # FIXME.
        SA = gsw.SA_from_SP(salinity[-18.5],
                            temperature.index.values.astype(float), -25.5,
                            -18.5)
    SA = gsw.SR_from_SP(salinity[-18.5])
    ax.plot(SA, salinity.index, linewidth=2, label='Salnidade Absoluta (SA')
    ax.grid()
    ax.set_xlabel(u"[g kg$^{-1}$]")
    ax.set_ylabel("Profundidade [m]")
    ax.legend(numpoints=1, loc='lower right')

    fname = 'profile_temperature_woa09.%s' % fmt
    fig.savefig(fname, **kfig)
    os.system('convert -trim %s %s' % (fname, fname))

    # Atlantic cross section -- Temperature.
    lon, lat, depth, temperature = get_data('woa09_temperature_at337.5.h5',
                                            'temperature')
コード例 #5
0
def IO_argo(floatdir):
    from datetime import datetime, date, timedelta
    programs = os.listdir(floatdir)
    programs = programs[1:]
    # initialize
    tot_fl = 0
    maxNprof = 0
    ll = 0
    ll1 = 0
    l0 = 0
    dateFlNum = []
    iniDate = datetime(1950, 1, 1)
    minDate = datetime(2019, 1, 1).toordinal()

    # initialize big arrays
    PT_dataSO = np.nan * np.ones((822 * 310, 2000), '>f4')
    SA_dataSO = np.nan * np.ones((822 * 310, 2000), '>f4')
    lon_dataSO = np.nan * np.ones((822 * 310), '>f4')
    lat_dataSO = np.nan * np.ones((822 * 310), '>f4')
    pr_dataSO = np.nan * np.ones((822 * 2000 * 310), '>f4')
    yySO = np.zeros((822 * 310), 'int32')
    IDSO = np.zeros((822 * 2000 * 310), 'int32')

    for pp in programs:
        SO_floats = os.listdir(os.path.join(floatdir, '%s' % pp))
        for ff_SO in SO_floats:
            print ff_SO
            # @hidden_cell
            SO_prof = [
                f for f in os.listdir(
                    os.path.join(floatdir, '%s/%s' % (pp, ff_SO)))
                if 'prof.nc' in f
            ]

            tot_fl += 1
            file = os.path.join(floatdir, '%s/%s/%s' % (pp, ff_SO, SO_prof[0]))
            data = nc.Dataset(file)
            time = data.variables['JULD'][:]
            lon = data.variables['LONGITUDE'][:]
            lat = data.variables['LATITUDE'][:]
            pressPre = data.variables['PRES_ADJUSTED'][:].transpose()
            tempPre = data.variables['TEMP_ADJUSTED'][:].transpose()
            tempQC = data.variables['TEMP_ADJUSTED_QC'][:].transpose()
            psaPre = data.variables['PSAL_ADJUSTED'][:].transpose()
            psaQC = data.variables['PSAL_ADJUSTED_QC'][:].transpose()
            # have to add the good QC: [1,2,5,8]  (not in ['1','2','5','8'])
            psaPre[np.where(psaQC != '1')] = np.nan
            tempPre[np.where(tempQC != '1')] = np.nan
            # let's get rid of some profiles that are out of the indian sector
            msk1 = np.where(np.logical_and(lon >= 0, lon < 180))[0][:]
            msk2 = np.where(np.logical_and(lat[msk1] > -70,
                                           lat[msk1] < -30))[0][:]

            lon = lon[msk1][msk2]
            lat = lat[msk1][msk2]
            time = time[msk1][msk2]
            pressPre = pressPre[:, msk1[msk2]]
            tempPre = tempPre[:, msk1[msk2]]
            psaPre = psaPre[:, msk1[msk2]]
            if time[0] + iniDate.toordinal() < minDate:
                minDate = time[0]
            if len(lon) > maxNprof:
                maxNprof = len(lon[~np.isnan(lon)])
                flN = ff_SO

            # interpolate
            lat = np.ma.masked_less(lat, -90)
            lon = np.ma.masked_less(lon, -500)
            lon[lon > 360.] = lon[lon > 360.] - 360.
            Nprof = np.linspace(1, len(lat), len(lat))
            # turn the variables upside down, to have from the surface to depth and not viceversa
            if any(pressPre[:10, 0] > 500.):
                pressPre = pressPre[::-1, :]
                psaPre = psaPre[::-1, :]
                tempPre = tempPre[::-1, :]
            # interpolate data on vertical grid with 1db of resolution (this is fundamental to then create profile means)
            fields = [psaPre, tempPre]
            press = np.nan * np.ones((2000, pressPre.shape[1]))
            for kk in range(press.shape[1]):
                press[:, kk] = np.arange(2, 2002, 1)
            psa = np.nan * np.ones((press.shape), '>f4')
            temp = np.nan * np.ones((press.shape), '>f4')

            for ii, ff in enumerate(fields):
                for nn in range(pressPre.shape[1]):
                    # only use non-nan values, otherwise it doesn't interpolate well
                    try:
                        f1 = ff[:, nn][ff[:, nn].mask ==
                                       False]  #ff[:,nn][~np.isnan(ff[:,nn])]
                        f2 = pressPre[:, nn][ff[:, nn].mask == False]
                    except:
                        f1 = ff[:, nn]
                        f2 = pressPre[:, nn]
                    if len(f1) == 0:
                        f1 = ff[:, nn]
                        f2 = pressPre[:, nn]
                    try:
                        sp = interpolate.interp1d(f2[~np.isnan(f1)],
                                                  f1[~np.isnan(f1)],
                                                  kind='linear',
                                                  bounds_error=False,
                                                  fill_value=np.nan)
                        ff_int = sp(press[:, nn])
                        if ii == 0:
                            psa[:, nn] = ff_int
                        elif ii == 1:
                            temp[:, nn] = ff_int
                    except:
                        continue
                    #print 'At profile number %i, the float %s has only 1 record valid'

            # To compute theta, I need absolute salinity [g/kg] from practical salinity (PSS-78) [unitless] and conservative temperature.
            sa = np.nan * np.ones((press.shape), '>f4')
            for kk in range(press.shape[1]):
                sa[:, kk] = gsw.SA_from_SP(psa[:, kk], press[:, 0], lon[kk],
                                           lat[kk])
            ptemp = gsw.pt_from_CT(sa, temp)

            # mask out the profiles with :
            msk = np.where(lat < -1000)
            lat[msk] = np.nan
            lon[msk] = np.nan
            sa[msk] = np.nan
            sa[sa == 0.] = np.nan
            ptemp[msk] = np.nan
            ptemp[temp == 0.] = np.nan

            # save the nprofiles
            NN = np.ones((temp.shape), 'int32')
            for ii in range(len(Nprof)):
                NN[:, ii] = Nprof[ii]

            lon_dataSO[ll1:ll1 + len(lon)] = lon
            lat_dataSO[ll1:ll1 + len(lon)] = lat
            PT_dataSO[ll:ll + len(sa[0, :]), :] = ptemp.T
            SA_dataSO[ll:ll + len(sa[0, :]), :] = sa.T
            floatID = int(ff_SO) * np.ones((sa.shape[1]), 'int32')
            IDSO[ll:ll + len(sa[0, :])] = floatID

            # separate seasons
            dateFl = []
            for dd in time:
                floatDate = iniDate + timedelta(float(dd))
                dateFl.append(floatDate)
                dateFlNum = np.append(dateFlNum, floatDate.toordinal())

            yearsSO = np.array([int(dd.year) for dd in dateFl])
            yySO[ll:ll + len(sa[0, :])] = yearsSO

            ll = ll + len(sa[0, :])
            ll1 = ll1 + len(lon)

    # chop away the part of the array with no data
    PT_dataSO = PT_dataSO[:ll, :]
    SA_dataSO = SA_dataSO[:ll, :]
    IDSO = IDSO[:ll]
    lat_dataSO = lat_dataSO[:ll]
    lon_dataSO = lon_dataSO[:ll]
    mmSO = mmSO[:ll]
    yySO = yySO[:ll]

    # remove entire columns of NaNs
    idBad = []
    for ii in range(PT_dataSO.shape[0]):
        f0 = PT_dataSO[ii, :]
        f1 = f0[~np.isnan(f0)]
        if len(f1) == 0:
            idBad.append(ii)
    PT_dataSO = np.delete(PT_dataSO, idBad, 0)
    SA_dataSO = np.delete(SA_dataSO, idBad, 0)
    IDSO = np.delete(IDSO, idBad, 0)
    lon_dataSO = np.delete(lon_dataSO, idBad, 0)
    lat_dataSO = np.delete(lat_dataSO, idBad, 0)
    mmSO = np.delete(mmSO, idBad, 0)
    yySO = np.delete(yySO, idBad, 0)

    idBad = []
    # Interpolate again in depth.. for some reason, some profiles have still wholes in the middle:
    for ii in range(PT_dataSO.shape[0]):
        f0 = PT_dataSO[ii, :]
        try:
            sp = interpolate.interp1d(press[~np.isnan(f0), 0],
                                      f0[~np.isnan(f0)],
                                      kind='linear',
                                      bounds_error=False,
                                      fill_value=np.nan)
            PT_dataSO[ii, :] = sp(press[:, 0])
            f0 = SA_dataSO[ii, :]
            sp = interpolate.interp1d(press[~np.isnan(f0), 0],
                                      f0[~np.isnan(f0)],
                                      kind='linear',
                                      bounds_error=False,
                                      fill_value=np.nan)
            SA_dataSO[ii, :] = sp(press[:, 0])
        except:
            idBad.append(ii)
            #print ii, ' has only 1 number'
    PT_dataSO = np.delete(PT_dataSO, idBad, 0)
    SA_dataSO = np.delete(SA_dataSO, idBad, 0)
    IDSO = np.delete(IDSO, idBad, 0)
    lon_dataSO = np.delete(lon_dataSO, idBad, 0)
    lat_dataSO = np.delete(lat_dataSO, idBad, 0)
    mmSO = np.delete(mmSO, idBad, 0)
    yySO = np.delete(yySO, idBad, 0)

    IO_argo.profSO = [PT_dataSO, SA_dataSO, lon_dataSO, lat_dataSO, IDSO]
    IO_argo.temporalSO = [yySO, mmSO]

    return [IO_argo.profSO, IO_argo.temporalSO]
コード例 #6
0
def read_sbe_cnv(file, lat=0, lon=0):
    """
    Read Seabird SBE37 .cnv file and return as xarray.Dataset.

    Parameters
    ----------
    file : str
        Complete path to .cnv file
    lat : float
        Latitude (used for gsw calculations). Defaults to zero.
    lon : float
        Longitude (used for gsw calculations). Defaults to zero.

    Returns
    -------
    mc : xarray.Dataset
        Microcat data as Dataset with some metadata in the attributes.
    """
    # Read cnv file using Seabird package
    cnv = fCNV(file)

    # parse time
    mcyday = cnv["timeJV2"]
    start_time_str_all = cnv.attributes["start_time"]
    start_time_str = start_time_str_all.split("[")[0]
    base_year = pd.to_datetime(start_time_str).year
    mctime = yday1_to_datetime64(base_year, mcyday)
    # let's make sure the first time stamp we generated matches the string in the cnv file
    assert pd.to_datetime(np.datetime64(mctime[0],
                                        "s")) == pd.to_datetime(start_time_str)

    # data vars
    dvars = {"prdM": "p", "tv290C": "t"}
    mcdata = {}
    for k, di in dvars.items():
        if k in cnv.keys():
            # print(di, ':', k)
            mcdata[di] = (["time"], cnv[k])
    mc = xr.Dataset(data_vars=mcdata, coords={"time": mctime})
    mc.attrs["file"] = cnv.attributes["filename"]
    mc.attrs["sbe_model"] = cnv.attributes["sbe_model"]
    # conductivity
    cvars = {"cond0mS/cm": "c", "cond0S/m": "c"}
    for k, di in cvars.items():
        if k in cnv.keys():
            # convert from S/m to mS/cm as this is needed for gsw.SP_from_C
            if k == "cond0S/m":
                conductivity = cnv[k] * 10
            else:
                conductivity = cnv[k]
            mc[di] = (["time"], conductivity)

    # calculate oceanographic variables
    mc["SP"] = (["time"], gsw.SP_from_C(mc.c, mc.t, mc.p))
    if lat == 0 and lon == 0:
        print(
            "warning: absolute salinity, conservative temperature\n",
            "and density calculation may be inaccurate\n",
            "due to missing latitude/longitude",
        )
    mc["SA"] = (["time"], gsw.SA_from_SP(mc.SP, mc.p, lat=lat, lon=lon))
    mc["CT"] = (["time"], gsw.CT_from_t(mc.SA, mc.t, mc.p))
    mc["sg0"] = (["time"], gsw.sigma0(mc.SA, mc.CT))

    # add attributes
    attributes = {
        "p": dict(long_name="pressure", units="dbar"),
        "t": dict(long_name="in-situ temperature", units="°C"),
        "CT": dict(long_name="conservative temperature", units="°C"),
        "SA": dict(long_name="absolute salinity", units=r"kg/m$^3$"),
        "c": dict(long_name="conductivity", units="mS/cm"),
        "SP": dict(long_name="practical salinity", units=""),
        "sg0": dict(long_name=r"potential density $\sigma_0$",
                    units=r"kg/m$^3$"),
    }
    for k, att in attributes.items():
        if k in list(mc.variables.keys()):
            mc[k].attrs = att

    return mc
コード例 #7
0
 def getRho(self):
     SA = gsw.SA_from_SP(self.sal, self.press, self.lon, self.lat)
     CT = gsw.CT_from_t(SA, self.theta,
                        self.press)  # Is this potential temperature
     rho = gsw.rho(SA, CT, self.press)
     return rho
コード例 #8
0
    def __init__(self,
                 time,
                 sal,
                 temp,
                 pres,
                 lon,
                 lat,
                 ballast,
                 pitch,
                 profile,
                 navresource,
                 ADCP_vel=None,
                 **param):

        self.timestamp = time
        self.time = date2float(self.timestamp)
        self.pressure = pres
        self.longitude = lon
        self.latitude = lat
        self.profile = profile
        self.ADCP_vel = ADCP_vel

        self.temperature = temp
        self.salinity = sal

        self.ballast = ballast / 1000000  # m^3
        self.pitch = np.deg2rad(pitch)  # rad

        self.AR = 7
        self.eOsborne = 0.8
        self.Cd1_hull = 2.1
        self.Omega = 0.75

        self.param_reference = dict({
            'mass': 60.772,  # Vehicle mass in kg
            'vol0': 59.015 /
            1000,  # Reference volume in m**3, with ballast at 0 (with -500 to 500 range), at surface pressure and 20 degrees C
            'area_w': 0.09,  # Wing surface area, m**2
            'Cd_0': 0.11781,  #
            'Cd_1': 2.94683,  #
            'Cl_w': 3.82807,  # 
            'Cl_h': 3.41939,  # 
            'comp_p': 4.5e-06,  # Pressure dependent hull compression factor
            'comp_t': -6.5e-05  # Temperature dependent hull compression factor
        })

        self.param = self.param_reference.copy()
        for k, v in param.items():
            self.param[k] = v
        self.param_initial = self.param

        def fillGaps(x, y):
            f = interp1d(x[np.isfinite(x + y)],
                         y[np.isfinite(x + y)],
                         bounds_error=False,
                         fill_value=np.NaN)
            return (f(x))

        def RM(x, N):
            big = np.full([N, len(x) + N - 1], np.nan)
            for n in np.arange(N):
                if n == N - 1:
                    big[n, n:] = x
                else:
                    big[n, n:-N + n + 1] = x
            return np.nanmedian(big[:,
                                    int(np.floor(N /
                                                 2)):-int(np.floor(N / 2))],
                                axis=0)

        def smooth(x, N):
            return np.convolve(x, np.ones(N) / N, mode='same')

        self.depth = gsw.z_from_p(
            self.pressure, self.latitude
        )  # m . Note depth (Z) is negative, so diving is negative dZdt
        self.dZdt = np.gradient(self.depth, self.time)  # m.s-1

        self.g = gsw.grav(self.latitude, self.pressure)

        self.SA = gsw.SA_from_SP(self.salinity, self.pressure, self.longitude,
                                 self.latitude)
        self.CT = gsw.CT_from_t(self.SA, self.temperature, self.pressure)
        self.rho = gsw.rho(self.SA, self.CT, self.pressure)

        ### Basic model
        # Relies on steady state assumption that buoyancy, weight, drag and lift cancel out when not accelerating.
        # F_B - cos(glide_angle)*F_L - sin(glide_angle)*F_D - F_g = 0
        # cos(glide_angle)*F_L + sin(glide_angle)*F_D = 0

        # Begin with an initial computation of angle of attack and speed through water:
        self.model_function()

        ### Get good datapoints to regress over
        self._valid = np.full(np.shape(self.pitch), True)
        self._valid[self.pressure < 5] = False
        self._valid[np.abs(self.pitch) < 0.2] = False  # TODO change back to 15
        self._valid[np.abs(self.pitch) > 0.6] = False  # TODO change back to 15
        self._valid[np.abs(np.gradient(self.dZdt, self.time)) >
                    0.005] = False  # Accelerations
        self._valid[np.gradient(self.pitch, self.time) == 0] = False
        self._valid = self._valid & ((navresource == 100) |
                                     (navresource == 117))

        print('Number of valid points: ' + str(np.count_nonzero(self._valid)) +
              ' (out of ' + str(len(self._valid)) + ')')

        # Do first pass regression on vol parameters, or volume and hydro?
        self.regression_parameters = ('vol0', 'Cd_0', 'Cd_1', 'comp_p',
                                      'comp_t')
コード例 #9
0
    def __init__(self, time, sal, temp, pres, lon, lat, ballast, pitch,
                 profile, navresource, **param):

        self.timestamp = time
        self.time = date2float(self.timestamp)
        self.pressure = pres
        self.longitude = lon
        self.latitude = lat
        self.profile = profile

        self.temperature = temp
        self.salinity = sal

        self.ballast = ballast / 1000000  # m^3
        self.pitch = np.deg2rad(pitch)  # rad

        self._dives = np.full(len(pres), True)

        self.param_reference = dict({
            'mass': 60.772,  # Vehicle mass in kg
            'vol0': 60 /
            1000,  # Reference volume in m**3, with ballast at 0 (with -500 to 500 range), at surface pressure and 20 degrees C
            'hd_a': 0.015,  # 0.003,  Wing surface area, m**2
            'hd_b': 0.018,  # 0.0118
            'hd_c': 9.85e-6,  #
            'hd_s': 0.2,  # -0.25, # 
            'comp_p': 4.5e-06,  # Pressure dependent hull compression factor
            'comp_t': -6.5e-05  # Temperature dependent hull compression factor
        })

        self.param = self.param_reference.copy()
        for k, v in param.items():
            self.param[k] = v
        self.param_initial = self.param

        def fillGaps(x, y):
            f = interp1d(x[np.isfinite(x + y)],
                         y[np.isfinite(x + y)],
                         bounds_error=False,
                         fill_value=np.NaN)
            return (f(x))

        def RM(x, N):
            big = np.full([N, len(x) + N - 1], np.nan)
            for n in np.arange(N):
                if n == N - 1:
                    big[n, n:] = x
                else:
                    big[n, n:-N + n + 1] = x
            return np.nanmedian(big[:,
                                    int(np.floor(N /
                                                 2)):-int(np.floor(N / 2))],
                                axis=0)

        def smooth(x, N):
            return np.convolve(x, np.ones(N) / N, mode='same')

        self.depth = gsw.z_from_p(
            self.pressure, self.latitude
        )  # m . Note depth (Z) is negative, so diving is negative dZdt
        self.dZdt = np.gradient(self.depth, self.time)  # m.s-1

        self.g = gsw.grav(self.latitude, self.pressure)

        self.SA = gsw.SA_from_SP(self.salinity, self.pressure, self.longitude,
                                 self.latitude)
        self.CT = gsw.CT_from_t(self.SA, self.temperature, self.pressure)
        self.rho = gsw.rho(self.SA, self.CT, self.pressure)

        # Begin with an initial computation of angle of attack and speed through water:
        self.model_function()

        ### Get good datapoints to regress over
        self._valid = np.full(np.shape(self.pitch), True)
        self._valid[self.pressure < 5] = False
        self._valid[np.abs(self.pitch) < 0.2] = False  # TODO change back to 15
        self._valid[np.abs(self.pitch) > 0.6] = False  # TODO change back to 15
        self._valid[np.abs(np.gradient(self.dZdt, self.time)) >
                    0.0005] = False  # Accelerations
        self._valid[np.gradient(self.pitch, self.time) == 0] = False
        self._valid = self._valid & ((navresource == 100) |
                                     (navresource == 117))

        # Do first pass regression on vol parameters, or volume and hydro?
        self.regression_parameters = ('vol0', 'hd_a', 'hd_b', 'hd_c', 'comp_t',
                                      'comp_p')
コード例 #10
0
1) Cabbeling
****************************************************************************"""
# You make two measurements of seawater with a CTD...
# T (in-situ temperature, C)
T1  =  0.0
T2  =  16.45
# Sp (Practical Salinity, PSU)
S1  =  31.0
S2  =  32.0

p0  =  0         # dbar pressure at surface
lat =  45        # N
lon = -30        # E

# First convert the measurments to absolute salinity 
Sa1 = sw.SA_from_SP(S1,p0,lon,lat)
Sa2 = sw.SA_from_SP(S2,p0,lon,lat)

# ...and conservative temperature.
Tc1 = sw.CT_from_t(Sa1,T1,p0)
Tc2 = sw.CT_from_t(Sa2,T2,p0)

# Now calculate the density of each water parcel? 
rho1 = sw.rho(Sa1,T1,p0)
rho2 = sw.rho(Sa2,T2,p0)

#Which water mass is denser?
print"The measurement 1 is", round(rho1-rho2,SF),"kg/m^2 denser than measurement 2."
#What is their average density?
print"Their average density is",round((rho1+rho2)/2,SF),"."
コード例 #11
0
def find_sigma0_z(salinity, temperature, pressure, latitude, longitude,
                  sigmas):
    """
    Find the depth of the isopycnal using T/S from a cast
    Inputs:
        salinity    (array) : Salinity in PSU
        temperature (array) : In-situ temperature (C)
        latitude    (array) : Latitude of the sample
        longitude   (array) : Longitude of the sample
        sigmas      (array) : Isopycnals for which to find the depth
    Outputs:
        sigma_z     (array) : Depth of the isopycnals
    Algorithm:
        1. Convert in-situ salinity and temperature to Absolute Salinity and Conservative Temperature
        2. Calculate sigma0
        3. Check to ensure the isopycnal surface spans the density range of the water column
        4. Build interpolating functions for both T and S
        5. Sweep down and find the first place where the specified density exists in between adjacent points
        6. Use the EOS to find the where the zero crossing is
    """
    def dens_diff(pressure, SA_f, CT_f, target_sigma0):
        return np.square(
            gsw.sigma0(SA_f(pressure), CT_f(pressure)) - target_sigma0)

    def return_early(is_scalar):
        if is_scalar:
            return np.nan
        else:
            return np.nan * np.ones(sigmas.shape)

    # Promote to single element array if only one level requested
    valid = (~np.isnan(salinity)) & (~np.isnan(temperature)) & (
        ~np.isnan(pressure))
    salinity = salinity[valid]
    temperature = temperature[valid]
    pressure = pressure[valid]
    longitude = longitude[valid]
    latitude = latitude[valid]

    is_scalar = type(sigmas) == type(0.)
    if is_scalar:
        sigmas = np.array([sigmas])

    if valid.sum() < 3:
        return return_early(is_scalar)

    pressure = np.array(pressure)
    SA = gsw.SA_from_SP(salinity, pressure, longitude, latitude)
    CT = gsw.CT_from_t(salinity, temperature, pressure)

    P_sort = np.unique(pressure)
    if len(P_sort) < 3:
        return return_early(is_scalar)

    SA_sort = np.zeros(P_sort.shape)
    CT_sort = np.zeros(P_sort.shape)
    # Loop through all pressures that overlap, average the temperatures and salinity accordingly
    for idx, P in enumerate(P_sort):
        presidx = (pressure == P)
        SA_sort[idx] = SA[presidx].mean()
        CT_sort[idx] = CT[presidx].mean()

    SA_intp = intp.interp1d(P_sort, SA_sort, kind='quadratic')
    CT_intp = intp.interp1d(P_sort, CT_sort, kind='quadratic')

    sigma0 = gsw.sigma0(SA_sort, CT_sort)
    sigma0_max = sigma0.max()
    sigma0_min = sigma0.min()

    sigma0_z = np.zeros(len(sigmas))

    for sigidx, siglev in enumerate(sigmas):
        if (siglev < sigma0_min) or (siglev > sigma0_max):
            sigma0_z[sigidx] = np.nan
        else:
            for botidx in range(len(sigma0) - 1):
                if (siglev >= sigma0[botidx]) & (siglev <= sigma0[botidx + 1]):
                    start_idx = botidx
                    break

            out = optimize.minimize_scalar(
                dens_diff,
                bounds=[P_sort[botidx], P_sort[botidx + 1]],
                method='Bounded',
                args=(SA_intp, CT_intp, siglev))

            sigma0_z[sigidx] = out.x

    if is_scalar:
        sigma0_z = np.squeeze(sigma0_z)

    return sigma0_z
コード例 #12
0
def MLD(PresOld, TempOld, SalOld, Lat, Lon, InterpFlag):
    
    # Calculate MLD of a single profile
    # Extrapolates surface values only if min pres is less than 15 dbar
    
    MinSurfP=0
    MaxSurfP=10
     
    j=0
    surf_flag=0
    surf_pres_i=[]
    
    dense_offset=.03
    
    mld_pres=np.NaN
    
    # Interpolate pressure and other variables
    
    sflag = 0
    if InterpFlag == True: 
        if np.nanmin(PresOld) < 15:
            Pres = np.arange(1,np.nanmax(PresOld))
            
            sal_int = interpolate.interp1d(PresOld, SalOld, fill_value = 'extrapolate')
            temp_int = interpolate.interp1d(PresOld, TempOld, fill_value = 'extrapolate')
            
            Sal = sal_int(Pres)
            Temp = temp_int(Pres)
            sflag = 1
    else: 
        Pres = PresOld
        Temp = TempOld
        Sal = SalOld
        sflag = 1
    
    if sflag == 1:
        
        if np.sum(np.isnan(Pres)) != len(Pres) and np.nanmin(Pres) <= MaxSurfP:
            
            while (j<len(Pres) and surf_flag ==0):
                if (Pres[j]>= MinSurfP and Pres[j] <= MaxSurfP):
                    surf_pres_i=surf_pres_i+[j]
                
                if Pres[j] > MaxSurfP:
                    surf_flag=1
                
                j=j+1
            
            if surf_pres_i != []:
                
                if len(surf_pres_i)>1:
                    s_start=surf_pres_i[0]
                    s_end=surf_pres_i[-1]+1
        
                    P_mean=np.nanmean(Pres[s_start:s_end])
                else:
                    P_mean=surf_pres_i[0]
                    s_end=surf_pres_i[-1]+1
                
                # Calculate density
                SA=gsw.SA_from_SP(Sal,Pres,Lat,Lon)
                CT=gsw.CT_from_t(SA,Temp,P_mean)
                density = np.zeros(len(Pres))
                density[:]=np.NaN
                
                for k in np.arange(len(density)):
                    density[k]=gsw.density.sigma0(SA=SA[k],CT=CT[k])
                
                if len(surf_pres_i)>1:
                    surf_dense=np.nanmean(density[s_start:s_end])
                else:
                    surf_dense=np.nanmean(density[surf_pres_i[0]])
                    
                if np.isnan(surf_dense) == False:
                    #print(surf_dense)
                    rho_mld=surf_dense+dense_offset
                    
                    #print(mld_dense)
                    # Find MLD
                    mld_flag=np.NaN
                    inter_flag=np.NaN
                    mld_pres=np.NaN
                    
                    P_L=np.NaN
                    rho_L=np.NaN
                    P_D=np.NaN
                    rho_D=np.NaN
                    
                    mld_exact = 0
                    
                    j = s_end -1
                    # Start search at base of surface layer
                    while(j<len(density) and np.isnan(mld_flag)==True):
                    
                        if density[j] == rho_mld:
                            mld_pres=Pres[j]
                            mld_flag=1
                            mld_exact = 1
                        elif density[j]<rho_mld:
                            P_L=Pres[j]
                            rho_L=density[j]
                        elif density[j]>rho_mld:
                            P_D=Pres[j]
                            rho_D=density[j]
                            inter_flag=1
                            mld_flag=1
                        
                        j=j+1
                    
                    #if mld_exact == 1:
                       # mld_pres=mld_pres
                    if (np.isnan(mld_flag) == True):
                        # Ran through entire profile and did not find mld
                        # i.e. MLD is deeper than deepest pressure measurement
                        # So make md deepest pressure measurement
                        # OR 2000 dbar?
                        mld_pres=np.nanmax(Pres)
                    elif (np.isnan(mld_flag)== False and inter_flag == 1):
                        # Need to interpolate to get MLD
                        #mld_pres=M_D-(((M_D-mld_dense)/(M_D-L_D))*(M_P-L_P))
                        mld_pres = P_D-(P_D - P_L)*((rho_D-rho_mld)/(rho_D-rho_L))
                    elif (np.isnan(mld_flag)== False and inter_flag == 0):
                        mld_pres=mld_pres
                    else:
                        print('ERROR')
                
        return mld_pres  
コード例 #13
0
                                        # Determine if the roundup or rounddown date is closer
                                        rd_dif = abs(
                                            (prof_date -
                                             rounddown_date).total_seconds())
                                        ru_dif = abs(
                                            (prof_date -
                                             roundup_date).total_seconds())

                                        if ru_dif <= rd_dif:
                                            close_date = roundup_date
                                        else:
                                            close_date = rounddown_date

                                    # Unit Conversion
                                    SA = gsw.SA_from_SP(
                                        surf_S, P, lon[j], lat[j])

                                    # Calculate conservative temp or temp
                                    CT = gsw.CT_from_t(SA, surf_T, P)

                                    # Calculate density
                                    #dense=gsw.density.rho_t_exact(SA, T, P) # kg/m^3
                                    surf_dense = gsw.density.sigma0(SA,
                                                                    CT) + 1000

                                    # Calculate oxygen saturation at each point
                                    O2_sol = gsw.O2sol(SA, CT, P, lon[j],
                                                       lat[j])
                                    oxy_sat = np.round(surf_O / O2_sol * 100,
                                                       2)
                                    oxy_dev = surf_O - O2_sol
コード例 #14
0
distlon = (lon_int - iflon) * 111e3

fdist = np.sign(lat_int - iflat) * np.sqrt((
    (lat_int - iflat) * 111e3 * np.cos(lat_int))**2 +
                                           ((lon_int - iflon) * 111e3)**2)
#%% HISTO IN T-S Space 3 panel

cmap = 'gnuplot'
cl = [-5, -1]
norm = np.max(fluorppb_ts)
mask = (fluorppb_ts / norm > 10**(cl[0])) & (jday_ts < 68)
#mask = jday_ts<90
xedges = np.linspace(34.5, 37, 150)
yedges = np.linspace(13, 22, 150)
X, Y = np.meshgrid(xedges, yedges)
SA = gsw.SA_from_SP(X, 0, -66, 39)
CT = gsw.CT_from_t(SA, Y, 0)
R = gsw.rho(SA, CT, 0)
R = R - 1000

SA = gsw.SA_from_SP(fS, fP, -66, 39)
CT = gsw.CT_from_t(SA, fT, fP)
Rf = gsw.rho(SA, CT, 0)
Rf = Rf - 1000
norm = np.sum(fluorppb_ts[mask])
norm = 1
H, xedges, yedges = np.histogram2d(S_ts[mask],
                                   T_ts[mask],
                                   weights=(fluorppb_ts[mask] / norm),
                                   bins=(xedges, yedges),
                                   density=False)
コード例 #15
0
ファイル: xarray.py プロジェクト: DamienIrving/argopy
    def teos10(self,
               vlist: list = ['SA', 'CT', 'SIG0', 'N2', 'PV', 'PTEMP'],
               inplace: bool = True):
        """ Add TEOS10 variables to the dataset

        By default, add: 'SA', 'CT', 'SIG0', 'N2', 'PV', 'PTEMP'
        Rely on the gsw library.

        Parameters
        ----------
        vlist: list(str)
            List with the name of variables to add.
        inplace: boolean, True by default
            If True, return the input :class:`xarray.Dataset` with new TEOS10 variables added as a new :class:`xarray.DataArray`
            If False, return a :class:`xarray.Dataset` with new TEOS10 variables

        Returns
        -------
        :class:`xarray.Dataset`
        """
        if not with_gsw:
            raise ModuleNotFoundError(
                "This functionality requires the gsw library")

        this = self._obj

        to_profile = False
        if self._type == 'profile':
            to_profile = True
            this = this.argo.profile2point()

        # Get base variables as numpy arrays:
        psal = this['PSAL'].values
        temp = this['TEMP'].values
        pres = this['PRES'].values
        lon = this['LONGITUDE'].values
        lat = this['LATITUDE'].values
        f = lat

        # Coriolis
        f = gsw.f(lat)

        # Depth:
        depth = gsw.z_from_p(pres, lat)

        # Absolute salinity
        sa = gsw.SA_from_SP(psal, pres, lon, lat)

        # Conservative temperature
        ct = gsw.CT_from_t(sa, temp, depth)

        # Potential Temperature
        if 'PTEMP' in vlist:
            pt = gsw.pt_from_CT(sa, ct)

        # Potential density referenced to surface
        if 'SIG0' in vlist:
            sig0 = gsw.sigma0(sa, ct)

        # N2
        if 'N2' in vlist or 'PV' in vlist:
            n2_mid, p_mid = gsw.Nsquared(sa, ct, pres, lat)
            # N2 on the CT grid:
            ishallow = (slice(0, -1), Ellipsis)
            ideep = (slice(1, None), Ellipsis)

            def mid(x):
                return 0.5 * (x[ideep] + x[ishallow])

            n2 = np.zeros(ct.shape) * np.nan
            n2[1:-1] = mid(n2_mid)

        # PV:
        if 'PV' in vlist:
            pv = f * n2 / gsw.grav(lat, pres)

        # Back to the dataset:
        that = []
        if 'SA' in vlist:
            SA = xr.DataArray(sa, coords=this['PSAL'].coords, name='SA')
            SA.attrs['standard_name'] = 'Absolute Salinity'
            SA.attrs['unit'] = 'g/kg'
            that.append(SA)

        if 'CT' in vlist:
            CT = xr.DataArray(ct, coords=this['TEMP'].coords, name='CT')
            CT.attrs['standard_name'] = 'Conservative Temperature'
            CT.attrs['unit'] = 'degC'
            that.append(CT)

        if 'SIG0' in vlist:
            SIG0 = xr.DataArray(sig0, coords=this['TEMP'].coords, name='SIG0')
            SIG0.attrs[
                'long_name'] = 'Potential density anomaly with reference pressure of 0 dbar'
            SIG0.attrs['standard_name'] = 'Potential Density'
            SIG0.attrs['unit'] = 'kg/m^3'
            that.append(SIG0)

        if 'N2' in vlist:
            N2 = xr.DataArray(n2, coords=this['TEMP'].coords, name='N2')
            N2.attrs['standard_name'] = 'Squared buoyancy frequency'
            N2.attrs['unit'] = '1/s^2'
            that.append(N2)

        if 'PV' in vlist:
            PV = xr.DataArray(pv, coords=this['TEMP'].coords, name='PV')
            PV.attrs['standard_name'] = 'Planetary Potential Vorticity'
            PV.attrs['unit'] = '1/m/s'
            that.append(PV)

        if 'PTEMP' in vlist:
            PTEMP = xr.DataArray(pt, coords=this['TEMP'].coords, name='PTEMP')
            PTEMP.attrs['standard_name'] = 'Potential Temperature'
            PTEMP.attrs['unit'] = 'degC'
            that.append(PTEMP)

        # Create a dataset with all new variables:
        that = xr.merge(that)
        # Add to the dataset essential Argo variables (allows to keep using the argo accessor):
        that = that.assign({
            k: this[k]
            for k in [
                'TIME', ' LATITUDE', 'LONGITUDE', 'PRES', 'PRES_ADJUSTED',
                'PLATFORM_NUMBER', 'CYCLE_NUMBER', 'DIRECTION'
            ] if k in this
        })
        # Manage output:
        if inplace:
            # Merge previous with new variables
            for v in that.variables:
                this[v] = that[v]
            if to_profile:
                this = this.argo.point2profile()
            for k in this:
                if k not in self._obj:
                    self._obj[k] = this[k]
            return self._obj
        else:
            if to_profile:
                return that.argo.point2profile()
            else:
                return that
コード例 #16
0
    def __init__(self, time, sal, temp_ext, temp_int, pres_ext, pres_int, lon,
                 lat, ballast, pitch, profile, navresource, tau,
                 speed_through_water, **param):
        # Questions:
        # is dzdt spiky?
        # do values need to be interpolated?

        # Parse input variables:
        self.timestamp = time
        self.time = date2float(self.timestamp)

        self.external_pressure = pres_ext
        self.internal_pressure = pres_int
        self.external_temperature = temp_ext
        self.internal_temperature = temp_int

        self.longitude = lon
        self.latitude = lat
        self.profile = profile

        self.salinity = sal

        self.ballast = ballast / 1000000  # m^3
        self.pitch = np.deg2rad(pitch)  # rad

        self.navresource = navresource

        self.tau = tau
        self.speed_through_water = speed_through_water

        # Rerefence parameters for scaling and initial guesses:
        self.param_reference = dict({
            'mass': 60,  # Vehicle mass in kg
            'vol0':
            0.06,  # Reference volume in m**3, with ballast at 0 (with -500 to 500 range), at surface pressure and 20 degrees C
            'area_w': 0.24,  # Wing surface area, m**2
            'Cd_0': 0.046,  #
            'Cd_1': 2.3,  #             
            'Cl': 2.0,  # Negative because wrong convention on theta
            'comp_p':
            4.7e-06,  #1.023279317627415e-06, #Pressure dependent hull compression factor
            'comp_t':
            8.9e-05,  #1.5665248101730484e-04, # Temperature dependent hull compression factor
            'SSStau': 18.5  #characteristic response time of the glider in sec
        })

        self.param = self.param_reference.copy()
        for k, v in param.items():
            self.param[k] = v
        self.param_initial = self.param

        self.depth = gsw.z_from_p(
            self.external_pressure, self.latitude
        )  # m . Note depth (Z) is negative, so diving is negative dZdt
        self.dZdt = np.gradient(self.depth, self.time)  # m.s-1

        self.g = gsw.grav(self.latitude, self.external_pressure)

        self.SA = gsw.SA_from_SP(self.salinity, self.external_pressure,
                                 self.longitude, self.latitude)
        self.CT = gsw.CT_from_t(self.SA, self.external_temperature,
                                self.external_pressure)
        self.rho = gsw.rho(self.SA, self.CT, self.external_pressure)

        ### Basic model
        # Relies on steady state assumption that buoyancy, weight, drag and lift cancel out when not accelerating.
        # F_B - cos(glide_angle)*F_L - sin(glide_angle)*F_D - F_g = 0
        # cos(glide_angle)*F_L + sin(glide_angle)*F_D = 0

        # Begin with an initial computation of angle of attack and speed through water:
        self.model_function()

        ### Get good datapoints to regress over
        self._valid = np.full(np.shape(self.pitch), True)
        self._valid[self.external_pressure < 5] = False
        self._valid[np.abs(self.pitch) < 0.2] = False  # TODO change back to 15
        self._valid[np.abs(self.pitch) > 0.6] = False  # TODO change back to 15
        self._valid[np.abs(np.gradient(self.dZdt, self.time)) >
                    0.0005] = False  # Accelerations
        self._valid[np.gradient(self.pitch, self.time) ==
                    0] = False  # Rotation
        self._valid = self._valid & (
            (navresource == 100) | (navresource == 117)
        )  #100=glider going down & 117=glider going up (=> not at surface or inflecting)

        # Do first pass regression on vol parameters, or volume and hydro?
        self.regression_parameters = ('vol0', 'Cd_0', 'Cd_1', 'Cl', 'comp_p',
                                      'comp_t')
コード例 #17
0
def find_isopycnals(p_btl_col, t_btl_col, sal_btl_col, dov_btl_col,
                    lat_btl_col, lon_btl_col, btl_data, p_col, t_col, sal_col,
                    dov_col, lat_col, lon_col, time_data):
    """find_iscopycnals

    p_btl_col:   Pressure column for bottle data
    t_btl_col:   Temperature column for bottle data
    sal_btl_col: Salinity column for bottle data
    dov_btl_col: Oxygen voltage column for bottle data
    lat_btl_col: Latitude bottle column for bottle data
    lon_btl_col: Longitude bottle column for bottle data
    btl_data:    Bottle data ndarray
    p_col:       Pressure column for bottle data
    t_col:       Temperature column for bottle data
    sal_col:     Salinity column for bottle data
    dov_col:     Oxygen voltage column for bottle data
    lat_col:     Latitude column for bottle data
    lon_col:     Longitude column for bottle data
    time_data:   Time data ndarray

    """

    time_sigma = []
    CT = gsw.CT_from_t(time_data[sal_col], time_data[t_col], time_data[p_col])
    SA = gsw.SA_from_SP(time_data[sal_col], time_data[p_col],
                        time_data[lon_col], time_data[lat_col])
    time_sigma = gsw.sigma0(SA, CT)

    # Pressure-bounded isopycnal search.
    # Based on maximum decent rate and package size.
    CT = gsw.CT_from_t(btl_data[sal_btl_col], btl_data[t_btl_col],
                       btl_data[p_btl_col])
    SA = gsw.SA_from_SP(btl_data[sal_btl_col], btl_data[p_btl_col],
                        btl_data[lon_btl_col], btl_data[lat_btl_col])
    btl_sigma = gsw.sigma0(SA, CT)
    for i in range(0, len(btl_data[p_btl_col])):
        #CT = gsw.CT_from_t(btl_data[sal_btl_col][i],btl_data[t_btl_col][i],btl_data[p_btl_col][i])
        #SA = gsw.SA_from_SP(btl_data[sal_btl_col][i],btl_data[p_btl_col][i],btl_data[lon_btl_col][i],btl_data[lat_btl_col][i])
        #btl_sigma = gsw.sigma0(SA,CT)
        p_indx = find_nearest(time_data[p_col], btl_data[p_btl_col][i])
        indx = find_nearest(
            time_sigma[p_indx - int(24 * 1.5):p_indx + int(24 * 1.5)],
            btl_sigma[i])

        #print('Bottle:')
        #print('Sigma: '+str(btl_sigma))
        #print('Pres: '+str(btl_data[p_btl_col][i]))
        #print('Temp: '+str(btl_data[t_btl_col][i]))
        #print('Salt: '+str(btl_data[sal_btl_col][i]))
        #print('Pressure: '+str(p_indx)+' '+str(indx+p_indx))
        #print('Sigma: '+str(time_sigma[indx+p_indx]))
        #print('Pres: '+str(time_data[p_col][indx+p_indx]))
        #print('Temp: '+str(time_data[t_col][indx+p_indx]))
        #print('Salt: '+str(time_data[sal_col][indx+p_indx]))

        if indx + p_indx > len(time_sigma):
            btl_data[t_btl_col][i] = time_data[t_col][len(time_data) - 1]
            btl_data[sal_btl_col][i] = time_data[sal_col][len(time_data) - 1]
            btl_data[dov_btl_col][i] = time_data[dov_col][len(time_data) - 1]
        else:
            btl_data[t_btl_col][i] = time_data[t_col][indx + p_indx]
            btl_data[sal_btl_col][i] = time_data[sal_col][indx + p_indx]
            btl_data[dov_btl_col][i] = time_data[dov_col][indx + p_indx]

    return btl_data
コード例 #18
0
def prepare_oxy(btl_df, time_df, ssscc_list):
    """
    Calculate oxygen-related variables needed for calibration:
    sigma, oxygen solubility (OS), and bottle oxygen

    Parameters
    ----------
    btl_df : DataFrame
        CTD data at bottle stops
    time_df : DataFrame
        Continuous CTD data
    ssscc_list : list of str
        List of stations to process

    Returns
    -------

    """
    # Calculate SA and CT
    btl_df["SA"] = gsw.SA_from_SP(
        btl_df[cfg.column["sal"]],
        btl_df[cfg.column["p_btl"]],
        btl_df[cfg.column["lon_btl"]],
        btl_df[cfg.column["lat_btl"]],
    )
    btl_df["CT"] = gsw.CT_from_t(
        btl_df["SA"],
        btl_df[
            cfg.column["t1_btl"]],  # oxygen sensor is on primary line (ie t1)
        btl_df[cfg.column["p_btl"]],
    )
    time_df["SA"] = gsw.SA_from_SP(
        time_df[cfg.column["sal"]],
        time_df[cfg.column["p"]],
        time_df[cfg.column["lon_btl"]],
        time_df[cfg.column["lat_btl"]],
    )
    time_df["CT"] = gsw.CT_from_t(
        time_df["SA"],
        time_df[cfg.column["t1"]],  # oxygen sensor is on primary line (ie t1)
        time_df[cfg.column["p"]],
    )

    # calculate sigma
    btl_df["sigma_btl"] = gsw.sigma0(btl_df["SA"], btl_df["CT"])
    time_df["sigma_btl"] = gsw.sigma0(time_df["SA"], time_df["CT"])

    # Calculate oxygen solubility in µmol/kg
    btl_df["OS"] = gsw.O2sol(
        btl_df["SA"],
        btl_df["CT"],
        btl_df[cfg.column["p_btl"]],
        btl_df[cfg.column["lon_btl"]],
        btl_df[cfg.column["lat_btl"]],
    )
    time_df["OS"] = gsw.O2sol(
        time_df["SA"],
        time_df["CT"],
        time_df[cfg.column["p"]],
        time_df[cfg.column["lon"]],
        time_df[cfg.column["lat"]],
    )
    # Convert CTDOXY units
    btl_df["CTDOXY"] = oxy_ml_to_umolkg(btl_df["CTDOXY1"], btl_df["sigma_btl"])
    # Calculate bottle oxygen
    btl_df[cfg.column["oxy_btl"]] = calculate_bottle_oxygen(
        ssscc_list,
        btl_df["SSSCC"],
        btl_df["TITR_VOL"],
        btl_df["TITR_TEMP"],
        btl_df["FLASKNO"],
    )
    btl_df[cfg.column["oxy_btl"]] = oxy_ml_to_umolkg(
        btl_df[cfg.column["oxy_btl"]], btl_df["sigma_btl"])
    btl_df["OXYGEN_FLAG_W"] = flagging.nan_values(
        btl_df[cfg.column["oxy_btl"]])
    # Load manual OXYGEN flags
    if Path("data/oxygen/manual_oxy_flags.csv").exists():
        manual_flags = pd.read_csv("data/oxygen/manual_oxy_flags.csv",
                                   dtype={"SSSCC": str})
        for _, flags in manual_flags.iterrows():
            df_row = (btl_df["SSSCC"] == flags["SSSCC"]) & (
                btl_df["btl_fire_num"] == flags["Bottle"])
            btl_df.loc[df_row, "OXYGEN_FLAG_W"] = flags["Flag"]

    return True
コード例 #19
0
    def __init__(self,eyed, data,tempunit,salunit):
        ##id of profiles plus info
        if tempunit not in ["insitu","conservative","potential"]:
            raise ValueError("This temperature unit is not supported")
        if salunit not in ["practical","absolute","insitu"]:
            raise ValueError("This salinity unit is not supported")
        if not {"sal","temp","pres","lat","lon"}.issubset(data.keys()):
            raise ValueError("This does not contain the required information")
        if abs(max(data["pres"])-min(data["pres"])) <50:
            print(data["pres"])
            raise ValueError("This does not contain enough pressure information ")
        self.eyed = eyed
        self.lat = np.abs(data["lat"])
        self.maplat = data["lat"]
        self.lon = data["lon"]
        self.f = gsw.f(self.lat)
        self.gamma = (9.8)/(self.f*1025.0)
        if "time" in data.keys():
            self.time = data["time"]
        if "cruise" in data.keys():
            self.cruise = data["cruise"]#+str(self.time.year)
        if "station" in data.keys():
            self.station = data["station"]#+str(self.time.year)
        if "knownns" in data.keys():
            self.knownns = data["knownns"]
        else:
            self.knownns = {}
        if "relcoord" in data.keys():
            self.relcoord = data["relcoord"]
        if "knownu" in data.keys():
            self.knownu = data["knownu"]
            self.knownv = data["knownv"]
        if "knownpsi" in data.keys():
            self.knownpsi = data["knownpsi"]
        if "kapredi" in data.keys():
            self.kapredi = data["kapredi"]
            self.kapgm = data["kapgm"]
            self.diffkr = data["diffkr"]
        #Temerature Salinity and Pressure
        self.temps = np.asarray(data["temp"])
        self.sals = np.asarray(data["sal"])
        self.pres = np.abs(np.asarray(data["pres"]))
        if hasattr(self.temps,"mask"):
            print("mask")
            flter = np.logical_or(~self.temps.mask,~self.sals.mask)
            self.temps = self.temps[flter]
            self.sals = self.sals[flter]
            self.pres = self.pres[flter]
        if np.isnan(self.temps).any() or np.isnan(self.sals).any():
            print("huh")
        if salunit == "practical":
            self.sals = gsw.SA_from_SP(self.sals,self.pres,self.lon,self.maplat)

        if tempunit == "potential":
            self.temps = gsw.CT_from_pt(self.sals,self.temps)

        if tempunit == "insitu":
            self.temps = gsw.CT_from_t(self.sals,self.temps,np.abs(self.pres))

        s = np.argsort(self.pres)
        self.temps = self.temps[s]
        self.sals = self.sals[s]
        self.pres = self.pres[s]
        ##Interpolated Temperature, Salinity, and Pressure
        self.itemps = []
        self.isals = []
        self.ipres = []
        theta = np.deg2rad(self.lat)
        r = (90-self.lon) *111*1000
        x = (r*np.cos(theta))
        y = (r*np.sin(theta))
        self.x = x
        self.y = y
        self.idensities = []
        self.neutraldepth = {}
        self.interpolate()
コード例 #20
0
ファイル: core_funcs.py プロジェクト: ouc-cook/Ray_Tracing
    def createFuncs(self, X, t, lonpad=1.5, latpad=1.5, tpad=1.5):
        """
        Pass data fields of satgem to generate interpolation functions 
    
        Generate Interpolation functions 

        Paramaters
        ----------
        X: Position Vector
        t: initial time (center of the interpolation field)
        """
        if tpad < 7:
            tpad = 7

        # Get indicies for subset of satgem/bathy data
        lonind = self.gem.temp.lon.sel(lon=slice(X[0] - lonpad, X[0] + lonpad))
        clonind = self.gem.V.clon.sel(clon=slice(X[0] - lonpad, X[0] + lonpad))
        latind = self.gem.temp.lat.sel(lat=slice(X[1] - latpad, X[1] + latpad))
        clatind = self.gem.U.clat.sel(clat=slice(X[1] - latpad, X[1] + latpad))
        tind = self.gem.temp.time.sel(time=slice(t - tpad, t + tpad))

        blonind = self.bathy_file.lon.sel(lon=slice(X[0] - lonpad, X[0] +
                                                    lonpad))
        blatind = self.bathy_file.lat.sel(lat=slice(X[1] - latpad, X[1] +
                                                    latpad))

        bsub = self.bathy_file.elevation.sel(lon=blonind, lat=blatind)

        setattr(
            self, 'bathy',
            LinearNDInterpolatorExt((blonind, blatind),
                                    bsub.T,
                                    fill_value=None))

        N2 = []
        rho = []
        for i in range(tind.shape[0]):
            SA = gsw.SA_from_SP(
                self.gem.sal.sel(lon=lonind, lat=latind, time=tind[i]),
                self.gem.depth[:], X[0], X[1])
            CT = gsw.CT_from_t(
                SA, self.gem.temp.sel(lon=lonind, lat=latind, time=tind[0]),
                self.gem.depth[:])
            if i == 0:
                # since the pmid grid will be uniform, only save once
                n2i, pmid = gsw.Nsquared(SA, CT, self.gem.depth, axis=2)
                N2.append(n2i)
                rho.append(gsw.sigma0(
                    SA,
                    CT,
                ))
            else:
                N2.append(gsw.Nsquared(SA, CT, self.gem.depth, axis=2)[0])
                rho.append(gsw.sigma0(
                    SA,
                    CT,
                ))

        FN2 = LinearNDInterpolatorExt(
            (self.gem.lon.sel(lon=lonind), self.gem.lat.sel(lat=latind),
             pmid[0, 0, :], self.gem.time.sel(time=tind)), np.stack(N2,
                                                                    axis=3))

        rho1 = LinearNDInterpolatorExt(
            (self.gem.lon.sel(lon=lonind), self.gem.lat.sel(lat=latind),
             self.gem.depth, self.gem.time.sel(time=tind)),
            np.stack(rho, axis=3))

        setattr(self, 'N2', FN2)
        setattr(self, 'rho', rho1)

        N2 = np.absolute(np.stack(N2, axis=3))
        N2 = np.sqrt(N2)
        # Don't actually need this as a dataArray but its used as one further down and im too lazy to change it
        N2 = xr.DataArray(N2,
                          coords=[
                              self.gem.lon.sel(lon=lonind),
                              self.gem.lat.sel(lat=latind), pmid[0, 0, :],
                              self.gem.time.sel(time=tind)
                          ],
                          dims=['lon', 'lat', 'depth', 'time'],
                          name='N2')

        Usub = self.gem.U.sel(lon=lonind, clat=clatind, time=tind)
        Tsub = self.gem.temp.sel(lon=lonind, lat=latind, time=tind)
        Vsub = self.gem.V.sel(clon=clonind, lat=latind, time=tind)

        # space and time Gradients
        delt = Usub.time.diff(dim='time') * 24 * 60 * \
            60  # time delta in seconds

        # U gradients
        dxu = gsw.distance(np.meshgrid(Usub.lon, Usub.clat)[0],
                           np.meshgrid(Usub.lon, Usub.clat)[1],
                           axis=1)

        dxu = np.repeat(np.repeat(dxu.T[:, :, np.newaxis],
                                  Usub.shape[2],
                                  axis=2)[:, :, :, np.newaxis],
                        Usub.shape[3],
                        axis=3)

        dyu = gsw.distance(np.meshgrid(Usub.lon, Usub.clat)[0],
                           np.meshgrid(Usub.lon, Usub.clat)[1],
                           axis=0)
        dyu = np.repeat(np.repeat(dyu.T[:, :, np.newaxis],
                                  Usub.shape[2],
                                  axis=2)[:, :, :, np.newaxis],
                        Usub.shape[3],
                        axis=3)
        # V gradients
        dxv = gsw.distance(np.meshgrid(Vsub.clon, Vsub.lat)[0],
                           np.meshgrid(Vsub.clon, Vsub.lat)[1],
                           axis=1)

        dxv = np.repeat(np.repeat(dxv.T[:, :, np.newaxis],
                                  Usub.shape[2],
                                  axis=2)[:, :, :, np.newaxis],
                        Usub.shape[3],
                        axis=3)

        dyv = gsw.distance(np.meshgrid(Vsub.clon, Vsub.lat)[0],
                           np.meshgrid(Vsub.clon, Vsub.lat)[1],
                           axis=0)
        dyv = np.repeat(np.repeat(dyv.T[:, :, np.newaxis],
                                  Usub.shape[2],
                                  axis=2)[:, :, :, np.newaxis],
                        Usub.shape[3],
                        axis=3)
        # N2 gradient
        dxn = gsw.distance(np.meshgrid(N2.lon, N2.lat)[0],
                           np.meshgrid(N2.lon, N2.lat)[1],
                           axis=1)

        dxn = np.repeat(np.repeat(dxn.T[:, :, np.newaxis], N2.shape[2],
                                  axis=2)[:, :, :, np.newaxis],
                        N2.shape[3],
                        axis=3)

        dyn = gsw.distance(np.meshgrid(N2.lon, N2.lat)[0],
                           np.meshgrid(N2.lon, N2.lat)[1],
                           axis=0)
        dyn = np.repeat(np.repeat(dyn.T[:, :, np.newaxis], N2.shape[2],
                                  axis=2)[:, :, :, np.newaxis],
                        N2.shape[3],
                        axis=3)

        dz = np.nanmean(np.diff(Usub.depth))

        # Spatial Gradient revisied grids
        clat = (Usub.clat[:-1] + np.diff(Usub.clat) / 2)
        clon = (Vsub.clon[:-1] + np.diff(Vsub.clon) / 2)
        lat = (N2.lat[:-1] + np.diff(N2.lat) / 2)
        lon = (N2.lon[:-1] + np.diff(N2.lon) / 2)
        time = Usub.time[:-1] + np.diff(Usub.time) / 2
        pmid = pmid[5, 5, :]
        pmidn = pmid[:-1] + np.diff(pmid) / 2

        setattr(
            self, 'dudx',
            LinearNDInterpolatorExt((lon, Usub.clat, Usub.depth, Usub.time),
                                    Usub.diff(dim='lon').values / dxu,
                                    fill_value=0))
        setattr(
            self, 'dudy',
            LinearNDInterpolatorExt((Usub.lon, clat, Usub.depth, Usub.time),
                                    Usub.diff(dim='clat').values / dyu,
                                    fill_value=0))
        setattr(
            self, 'dudz',
            LinearNDInterpolatorExt((Usub.lon, Usub.clat, pmid, Usub.time),
                                    Usub.diff(dim='depth').values / dz,
                                    fill_value=0))

        setattr(
            self, 'dvdx',
            LinearNDInterpolatorExt((clon, Vsub.lat, Usub.depth, Usub.time),
                                    Vsub.diff(dim='clon').values / dxv,
                                    fill_value=1343431))
        setattr(
            self, 'dvdy',
            LinearNDInterpolatorExt((Vsub.clon, lat, Usub.depth, Usub.time),
                                    Vsub.diff(dim='lat').values / dyv,
                                    fill_value=0))
        setattr(
            self, 'dvdz',
            LinearNDInterpolatorExt((Vsub.clon, Vsub.lat, pmid, Vsub.time),
                                    Vsub.diff(dim='depth').values / dz,
                                    fill_value=0))

        setattr(
            self, 'dndx',
            LinearNDInterpolatorExt((lon, N2.lat, N2.depth, N2.time),
                                    N2.diff(dim='lon').values / dxn,
                                    fill_value=0))
        setattr(
            self, 'dndy',
            LinearNDInterpolatorExt((N2.lon, lat, N2.depth, N2.time),
                                    N2.diff(dim='lat').values / dyn,
                                    fill_value=0))
        setattr(
            self, 'dndz',
            LinearNDInterpolatorExt((N2.lon, N2.lat, pmidn, N2.time),
                                    N2.diff(dim='depth').values / dz,
                                    fill_value=0))

        # Time Gradients Final
        delt = Usub.time.diff(dim='time') * 24 * 60 * \
            60  # time delta in seconds
        dudt = []
        dvdt = []
        dn2dt = []
        for i, dt1 in enumerate(delt):
            dudt.append(Usub.diff(dim='time')[:, :, :, i] / dt1)
            dvdt.append(Vsub.diff(dim='time')[:, :, :, i] / dt1)
            dn2dt.append(N2.diff(dim='time')[:, :, :, i] / dt1)

        setattr(
            self, 'dndt',
            LinearNDInterpolatorExt((N2.lon, N2.lat, N2.depth, time),
                                    np.stack(dn2dt, axis=3),
                                    fill_value=0))

        setattr(
            self, 'dudt',
            LinearNDInterpolatorExt((Usub.lon, Usub.clat, Usub.depth, time),
                                    np.stack(dudt, axis=3),
                                    fill_value=0))

        setattr(
            self, 'dvdt',
            LinearNDInterpolatorExt((Vsub.clon, Vsub.lat, Vsub.depth, time),
                                    np.stack(dvdt, axis=3),
                                    fill_value=0))

        setattr(
            self, 'U',
            LinearNDInterpolatorExt(
                (Usub.lon, Usub.clat, Usub.depth, Usub.time), Usub.values))

        setattr(
            self, 'V',
            LinearNDInterpolatorExt(
                (Vsub.clon, Vsub.lat, Vsub.depth, Vsub.time), Vsub.values))

        setattr(
            self, 'T',
            LinearNDInterpolatorExt(
                (Tsub.lon, Tsub.lat, Tsub.depth, Tsub.time), Tsub.values))

        lonlim = [N2.lon.min(), N2.lon.max()]
        latlim = [N2.lat.min(), N2.lat.max()]
        tlim = [N2.time.min(), N2.time.max()]

        return lonlim, latlim, tlim
コード例 #21
0
# Calculate N$^2$ from the CTD data, smooth it and then translate it to the linear equation of state.
# $$
# N^2 = -\frac{g}{\rho} \frac{d \rho}{dz}
# $$
# $$
# \rho = \alpha_T \theta
# $$
# $$
# T_{z0} = \frac{N^2}{g \alpha_T}
# $$

# %%
zshift = -50  # shift peak by how many metres

tmp = sec9.where(sec9.station == 12, drop=True)
SA = gsw.SA_from_SP(tmp.s.squeeze(), tmp.p.squeeze(), tmp.lon, tmp.lat)
CT = gsw.CT_from_t(SA, tmp.t.squeeze(), tmp.p.squeeze())
N2, pmid = gsw.Nsquared(SA, CT, tmp.p.squeeze(), tmp.lat)
zmid = utils.mid(tmp.z.data)
good = np.isfinite(N2)
N2smooth = utils.convolve_smooth(N2[good], 100)
zs = zmid[good]

imax, _ = sp.signal.find_peaks(N2smooth, height=(3e-6, 5e-6), prominence=2e-6)
hw = 220
ispeak = (zs > zs[imax - hw]) & (zs < zs[imax + hw])
N2filled = np.interp(zs, zs[~ispeak], N2smooth[~ispeak])
N2peak = (N2smooth - N2filled)
fpeak = sp.interpolate.interp1d(zs,
                                N2peak,
                                bounds_error=False,
コード例 #22
0
ファイル: xarray.py プロジェクト: ocefpaf/argopy
    def teos10(
        self,
        vlist: list = ["SA", "CT", "SIG0", "N2", "PV", "PTEMP"],
        inplace: bool = True,
    ):
        """ Add TEOS10 variables to the dataset

        By default, adds: 'SA', 'CT'
        Other possible variables: 'SIG0', 'N2', 'PV', 'PTEMP', 'SOUND_SPEED'
        Relies on the gsw library.

        If one exists, the correct CF standard name will be added to the attrs.

        Parameters
        ----------
        vlist: list(str)
            List with the name of variables to add.
            Must be a list containing one or more of the following string values:

            * `"SA"`
                Adds an absolute salinity variable
            * `"CT"`
                Adds a conservative temperature variable
            * `"SIG0"`
                Adds a potential density anomaly variable referenced to 0 dbar
            * `"N2"`
                Adds a buoyancy (Brunt-Vaisala) frequency squared variable.
                This variable has been regridded to the original pressure levels in the Dataset using a linear interpolation.
            * `"PV"`
                Adds a planetary vorticity variable calculated from :math:`\\frac{f N^2}{\\text{gravity}}`.
                This is not a TEOS-10 variable from the gsw toolbox, but is provided for convenience.
                This variable has been regridded to the original pressure levels in the Dataset using a linear interpolation.
            * `"PTEMP"`
                Adds a potential temperature variable
            * `"SOUND_SPEED"`
                Adds a sound speed variable
            
        inplace: boolean, True by default
            If True, return the input :class:`xarray.Dataset` with new TEOS10 variables added as a new :class:`xarray.DataArray`
            If False, return a :class:`xarray.Dataset` with new TEOS10 variables

        Returns
        -------
        :class:`xarray.Dataset`
        """
        if not with_gsw:
            raise ModuleNotFoundError(
                "This functionality requires the gsw library")

        allowed = ['SA', 'CT', 'SIG0', 'N2', 'PV', 'PTEMP', 'SOUND_SPEED']
        if any(var not in allowed for var in vlist):
            raise ValueError(
                f"vlist must be a subset of {allowed}, instead found {vlist}")

        warnings.warn(
            "Default variables will be reduced to 'SA' and 'CT' in 0.1.9",
            category=FutureWarning)

        this = self._obj

        to_profile = False
        if self._type == "profile":
            to_profile = True
            this = this.argo.profile2point()

        # Get base variables as numpy arrays:
        psal = this['PSAL'].values
        temp = this['TEMP'].values
        pres = this['PRES'].values
        lon = this['LONGITUDE'].values
        lat = this['LATITUDE'].values

        # Coriolis
        f = gsw.f(lat)

        # Absolute salinity
        sa = gsw.SA_from_SP(psal, pres, lon, lat)

        # Conservative temperature
        ct = gsw.CT_from_t(sa, temp, pres)

        # Potential Temperature
        if "PTEMP" in vlist:
            pt = gsw.pt_from_CT(sa, ct)

        # Potential density referenced to surface
        if "SIG0" in vlist:
            sig0 = gsw.sigma0(sa, ct)

        # N2
        if "N2" in vlist or "PV" in vlist:
            n2_mid, p_mid = gsw.Nsquared(sa, ct, pres, lat)
            # N2 on the CT grid:
            ishallow = (slice(0, -1), Ellipsis)
            ideep = (slice(1, None), Ellipsis)

            def mid(x):
                return 0.5 * (x[ideep] + x[ishallow])

            n2 = np.zeros(ct.shape) * np.nan
            n2[1:-1] = mid(n2_mid)

        # PV:
        if "PV" in vlist:
            pv = f * n2 / gsw.grav(lat, pres)

        # Sound Speed:
        if 'SOUND_SPEED' in vlist:
            cs = gsw.sound_speed(sa, ct, pres)

        # Back to the dataset:
        that = []
        if 'SA' in vlist:
            SA = xr.DataArray(sa, coords=this['PSAL'].coords, name='SA')
            SA.attrs['long_name'] = 'Absolute Salinity'
            SA.attrs['standard_name'] = 'sea_water_absolute_salinity'
            SA.attrs['unit'] = 'g/kg'
            that.append(SA)

        if 'CT' in vlist:
            CT = xr.DataArray(ct, coords=this['TEMP'].coords, name='CT')
            CT.attrs['long_name'] = 'Conservative Temperature'
            CT.attrs['standard_name'] = 'sea_water_conservative_temperature'
            CT.attrs['unit'] = 'degC'
            that.append(CT)

        if 'SIG0' in vlist:
            SIG0 = xr.DataArray(sig0, coords=this['TEMP'].coords, name='SIG0')
            SIG0.attrs[
                'long_name'] = 'Potential density anomaly with reference pressure of 0 dbar'
            SIG0.attrs['standard_name'] = 'sea_water_sigma_theta'
            SIG0.attrs['unit'] = 'kg/m^3'
            that.append(SIG0)

        if 'N2' in vlist:
            N2 = xr.DataArray(n2, coords=this['TEMP'].coords, name='N2')
            N2.attrs['long_name'] = 'Squared buoyancy frequency'
            N2.attrs['unit'] = '1/s^2'
            that.append(N2)

        if 'PV' in vlist:
            PV = xr.DataArray(pv, coords=this['TEMP'].coords, name='PV')
            PV.attrs['long_name'] = 'Planetary Potential Vorticity'
            PV.attrs['unit'] = '1/m/s'
            that.append(PV)

        if 'PTEMP' in vlist:
            PTEMP = xr.DataArray(pt, coords=this['TEMP'].coords, name='PTEMP')
            PTEMP.attrs['long_name'] = 'Potential Temperature'
            PTEMP.attrs['standard_name'] = 'sea_water_potential_temperature'
            PTEMP.attrs['unit'] = 'degC'
            that.append(PTEMP)

        if 'SOUND_SPEED' in vlist:
            CS = xr.DataArray(cs,
                              coords=this['TEMP'].coords,
                              name='SOUND_SPEED')
            CS.attrs['long_name'] = 'Speed of sound'
            CS.attrs['standard_name'] = 'speed_of_sound_in_sea_water'
            CS.attrs['unit'] = 'm/s'
            that.append(CS)

        # Create a dataset with all new variables:
        that = xr.merge(that)
        # Add to the dataset essential Argo variables (allows to keep using the argo accessor):
        that = that.assign({
            k: this[k]
            for k in [
                "TIME",
                " LATITUDE",
                "LONGITUDE",
                "PRES",
                "PRES_ADJUSTED",
                "PLATFORM_NUMBER",
                "CYCLE_NUMBER",
                "DIRECTION",
            ] if k in this
        })
        # Manage output:
        if inplace:
            # Merge previous with new variables
            for v in that.variables:
                this[v] = that[v]
            if to_profile:
                this = this.argo.point2profile()
            for k in this:
                if k not in self._obj:
                    self._obj[k] = this[k]
            return self._obj
        else:
            if to_profile:
                return that.argo.point2profile()
            else:
                return that
コード例 #23
0
 ## Interpolate location
 lat_interp_time=interpolate.interp1d(date_reform_num, lat)
 lat_interp=lat_interp_time(new_dates_num)
 lon_interp_time=interpolate.interp1d(date_reform_num, lon)
 lon_interp=lon_interp_time(new_dates_num)
 
 for l in np.arange(lat_array_pd.shape[0]):
     # rows: Pressure, columns dates 
     lat_array_pd[l,:]=lat_interp.T
     lon_array_pd[l,:]=lon_interp.T
     
 P_PD=np.zeros(T_PD.shape)
 for l in np.arange(len(new_dates)):
     P_PD[:,l]=pres_range
     
 SA=gsw.SA_from_SP(S_PD,P_PD,lon_array_pd,lat_array_pd)
 CT=gsw.CT_from_t(SA, T_PD, P_PD)
 oxy_eq=gsw.O2sol(SA, CT, P_PD, lon_array_pd, lat_array_pd)
 OS_PD=O_PD/oxy_eq*100
 
 D_PD=np.zeros(T_PD.shape)
 D_PD[:]=np.NaN
 
 for r in np.arange(D_PD.shape[0]):
     for c in np.arange(D_PD.shape[1]):
         if np.isnan(SA[r,c]) == False and np.isnan(CT[r,c]) == False:
             D_PD[r,c]=gsw.sigma0(SA[r,c], CT[r,c])
         
 plt.figure(figsize=(figx, figy))
 plt.pcolormesh(X,Y,OS_PD ,vmin=minOsat, vmax=maxOsat, cmap=cmo.haline)
 plt.gca().invert_yaxis()
コード例 #24
0
def oxygen(netCDFfile):
    ds = Dataset(netCDFfile, 'a')

    var_temp = ds.variables["TEMP"]
    var_psal = ds.variables["PSAL"]
    var_pres = ds.variables["PRES"]

    t = var_temp[:]
    SP = var_psal[:]
    p = var_pres[:]

    SA = gsw.SA_from_SP(SP, p, ds.longitude, ds.latitude)
    CT = gsw.CT_from_t(SA, t, p)
    pt = gsw.pt0_from_t(SA, t, p)

    sigma_theta0 = gsw.sigma0(SA, CT)
    oxsol = ds.variables["OXSOL"][:]

    ts = np.log((298.15 - t) / (273.15 + t))

    # psal correction, from Aanderra TD-218, Gordon and Garcia oxygaen solubility salinity coefficents
    B0 = -6.24097e-3
    C0 = -3.11680e-7
    B1 = -6.93498e-3
    B2 = -6.90358e-3
    B3 = -4.29155e-3

    psal_correction =  np.exp(SP *(B0 + B1 * ts + B2 * np.power(ts, 2) + B3 * np.power(ts, 3)) + np.power(SP, 2) * C0)

    # get correction slope, offset
    slope = 1.0
    offset = 0.0
    try:
        slope = ds.variables['DOX2_RAW'].calibration_slope
        offset = ds.variables['DOX2_RAW'].calibration_offset
    except AttributeError:
        pass

    # calculate disolved oxygen, umol/kg
    dox2_raw = ds.variables['DOX2_RAW'] * psal_correction * slope + offset
    dox2 = 1000 * dox2_raw / (sigma_theta0 + 1000)

    if 'DOX2' not in ds.variables:
        ncVarOut = ds.createVariable("DOX2", "f4", ("TIME",), fill_value=np.nan, zlib=True)  # fill_value=nan otherwise defaults to max
    else:
        ncVarOut = ds.variables['DOX2']

    ncVarOut[:] = dox2
    ncVarOut.units = "umol/kg"
    ncVarOut.comment = "calculated using DOX2 = DOX2_RAW * PSAL_CORRECTION / ((sigma_theta(P=0,Theta,S) + 1000).. Sea Bird AN 64, Aanderaa TD210 Optode Manual"
    ncVarOut.comment_calibration = "calibration slope " + str(slope) + " offset " + str(offset) + " umol/l"

    # calculate, and write the oxygen mass/seawater mass
    if 'DOX_MG' not in ds.variables:
        ncVarOut = ds.createVariable("DOXY", "f4", ("TIME",), fill_value=np.nan, zlib=True)  # fill_value=nan otherwise defaults to max
    else:
        ncVarOut = ds.variables['DOXY']

    ncVarOut[:] = dox2_raw / 31.24872
    ncVarOut.units = "mg/l"
    ncVarOut.comment = "calculated using DOXY =  * DOX2_RAW * PSAL_CORRECTION / 31.24872... Aanderaa TD210 Optode Manual"
    ncVarOut.comment_calibration = "calibration slope " + str(slope) + " offset " + str(offset) + " umol/l"

    # calculate and write oxygen solubility, ratio of disolved oxgen / oxygen solubility
    if 'DOXS' not in ds.variables:
        ncVarOut = ds.createVariable("DOXS", "f4", ("TIME",), fill_value=np.nan, zlib=True)  # fill_value=nan otherwise defaults to max
    else:
        ncVarOut = ds.variables['DOXS']

    ncVarOut[:] = dox2/oxsol
    ncVarOut.units = "1"
    ncVarOut.comment = "calculated using DOX2/OXSOL"

    # finish off, and close file

    # update the history attribute
    try:
        hist = ds.history + "\n"
    except AttributeError:
        hist = ""

    ds.setncattr('history', hist + datetime.utcnow().strftime("%Y-%m-%d") + " : added derived oxygen, DOX2, DOXS, DOX_MG")

    ds.close()
コード例 #25
0
def load_seals(sealdir, bathy_data):
    from datetime import datetime, date, timedelta
    # initialize
    maxNprof = 0
    ll = 0
    ll1 = 0
    l0 = 0
    dateFlNum = []

    XC = bathy_data[0]
    YC = bathy_data[1]
    x1 = bathy_data[3]
    x2 = bathy_data[4]
    y1 = bathy_data[5]
    y2 = bathy_data[6]

    # initialize big arrays
    CT_dataSO = np.nan * np.ones((100 * 310, 1000), '>f4')
    SA_dataSO = np.nan * np.ones((100 * 310, 1000), '>f4')
    SP_dataSO = np.nan * np.ones((100 * 310, 1000), '>f4')
    lon_dataSO = np.nan * np.ones((100 * 310), '>f4')
    lat_dataSO = np.nan * np.ones((100 * 310), '>f4')
    pr_dataSO = np.nan * np.ones((100 * 1000 * 310), '>f4')
    yySO = np.zeros((100 * 310), 'int32')
    mmSO = np.zeros((100 * 310), 'int32')
    IDSO = np.zeros((100 * 310), 'int32')

    data_list = [
        g for g in os.listdir(seadir)
        if g.endswith('nc') and not g.startswith('WOD')
    ]
    for ff_SO in data_list:
        #printff_SO
        tot_fl = 0
        iniDate = datetime(1950, 1, 1)
        minDate = datetime(2019, 1, 1).toordinal()
        #printff_SO
        file = os.path.join(sealdir, '%s' % ff_SO)
        # load data
        data = nc.Dataset(file)
        cruise = data.variables['PLATFORM_NUMBER'][:]
        if "CTD2020" in ff_SO:
            cruise = np.array(['202020%0.3i' % (int(f)) for f in cruise])
        elif "CTD2019" in ff_SO:
            cruise = np.array(['191919%0.3i' % (int(f)) for f in cruise])
        else:
            cruise = np.array(['%0.9i' % f for f in cruise])
        time = data.variables['JULD'][:]
        lon = data.variables['LONGITUDE'][:]
        lat = data.variables['LATITUDE'][:]
        pressPre = data.variables['PRES_ADJUSTED'][:].transpose()
        tempPre = data.variables['TEMP_ADJUSTED'][:].transpose()
        tempQC = data.variables['TEMP_ADJUSTED_QC'][:].transpose()
        psaPre = data.variables['PSAL_ADJUSTED'][:].transpose()
        psaQC = data.variables['PSAL_ADJUSTED_QC'][:].transpose()
        psaPre[np.where(psaQC == '4')] = np.nan
        tempPre[np.where(tempQC == '4')] = np.nan

        # let's get rid of some profiles that are out of the Amudsen Sea
        tot_fl += 1
        msk1 = np.where(np.logical_and(lon >= XC[x1], lon < XC[x2]))[0][:]
        msk2 = np.where(np.logical_and(lat[msk1] > YC[y1],
                                       lat[msk1] < YC[y2]))[0][:]

        lon = lon[msk1][msk2]
        lat = lat[msk1][msk2]
        time = time[msk1][msk2]
        pressPre = pressPre[:, msk1[msk2]]
        tempPre = tempPre[:, msk1[msk2]]
        psaPre = psaPre[:, msk1[msk2]]
        cruise = cruise[msk1][msk2]
        if time[0] + iniDate.toordinal() < minDate:
            minDate = time[0]
        if len(lon) > maxNprof:
            maxNprof = len(lon[~np.isnan(lon)])
            flN = ff_SO
        # remove data below 1000m (there are just so few seal profiles with data below 1000m anyway)
        msk = np.where(pressPre > 1000)
        pressPre[msk] = np.nan
        tempPre[msk] = np.nan
        psaPre[msk] = np.nan

        # interpolate and prepare the data
        lat = np.ma.masked_less(lat, -90)
        lon = np.ma.masked_less(lon, -500)
        lon[lon > 360.] = lon[lon > 360.] - 360.
        Nprof = np.linspace(1, len(lat), len(lat))
        # turn the variables upside down, to have from the surface to depth and not viceversa
        if any(pressPre[:10, 0] > 500.):
            pressPre = pressPre[::-1, :]
            psaPre = psaPre[::-1, :]
            tempPre = tempPre[::-1, :]
        # interpolate data on vertical grid with 1db of resolution (this is fundamental to then create profile means)
        fields = [psaPre, tempPre]
        press = np.nan * np.ones((1000, pressPre.shape[1]))
        for kk in range(press.shape[1]):
            press[:, kk] = np.arange(2, 1002, 1)
        psa = np.nan * np.ones((press.shape), '>f4')
        inst_temp = np.nan * np.ones((press.shape), '>f4')

        for ii, ff in enumerate(fields):
            for nn in range(pressPre.shape[1]):
                # only use non-nan values, otherwise it doesn't interpolate well
                try:
                    f1 = ff[:, nn][ff[:, nn].mask ==
                                   False]  #ff[:,nn][~np.isnan(ff[:,nn])]
                    f2 = pressPre[:, nn][ff[:, nn].mask == False]
                except:
                    f1 = ff[:, nn]
                    f2 = pressPre[:, nn]
                if len(f1) == 0:
                    f1 = ff[:, nn]
                    f2 = pressPre[:, nn]
                try:
                    sp = interpolate.interp1d(f2[~np.isnan(f1)],
                                              f1[~np.isnan(f1)],
                                              kind='linear',
                                              bounds_error=False,
                                              fill_value=np.nan)
                    ff_int = sp(press[:, nn])
                    if ii == 0:
                        psa[:, nn] = ff_int
                    elif ii == 1:
                        inst_temp[:, nn] = ff_int
                except:
                    print(
                        'At profile number %i, the float %s has only 1 record valid: len(f2)=%i'
                        % (nn, ff_SO, len(f2)))

        # To compute theta, I need absolute salinity [g/kg] from practical salinity (PSS-78) [unitless] and conservative temperature.
        sa = np.nan * np.ones((press.shape), '>f4')
        for kk in range(press.shape[1]):
            sa[:, kk] = gsw.SA_from_SP(psa[:, kk], press[:, 0], lon[kk],
                                       lat[kk])
        temp = gsw.CT_from_t(sa, inst_temp, press)
        ptemp = gsw.pt_from_CT(sa, temp)

        # mask out the profiles with :
        msk = np.where(lat < -1000)
        lat[msk] = np.nan
        lon[msk] = np.nan
        cruise[msk] = np.nan
        psa[msk] = np.nan
        sa[msk] = np.nan
        psa[sa == 0.] = np.nan
        sa[sa == 0.] = np.nan
        # use CT instead of PT
        temp[msk] = np.nan
        temp[temp == 0.] = np.nan

        # save the nprofiles
        NN = np.ones((temp.shape), 'int32')
        for ii in range(len(Nprof)):
            NN[:, ii] = Nprof[ii]

        lon_dataSO[ll1:ll1 + len(lon)] = lon
        lat_dataSO[ll1:ll1 + len(lon)] = lat
        CT_dataSO[ll:ll + len(sa[0, :]), :] = temp.T
        SA_dataSO[ll:ll + len(sa[0, :]), :] = sa.T
        SP_dataSO[ll:ll + len(sa[0, :]), :] = psa.T
        IDSO[ll1:ll1 + len(lon)] = [int(f) for f in cruise]

        # separate seasons
        dateFl = []
        for dd in time:
            floatDate = iniDate + timedelta(float(dd))
            dateFl.append(floatDate)
            dateFlNum = np.append(dateFlNum, floatDate.toordinal())

        yearsSO = np.array([int(dd.year) for dd in dateFl])
        monthsSO = np.array([int(dd.month) for dd in dateFl])
        SPR = np.where(np.logical_and(monthsSO >= 9, monthsSO <= 11))
        SUM = np.where(np.logical_or(monthsSO == 12, monthsSO <= 2))
        AUT = np.where(np.logical_and(monthsSO >= 3, monthsSO <= 5))
        WIN = np.where(np.logical_and(monthsSO >= 6, monthsSO <= 8))
        mmFlSO = monthsSO.copy()
        mmFlSO[SPR] = 1
        mmFlSO[SUM] = 2
        mmFlSO[AUT] = 3
        mmFlSO[WIN] = 4

        mmSO[ll:ll + len(sa[0, :])] = mmFlSO
        yySO[ll:ll + len(sa[0, :])] = yearsSO

        ll = ll + len(sa[0, :])
        ll1 = ll1 + len(lon)

        minArgoDate = timedelta(float(minDate)) + iniDate
        minArgoDate.strftime('%Y/%m/%d %H:%M:%S%z')
    # chop away the part of the array with no data
    CT_dataSO = CT_dataSO[:ll, :]
    SA_dataSO = SA_dataSO[:ll, :]
    SP_dataSO = SP_dataSO[:ll, :]
    IDSO = IDSO[:ll]
    lat_dataSO = lat_dataSO[:ll]
    lon_dataSO = lon_dataSO[:ll]
    mmSO = mmSO[:ll]
    yySO = yySO[:ll]

    # remove entire columns of NaNs
    idBad = []
    for ii in range(CT_dataSO.shape[1]):
        f0 = CT_dataSO[:, ii]
        f1 = f0[~np.isnan(f0)]
        if len(f1) == 0:
            idBad.append(ii)

    CT_dataSO = np.delete(CT_dataSO, idBad, 0)
    SA_dataSO = np.delete(SA_dataSO, idBad, 0)
    SP_dataSO = np.delete(SP_dataSO, idBad, 0)
    IDSO = np.delete(IDSO, idBad, 0)
    lon_dataSO = np.delete(lon_dataSO, idBad, 0)
    lat_dataSO = np.delete(lat_dataSO, idBad, 0)
    mmSO = np.delete(mmSO, idBad, 0)
    yySO = np.delete(yySO, idBad, 0)

    load_seals.profSO = [
        CT_dataSO, SA_dataSO, lon_dataSO, lat_dataSO, IDSO, SP_dataSO
    ]
    load_seals.temporalSO = [yySO, mmSO]

    return [load_seals.profSO, load_seals.temporalSO]
コード例 #26
0
if l_accurate and not l2d:

    vz = f_out.variables['deptht'][:]

    [nt, nk, nj, ni] = nmp.shape(xsal)

    xdepth = nmp.zeros((nk, nj, ni))

    # building 3d arrays of depth, lon and lat:
    for jk in range(nk):
        xdepth[jk, :, :] = vz[jk]

    # pressure should be in dbar and it's the same as the depth in metre actually:
    for jt in range(nt):
        print ' jt =', jt
        f_out.variables[cv_sal][jt, :, :, :] = gsw.SA_from_SP(
            xsal[jt, :, :, :], xdepth, -140., 0.)

else:
    # Fabien says it's enough:
    if l2d:
        f_out.variables[cv_sal][:, :, :] = xsal[:, :, :] * SSO / 35.
    else:
        f_out.variables[cv_sal][:, :, :, :] = xsal[:, :, :, :] * SSO / 35.

f_out.variables[
    cv_sal].long_name = 'Absolute Salinity (TEOS10) build from practical salinity (*35.16504/35)'

f_out.close()

print cf_out + ' sucessfully created!'
コード例 #27
0
dfm['PRES_ADJUSTED_QC'] = dfm['PRES_ADJUSTED_QC'].str.decode("utf-8")
dfm['PSAL_ADJUSTED_QC'] = dfm['PSAL_ADJUSTED_QC'].str.decode("utf-8")

# In[3]:

dfm["JULD"] = pd.to_datetime(dfm['JULD'], infer_datetime_format=True)

# In[4]:

dfm["DEPTH"] = gsw.z_from_p(dfm["PRES_ADJUSTED"], dfm["LATITUDE"])

# uncomment the cell below if you want the entire "dfm" dataframe to be written out into a csv file

# #### Using Gibbs Sea Water Equation of State (TEOS-10) functions, we calculate the density and the conserved density/temperature

SA = gsw.SA_from_SP(dfm['PSAL_ADJUSTED'], dfm['PRES_ADJUSTED'],
                    dfm['LONGITUDE'], dfm['LATITUDE'])
CT = gsw.CT_from_t(SA, dfm['TEMP_ADJUSTED'], dfm['PRES_ADJUSTED'])
dfm['DENSITY_INSITU'] = gsw.density.rho(SA, CT, dfm['PRES_ADJUSTED'])

dfm['POT_DENSITY'] = gsw.density.sigma0(SA, CT)
dfm['CTEMP'] = CT
dfm['SA'] = SA

mask_notbad_temp = ~(dfm['TEMP_ADJUSTED_QC'] == 4)
mask_notbad_sal = ~(dfm['PSAL_ADJUSTED_QC'] == 4)
mask_notbad_pres = ~(dfm['PRES_ADJUSTED_QC'] == 4)

dfmg = dfm[mask_notbad_pres & mask_notbad_sal
           & mask_notbad_temp]  # data with only good QC + null value flags

from scipy.io import netcdf
コード例 #28
0
import matplotlib.pyplot as plt
from ocean_tools import TKED
import gsw

directory = '../../Data/deployment_raw/'
outdir = '../../plots/ctd/LT_D_R/'
deployment_name = 'deploy2_'
measurement_type = '1ctd_'
file_type = 'raw_'

for i in range(10):
    c_file = 'C' + ("%07d" % (i, ))
    c_data = pd.read_pickle(directory + deployment_name + file_type + c_file)

    CT = gsw.CT_from_t(c_data['c_sal'], c_data['c_temp'], c_data['c_pres'])
    SA = gsw.SA_from_SP(c_data['c_sal'], c_data['c_pres'], 174, -43)
    pdens = gsw.sigma0(SA, CT)
    c_data["pdens"] = pdens
    [LT, Td, Nsqu, Lo, R, x_sorted,
     idxs] = TKED.thorpe_scales(c_data["c_depth"].values * -1,
                                c_data['pdens'].values,
                                full_output=True)

    #plt.show()
    fig2, (ax2, ax3, ax4) = plt.subplots(1, 3, sharey=True)
    # Temperature
    ax2.plot(c_data['pdens'], c_data["c_depth"].values, c='k')
    ax2.set_ylabel('Depth (m)')
    #ax2.set_ylim(ax2.get_ylim()[::-1]) #this reverses the yaxis (i.e. deep at the bottom)
    ax2.set_xlabel('Density (kg/m3)')
    ax2.xaxis.set_label_position('top')  # this moves the label to the top
コード例 #29
0
                        date_reform_num[:] = np.NaN

                        for l in np.arange(len(date_reform)):
                            date_reform_num[l] = date_reform_sub[
                                l].total_seconds()

                        lat_array = np.zeros(pres.shape)
                        lat_array[:] = np.NaN
                        lon_array = np.zeros(pres.shape)
                        lon_array[:] = np.NaN

                        for l in np.arange(lat_array.shape[0]):
                            lat_array[l, :] = lat[l]
                            lon_array[l, :] = lon[l]

                        SA = gsw.SA_from_SP(sal, pres, lon_array, lat_array)
                        CT = gsw.CT_from_t(SA, temp, pres)
                        oxy_eq = gsw.O2sol(SA, CT, pres, lon_array, lat_array)

                        # calculate depth
                        geo_strf = gsw.geo_strf_dyn_height(SA=SA.T,
                                                           CT=CT.T,
                                                           p=pres.T)
                        geo_strf = geo_strf.T
                        z = gsw.z_from_p(p=pres,
                                         lat=lat_array,
                                         geo_strf_dyn_height=geo_strf)
                        z = -1 * z

                        oxy_sat = doxy / oxy_eq * 100
コード例 #30
0
ファイル: AR30_funcs.py プロジェクト: ilebras/OSNAP
uni['N2']['vmin'] = -8
uni['N2']['vmax'] = -2
uni['N2']['cmap'] = cm.YlGn

uni['sal_1m'] = uni['sal']
uni['tmp_1m'] = uni['tmp']
uni['turner_1m'] = uni['turner']

uni['o2'] = {}
uni['o2']['vmin'] = 4
uni['o2']['vmax'] = 9
uni['o2']['cmap'] = cm.rainbow

salvec = linspace(31, 36, 103)
tmpvec = linspace(-3, 16, 103)
salmat, tmpmat = meshgrid(salvec, tmpvec)

SA_vec = gsw.SA_from_SP(salvec, zeros(len(salvec)), -44, 59.5)
SA_vec_1000 = gsw.SA_from_SP(salvec, 1e3 * ones(len(salvec)), -44, 59.5)

CT_vec = gsw.CT_from_pt(SA_vec, tmpvec)
pdenmat = zeros((shape(salmat)))
pdenmat2 = zeros((shape(salmat)))
sigma1mat = zeros((shape(salmat)))
for ii in range(len(salvec)):
    for jj in range(len(tmpvec)):
        pdenmat[jj, ii] = gsw.sigma0(SA_vec[ii], CT_vec[jj])
        pdenmat2[jj, ii] = gsw.pot_rho_t_exact(SA_vec[ii], tmpvec[jj], 750,
                                               0) - 1e3
        sigma1mat[jj, ii] = gsw.sigma1(SA_vec[ii], CT_vec[jj])