コード例 #1
0
 def test_bad_tol_grid_key(self):
     with pytest.raises(KeyError):
         # Should raise a key error because the value
         # for grid is not a key in 'tols'
         geo_tools.find_closest_model_point(-124.5,
                                            48.5,
                                            self.model_lons,
                                            self.model_lats,
                                            grid="NotAKey")
コード例 #2
0
 def test_no_water_pt_found(self):
     lon, lat = -124.5, 48.555
     all_land_land_mask = np.full(self.land_mask.shape, True, dtype=bool)
     with pytest.raises(ValueError):
         geo_tools.find_closest_model_point(lon,
                                            lat,
                                            self.model_lons,
                                            self.model_lats,
                                            land_mask=all_land_land_mask)
コード例 #3
0
 def test_no_land_mask_closest_grid_pt_found(self):
     lon = -124.5
     lat = 48.555
     expected = (3, 2)
     j, i = geo_tools.find_closest_model_point(lon, lat, self.model_lons,
                                               self.model_lats)
     assert (j, i) == expected
コード例 #4
0
ファイル: grid_tools.py プロジェクト: mdunphy/tools
def build_GEM_mask(grid_GEM, grid_NEMO, mask_NEMO):
    """
    """

    # Preallocate
    ngrid_GEM = grid_GEM['gridX'].shape[0] * grid_GEM['gridY'].shape[0]
    mask_GEM = np.zeros(ngrid_GEM, dtype=int)

    # Evaluate each point on GEM grid
    bar = utilities.statusbar('Building GEM mask', width=90, maxval=ngrid_GEM)
    for index, coords in enumerate(
            bar(
                zip(
                    grid_GEM['longitude'].values.reshape(ngrid_GEM) - 360,
                    grid_GEM['latitude'].values.reshape(ngrid_GEM),
                ))):

        j, i = geo_tools.find_closest_model_point(
            coords[0],
            coords[1],
            grid_NEMO['longitude'],
            grid_NEMO['latitude'],
        )
        if j is np.nan or i is np.nan:
            mask_GEM[index] = 0
        else:
            mask_GEM[index] = mask_NEMO[j, i].values

    # Reshape
    mask_GEM = mask_GEM.reshape(grid_GEM['longitude'].shape)

    return mask_GEM
コード例 #5
0
 def test_find_water_point(self, lon, lat, expected):
     j, i = geo_tools.find_closest_model_point(lon,
                                               lat,
                                               self.model_lons,
                                               self.model_lats,
                                               land_mask=self.land_mask)
     assert (j, i) == expected
コード例 #6
0
def retrieve_hindcast_data(lon, lat, date, obs_depth, field, grid_B, mesh_mask):
    """Gather nowcast field daily mean, min and max at lat, lon on date,
    interpolated to obs_depth.

    :arg lon: longitude point
    :type lon: real number

    :arg lat: latitude point
    :type lat: real number

    :arg date: simulation date
    :type date: datetime

    :arg obs_depth: array of depths to be interpolated to
    :type obs_depth: numpy array

    :arg field: name of variable to load, e.g 'vosaline' or 'votemper'
    :type field: string

    :arg grid_B: model bathymetry
    :type grid_B: netCDF4 object

    :arg mesh_mask: model mesh mask
    :type mesh_mask: netCDF4 object

    :returns: model_d_interp, model_max, model_min - numpy arrays
    """
    # look up model grid point
    bathy, lons, lats = tidetools.get_bathy_data(grid_B)
    j, i = geo_tools.find_closest_model_point(lon, lat, lons, lats, land_mask = bathy.mask)
    # loading
    grid_d = results_dataset2('1d', 'grid_T', date)
    grid_h = results_dataset2('1h', 'grid_T', date)
    model_d = grid_d.variables[field][0, :, j, i]
    model_h = grid_h.variables[field][:, :, j, i]
    if 'gdept' in mesh_mask.variables.keys():
        gdep = mesh_mask.variables['gdept'][0, :, j, i]
    else:
        gdep = mesh_mask.variables['gdept_0'][0, :, j, i]
    # masking
    tmask = mesh_mask.variables['tmask'][:, :, j, i]
    tmask = 1 - tmask + np.zeros(model_h.shape)
    model_d = np.ma.array(model_d, mask=tmask[0, :])
    gdep_mask = np.ma.array(gdep, mask=tmask[0, :])
    model_h = np.ma.array(model_h, mask=tmask)
    # interpolate to observed depth
    model_d_interp = comparisons.interpolate_depth(model_d, gdep_mask,
                                                   obs_depth)
    model_h_interp = np.zeros((model_h.shape[0], len(obs_depth)))
    for t in np.arange(model_h.shape[0]):
        model_h_interp[t, :] = comparisons.interpolate_depth(model_h[t, :],
                                                             gdep_mask,
                                                             obs_depth)
    # daily max and min
    model_max = np.max(model_h_interp, axis=0)
    model_min = np.min(model_h_interp, axis=0)

    return model_d_interp, model_max, model_min
コード例 #7
0
def dothetest():
    for j in range(glamt.shape[0]):
        for i in range(glamt.shape[1]):
            jfast, ifast = fast_ll2ij_SalishSea201702(glamt[j, i], gphit[j, i],
                                                      glamt, gphit)
            jgeo, igeo = find_closest_model_point(glamt[j, i], gphit[j, i],
                                                  glamt, gphit)
            if jfast != jgeo or ifast != igeo:
                print("Mismatch:", ifast, jfast, igeo, jgeo)
コード例 #8
0
def still_inside(time, number):
    number_of_particles = np.zeros(time)
    for n in range(time):
        for m in range(number):
            if (mask[n,m]) == False: 
                y,x = geo_tools.find_closest_model_point(lont[n,m],latt[n,m],lons, lats, land_mask=bathy.mask)
                if (598<y<658) and (118<x<134):
                    number_of_particles[n] = number_of_particles[n] + 1
    return number_of_particles
コード例 #9
0
def _model_IDW(obs, bathy, grid_T_hr, sal_a, sal_b):
    """Perform a inverse distance weighted (IDW) interpolation with 8 nearest
    points to the model value that is nearest to a ferry observation point.

    :arg obs: Array containing time, lon, lat and salinity or a single point
    :type obs: numpy array

    :arg bathy: model bathymetry
    :type bathy: numpy array

    :arg grid_T_hr: Hourly tracer results dataset from NEMO.
    :type grid_T_hr: :class:`netCDF4.Dataset`

    :arg sal_a: 1.5 m depth for 3 am (if TWDP route, 2am)
    :type sal_a: numpy array

    :arg sal_b: 1.5 m depth for 4 am (if TWDP route, 3am)
    :arg sal_b: numpy array

    :returns: integral of model salinity values divided by weights for
              sal_a and sal_b.
    """
    lats = grid_T_hr.variables['nav_lat'][:, :]
    lons = grid_T_hr.variables['nav_lon'][:, :]
    depths = bathy.variables['Bathymetry'][:]
    x1, y1 = geo_tools.find_closest_model_point(
        obs[1], obs[2], lons, lats)  # Removed 'lat_tol=0.00210'
    # Inverse distance weighted interpolation with the 8 nearest model values.
    val_a_sum = 0
    val_b_sum = 0
    weight_sum = 0
    # Some ferry model routes go over land, replace locations when 4 or
    # more of the surrounding grid point are land with NaN.
    interp_area = sal_a[x1 - 1:x1 + 2, y1 - 1:y1 + 2]
    if interp_area.size - np.count_nonzero(interp_area) >= 4:
        sal_a_idw = np.NaN
        sal_b_idw = np.NaN
    else:
        for i in np.arange(x1 - 1, x1 + 2):
            for j in np.arange(y1 - 1, y1 + 2):
                # Some adjacent points are land we don't count them into the
                # salinity average.
                if depths[i, j] > 0:
                    dist = geo_tools.haversine(obs[1], obs[2], lons[i, j],
                                               lats[i, j])
                    weight = 1.0 / dist
                    weight_sum += weight
                    val_a = sal_a[i, j] * weight
                    val_b = sal_b[i, j] * weight
                    val_a_sum += val_a
                    val_b_sum += val_b
        sal_a_idw = val_a_sum / weight_sum
        sal_b_idw = val_b_sum / weight_sum
    return sal_a_idw, sal_b_idw
コード例 #10
0
def go():
    #for j in range(glamt.shape[0]):
    #    for i in range(glamt.shape[1]):
    for j in range(380, 450):
        for i in range(280, 350):
            jfast, ifast = fast_ll2ij_SalishSea201702(glamt[j, i], gphit[j, i],
                                                      glamt, gphit)
            jgeo, igeo = find_closest_model_point(glamt[j, i], gphit[j, i],
                                                  glamt, gphit)
            if jfast != jgeo or ifast != igeo:
                print(ifast, jfast, igeo, jgeo)
コード例 #11
0
 def test_no_land_mask_1_grid_pt_found(self):
     lon, lat = -124.49885559, 48.54185486
     expected = (1, 1)
     j, i = geo_tools.find_closest_model_point(
         lon,
         lat,
         self.model_lons,
         self.model_lats,
         grid='test',
         tols={'test': {
             'tol_lon': 0.000001,
             'tol_lat': 0.000001
         }})
     assert (j, i) == expected
コード例 #12
0
ファイル: ONC.py プロジェクト: SalishSeaCast/analysis-nancy
def load_model_data(sdt, edt, grid_B, results_home, period, variable, lat,
                    lon):
    """Load the model data in date range of interest and at the location.
    :arg sdt: the start date
    :type sdt: datetime object

    :arg edt: the end date
    :type edt: datetime object

    :arg grid_B: the model bathymetry
    :type grid_B: netCDF4 handle

    :arg results_home: directory for model results
    :type restuls_home: string

    :arg period: the model avergaing period eg '1h' or '1d'
    :time period: string

    :arg variable: the variable to be loaded, eg 'vosaline' or 'votemper'
    :type variable: string.

    :arg lat: the latitude
    :type lat: float

    :arg lon: the longitude
    :type lon: float

    :returns: var, times, mdepths - the array of data, the times associated
    and the model depth array
    """

    files = analyze.get_filenames(sdt, edt, period, 'grid_T', results_home)
    ftmp = nc.Dataset(files[0])
    mdepths = ftmp.variables['deptht'][:]
    # Model grid
    X = grid_B.variables['nav_lon'][:]
    Y = grid_B.variables['nav_lat'][:]
    bathy = grid_B.variables['Bathymetry'][:]
    # Look up grid coordinates
    j, i = geo_tools.find_closest_model_point(lon, lat, X, Y)
    # Grab model data
    var, times = analyze.combine_files(files, variable,
                                       np.arange(mdepths.shape[0]), j, i)
    print('Model bathymetry:', bathy[j, i])
    return var, times, mdepths
コード例 #13
0
ファイル: VENUS.py プロジェクト: SalishSeaCast/analysis-nancy
def get_model_time_series(station, fnames, grid_B, mesh_mask, nemo_36=True):
    """Retrieve the density, salinity and temperature time series at a station.
    Time series is created from files listed in fnames"""
    if nemo_36:
        depth_var = 'gdept_0'
        depth_var_w = 'gdepw_0'
    else:
        depth_var = 'gdept'
        depth_var_w = 'gdepw'
    # station info
    lon = places.PLACES[station]['lon lat'][0]
    lat = places.PLACES[station]['lon lat'][1]
    depth = places.PLACES[station]['depth']
    # model corresponding locations and variables
    bathy, X, Y = tidetools.get_bathy_data(grid_B)
    j, i = geo_tools.find_closest_model_point(lon,
                                              lat,
                                              X,
                                              Y,
                                              land_mask=bathy.mask)
    model_depths = mesh_mask.variables[depth_var][0, :, j, i]
    tmask = mesh_mask.variables['tmask'][0, :, j, i]
    wdeps = mesh_mask.variables[depth_var_w][0, :, j, i]
    sal, time = analyze.combine_files(fnames, 'vosaline', 'None', j, i)
    temp, time = analyze.combine_files(fnames, 'votemper', 'None', j, i)
    # interpolate:
    sal_interp = np.array([
        shared.interpolate_tracer_to_depths(sal[d, :], model_depths, depth,
                                            tmask, wdeps)
        for d in range(sal.shape[0])
    ])
    temp_interp = np.array([
        shared.interpolate_tracer_to_depths(temp[d, :], model_depths, depth,
                                            tmask, wdeps)
        for d in range(temp.shape[0])
    ])
    # convert to psu for using density function
    return sal_interp, temp_interp, time
コード例 #14
0
ファイル: loadDataFRP.py プロジェクト: mdunphy/tools
def loadDataFRP_SSGrid(
        exp='all',
        sel='narrow',
        meshPath='/ocean/eolson/MEOPAR/NEMO-forcing/grid/mesh_mask201702.nc'):
    import gsw  # only in this function; use to convert p to z
    if exp not in {'exp1', 'exp2', 'all'}:
        print('option exp=' + exp + ' is not defined.')
        raise
    if sel not in {'narrow', 'wide'}:
        print('option sel=' + sel + ' is not defined.')
        raise
    df0, clist, tcor, cast19, cast25 = loadDataFRP_init(exp=exp)

    # load mesh
    mesh = nc.Dataset(meshPath, 'r')
    tmask = mesh.variables['tmask'][0, :, :, :]
    gdept = mesh.variables['gdept_0'][0, :, :, :]
    gdepw = mesh.variables['gdepw_0'][0, :, :, :]
    nav_lat = mesh.variables['nav_lat'][:, :]
    nav_lon = mesh.variables['nav_lon'][:, :]
    mesh.close()

    zCasts = dict()
    for nn in clist:
        ip = np.argmax(cast25[nn].df['prSM'].values)
        ilag = df0.loc[df0.Station == nn, 'ishift_sub19'].values[0]
        pS_pr = df0.loc[df0.Station == nn, 'pS_pr'].values[0]
        pE_pr = df0.loc[df0.Station == nn, 'pE_pr'].values[0]
        pS_tur = df0.loc[df0.Station == nn, 'pStart25'].values[0]
        pE_tur = df0.loc[df0.Station == nn, 'pEnd25'].values[0]
        if sel == 'narrow':
            pS = pS_tur
            pE = pE_tur
            prebin = False
        elif sel == 'wide':
            pS = pS_pr
            pE = pE_pr
            prebin = True

        jj, ii = geo_tools.find_closest_model_point(
            df0.loc[df0.Station == nn]['LonDecDeg'].values[0],
            df0.loc[df0.Station == nn]['LatDecDeg'].values[0], nav_lon,
            nav_lat)

        zmax = -1 * gsw.z_from_p(cast25[nn].df.loc[ip, 'prSM'],
                                 df0.loc[df0.Station == nn]['LatDecDeg'])
        edges = gdepw[:, jj, ii]
        targets = gdept[:, jj, ii]
        edges = edges[edges < zmax]
        targets = targets[:(len(edges) - 1)]
        parDZ = .78
        xmisDZ = .36
        turbDZ = .67

        zshiftdict = {
            'gsw_ctA0': 0.0,
            'gsw_srA0': 0.0,
            'xmiss': xmisDZ,
            'seaTurbMtr': turbDZ,
            'par': parDZ,
            'wetStar': 0.0,
            'sbeox0ML_L': 0.0
        }
        dCast = pd.DataFrame()
        uCast = pd.DataFrame()
        for var in ('gsw_ctA0', 'gsw_srA0', 'xmiss', 'par', 'wetStar',
                    'sbeox0ML_L'):
            if not nn == 14.2:
                #downcast
                inP = -1 * gsw.z_from_p(
                    cast25[nn].df.loc[pS:ip]['prSM'].values,
                    df0.loc[df0.Station == nn]['LatDecDeg']) - zshiftdict[
                        var]  # down z
                inV = cast25[nn].df.loc[pS:ip][var].values  # down var
                if sel == 'wide':
                    inV[inP < .1] = np.nan
                p, out = bindepth(inP,
                                  inV,
                                  edges=edges,
                                  targets=targets,
                                  prebin=prebin)
                if var == 'gsw_ctA0':
                    dCast = pd.DataFrame(p, columns=['depth_m'])
                    dCast['indk'] = np.arange(0, len(p))
                dCast[var] = out
            else:  # special case where there is no downcast
                if var == 'gsw_ctA0':
                    dCast = pd.DataFrame(np.nan * np.ones(10),
                                         columns=['depth_m'])
                    dCast['indk'] = np.nan * np.ones(10)
                dCast[var] = np.nan * np.ones(10)
            if not nn == 14.1:
                #upcast
                inP = -1 * gsw.z_from_p(
                    cast25[nn].df.loc[ip:pE]['prSM'].values,
                    df0.loc[df0.Station == nn]['LatDecDeg']) - zshiftdict[
                        var]  # down z
                inV = cast25[nn].df.loc[ip:pE][var].values  # down var
                if sel == 'wide':
                    inV[inP < .1] = np.nan
                p, out = bindepth(inP,
                                  inV,
                                  edges=edges,
                                  targets=targets,
                                  prebin=prebin)
                if var == 'gsw_ctA0':
                    uCast = pd.DataFrame(p, columns=['depth_m'])
                    uCast['indk'] = np.arange(0, len(p))
                uCast[var] = out
            else:  # special case where there is no upcast
                if var == 'gsw_ctA0':
                    uCast = pd.DataFrame(np.nan * np.ones(10),
                                         columns=['depth_m'])
                    uCast['indk'] = np.nan * np.ones(10)
                uCast[var] = np.nan * np.ones(10)
        if not nn == 14.2:
            #turbidity downcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[pS:ip]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg']) - turbDZ  # down z
            inV0 = cast19[nn].df.loc[(pS + ilag):(
                ip + ilag)]['seaTurbMtr'].values  # down var
            if sel == 'wide':
                # additional QC for broader data selection
                ii1 = amp(rolling_window_padded(inV0, 5),
                          -1) > .5 * np.nanmax(inV0)
                # get rid of near-zero turbidity values; seem to be dropped signal
                ii2 = np.nanmin(rolling_window_padded(inV0, 5), -1) < .3
                inV0[np.logical_or(ii1, ii2)] = np.nan
            inV = ssig.medfilt(inV0, 3)  # down var
            if sel == 'wide':  # exclude above surface data
                with np.errstate(invalid='ignore'):
                    inV[inP < .1] = np.nan
            p, tur = bindepth(inP,
                              inV,
                              edges=edges,
                              targets=targets,
                              prebin=prebin)
            dCast['turb'] = tur * 1.0 / tcor
        else:  # special case where there is no downcast
            dCast['turb'] = np.nan * np.ones(10)
        if not nn == 14.1:
            #turbidity upcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[ip:pE]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg']) - turbDZ  # up z
            inV0 = cast19[nn].df.loc[(ip + ilag):(
                pE + ilag)]['seaTurbMtr'].values  # up var
            if sel == 'wide':
                # additional QC for broader data selection
                ii1 = amp(rolling_window_padded(inV0, 5),
                          -1) > .5 * np.nanmax(inV0)
                # get rid of near-zero turbidity values; seem to be dropped signal
                ii2 = np.nanmin(rolling_window_padded(inV0, 5), -1) < .3
                inV0[np.logical_or(ii1, ii2)] = np.nan
            inV = ssig.medfilt(inV0, 3)  # down var
            if sel == 'wide':  # exclude above surface data
                with np.errstate(invalid='ignore'):
                    inV[inP < .1] = np.nan
            p, tur = bindepth(inP,
                              inV,
                              edges=edges,
                              targets=targets,
                              prebin=prebin)
            uCast['turb'] = tur * 1.0 / tcor
        else:  # special case where there is no upcasts
            uCast['turb'] = np.nan * np.ones(10)

        zCasts[nn] = zCast(uCast, dCast)

    # fix first 2 casts for which sb25 pump did not turn on. use sb19
    if (exp == 'exp1' or exp == 'all'):
        for nn in range(1, 3):

            uCast = zCasts[nn].uCast
            dCast = zCasts[nn].dCast

            ip = np.argmax(cast25[nn].df['prSM'].values)
            ilag = df0.loc[df0.Station == nn, 'ishift_sub19'].values[0]
            pS_pr = df0.loc[df0.Station == nn, 'pS_pr'].values[0]
            pE_pr = df0.loc[df0.Station == nn, 'pE_pr'].values[0]
            pS_tur = df0.loc[df0.Station == nn, 'pStart25'].values[0]
            pE_tur = df0.loc[df0.Station == nn, 'pEnd25'].values[0]
            if sel == 'narrow':
                pS = pS_tur
                pE = pE_tur
            elif sel == 'wide':
                pS = pS_pr
                pE = pE_pr

            jj, ii = geo_tools.find_closest_model_point(
                df0.loc[df0.Station == nn]['LonDecDeg'].values[0],
                df0.loc[df0.Station == nn]['LatDecDeg'].values[0], nav_lon,
                nav_lat)

            zmax = -1 * gsw.z_from_p(cast25[nn].df.loc[ip, 'prSM'],
                                     df0.loc[df0.Station == nn]['LatDecDeg'])
            edges = gdepw[:, jj, ii]
            targets = gdept[:, jj, ii]
            edges = edges[edges < zmax]
            targets = targets[:(len(edges) - 1)]

            ##temperature
            #downcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[pS:ip]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg'])  # down z
            inV = cast19[nn].df.loc[(pS + ilag):(
                ip + ilag)]['gsw_ctA0'].values  # down var
            if sel == 'wide':
                inV[inP < .1] = np.nan
            p, out = bindepth(inP,
                              inV,
                              edges=edges,
                              targets=targets,
                              prebin=prebin)
            dCast['gsw_ctA0'] = out
            #upcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[ip:pE]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg'])  # up z
            inV = cast19[nn].df.loc[(ip +
                                     ilag):(pE +
                                            ilag)]['gsw_ctA0'].values  # up var
            if sel == 'wide':
                inV[inP < .1] = np.nan
            p, out = bindepth(inP,
                              inV,
                              edges=edges,
                              targets=targets,
                              prebin=prebin)
            uCast['gsw_ctA0'] = out

            ##sal
            #downcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[pS:ip]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg'])  # down z
            inV = cast19[nn].df.loc[(pS + ilag):(
                ip + ilag)]['gsw_srA0'].values  # down var
            if sel == 'wide':
                inV[inP < .1] = np.nan
            p, out = bindepth(inP,
                              inV,
                              edges=edges,
                              targets=targets,
                              prebin=prebin)
            dCast['gsw_srA0'] = out
            #upcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[ip:pE]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg'])  # up z
            inV = cast19[nn].df.loc[(ip +
                                     ilag):(pE +
                                            ilag)]['gsw_srA0'].values  # up var
            if sel == 'wide':
                inV[inP < .1] = np.nan
            p, out = bindepth(inP, inV, edges, prebin=prebin)
            uCast['gsw_srA0'] = out

            ##xmiss: xmis25=1.14099414691*xmis19+-1.6910134322
            #downcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[pS:ip]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg']) - xmisDZ  # down z
            inV = 1.14099414691 * cast19[nn].df.loc[(pS + ilag):(
                ip + ilag)]['CStarTr0'].values - 1.6910134322  # down var
            if sel == 'wide':
                inV[inP < .1] = np.nan
            p, out = bindepth(inP,
                              inV,
                              edges=edges,
                              targets=targets,
                              prebin=prebin)
            dCast['xmiss'] = out
            #upcast
            inP = -1 * gsw.z_from_p(
                cast25[nn].df.loc[ip:pE]['prSM'].values,
                df0.loc[df0.Station == nn]['LatDecDeg']) - xmisDZ  # up p
            inV = 1.14099414691 * cast19[nn].df.loc[(ip + ilag):(
                pE + ilag)]['CStarTr0'].values - 1.6910134322  # up var
            if sel == 'wide':
                inV[inP < .1] = np.nan
            p, out = bindepth(inP,
                              inV,
                              edges=edges,
                              targets=targets,
                              prebin=prebin)
            uCast['xmiss'] = out

            uCast['wetStar'] = np.nan
            dCast['wetStar'] = np.nan
            uCast['sbeox0ML_L'] = np.nan
            dCast['sbeox0ML_L'] = np.nan

            zCasts[nn] = zCast(uCast, dCast)

    return df0, zCasts
コード例 #15
0
def find_model_dat(w, fname, datname):
    model_dat = np.nan

    #if the stn has lat, lons not findable in model (ie, out of model domain) this will change to the # of the station
    stn_with_nans = 9999

    #if the observations have data but the model has a 0, these (_f = faulty) record model lat,lon,depth
    w_f = 9999
    d_f = 9999
    i_f = 9999
    j_f = 9999

    #find closest model point, check that it's not nan, if it is, record it
    j, i = geo_tools.find_closest_model_point(lon[w], lat[w], nav_lon, nav_lat)
    j_ref = j
    i_ref = i
    if (np.isnan(i) | np.isnan(j)):
        stn_with_nans = stn[w]

    #extract model depths from model, for comparison with obs
    q2 = nc.Dataset(
        '/results2/SalishSea/nowcast-green.201806/01jan18/SalishSea_1h_20180101_20180101_grid_T.nc'
    )
    dep = q2.variables['deptht']
    d_mod = dep[:]

    #months, to make a path to model data
    mons = [
        'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sep', 'oct',
        'nov', 'dec'
    ]
    month = mon[w]

    #TJ check for month in may or later, findable station, and good quality flag, and dic>0 (should be redundant)
    if ((month >= 5) & (~np.isnan(j)) & (~np.isnan(i)) &
        ((dic_qf[w] == 2) | (dic_qf[w] == 6)) & (dic[w] > 0)):

        #from month and day, make string to
        mon_name = str(mons[int(month) - 1])
        day_name = str(int(day[w]))
        if len(day_name) == 1:
            day_name = '0' + day_name
        modpath = day_name + mon_name + '17/'

        bigpath = '/results2/SalishSea/hindcast.201812_annex/'
        if datname == 'carp':
            ncpath = 'SalishSea_1d_*_carp_T.nc'
        if datname == 'ptrc':
            ncpath = 'SalishSea_1d_*_ptrc_T.nc'
        else:
            ncpath = 'SalishSea_1d_*_grid_T.nc'
        q = glob.glob(bigpath + modpath + ncpath)
        #depths of observations
        dtt = P[w]

        #find closest depth in model - print if necesary
        close = np.abs(d_mod - dtt)
        t_depth = np.argmin(close)
        depth_mod = d_mod[t_depth]
        #         print('DEPTH IND: '+str(t_depth))
        #         print('DEPTH : '+str(depth_mod))

        #open dataset, record relevant model DIC
        qnc = nc.Dataset(q[0])
        model_dat = qnc.variables[fname][0, t_depth, j, i]
        # flag spots where model gives 0s.
        if (model_dat == 0):
            # we have
            #             print('*******')
            #             print('index of grl data: '+str(w))
            #             print('depth in grl data: '+str(P[w]))
            #             print('j index: '+str(j))
            #             print('i index: '+str(i))
            #             print('DEPTH IND: '+str(t_depth))
            #             print('DEPTH : '+str(depth_mod))
            w_f = w
            j_f = j
            i_f = i
            d_f = t_depth


#         print('Data dic: '+str( dic[w]))
#         print('Data dic qf: '+str( dic_qf[w]))
#         print('Model dic '+str(model_dat))

    return model_dat, stn_with_nans, j_f, i_f, d_f, w_f, j_ref, i_ref
コード例 #16
0
def plot_files(ax, grid_B, files, var, depth, t_orig, t_final, name, label,
               colour):
    """Plots values of  variable over multiple files covering
    a certain period of time.

    :arg ax: The axis where the variable is plotted.
    :type ax: axis object

    :arg grid_B: Bathymetry dataset for the Salish Sea NEMO model.
    :type grid_B: :class:`netCDF4.Dataset`

    :arg files: Multiple result files in chronological order.
    :type files: list

    :arg var: Name of variable (sossheig = sea surface height,
                      vosaline = salinity, votemper = temperature,
                      vozocrtx = Velocity U-component,
                      vomecrty = Velocity V-component).
    :type var: string

    :arg depth: Depth of model results ('None' if var=sossheig).
    :type depth: integer or string

    :arg t_orig: The beginning of the date range of interest.
    :type t_orig: datetime object

    :arg t_final: The end of the date range of interest.
    :type t_final: datetime object

    :arg name: The name of the station.
    :type name: string

    :arg label: Label for plot line.
    :type label: string

    :arg colour: Colour of plot lines.
    :type colour: string

    :returns: matplotlib figure object instance (fig) and axis object (ax).
    """

    # Stations information
    lat = figures.SITES[name]['lat']
    lon = figures.SITES[name]['lon']

    # Bathymetry
    bathy, X, Y = tidetools.get_bathy_data(grid_B)

    # Get index
    [j, i] = geo_tools.find_closest_model_point(lon,
                                                lat,
                                                X,
                                                Y,
                                                land_mask=bathy.mask)

    # Call function
    var_ary, time = combine_files(files, var, depth, j, i)

    # Plot
    ax.plot(time, var_ary, label=label, color=colour, linewidth=2.5)

    # Figure format
    ax_start = t_orig
    ax_end = t_final + datetime.timedelta(days=1)
    ax.set_xlim(ax_start, ax_end)
    hfmt = mdates.DateFormatter('%m/%d %H:%M')
    ax.xaxis.set_major_formatter(hfmt)

    return ax
コード例 #17
0
def get_error_model(names, runs_list, grid_B, t_orig):
    """ Sets up the calculation for the model residual error.

    :arg names: Names of station.
    :type names: list of strings

    :arg runs_list: Runs that have been verified as complete.
    :type runs_list: list

    :arg grid_B: Bathymetry dataset for the Salish Sea NEMO model.
    :type grid_B: :class:`netCDF4.Dataset`

    :arg t_orig: Date being considered.
    :type t_orig: datetime object

    :returns: error_mod_dict, t_mod_dict, t_orig_dict
    """

    bathy, X, Y = tidetools.get_bathy_data(grid_B)
    t_orig_obs = t_orig + datetime.timedelta(days=-1)
    t_final_obs = t_orig + datetime.timedelta(days=1)

    # truncation times
    sdt = t_orig.replace(tzinfo=tz.tzutc())
    edt = sdt + datetime.timedelta(days=1)

    error_mod_dict = {}
    t_mod_dict = {}
    for name in names:
        error_mod_dict[name] = {}
        t_mod_dict[name] = {}
        # Look up model grid
        lat = figures.SITES[name]['lat']
        lon = figures.SITES[name]['lon']
        j, i = geo_tools.find_closest_model_point(lon,
                                                  lat,
                                                  X,
                                                  Y,
                                                  land_mask=bathy.mask)
        # Observed residuals and wlevs and tides
        ttide = figures.shared.get_tides(name, path=paths['tides'])
        res_obs, wlev_meas = obs_residual_ssh(name, ttide, t_orig_obs,
                                              t_final_obs)
        res_obs_trun, time_obs_trun = analyze.truncate_data(
            np.array(res_obs), np.array(wlev_meas.time), sdt, edt)

        for mode in runs_list:
            filename, run_date = analyze.create_path(
                mode, t_orig, 'SalishSea_1h_*_grid_T.nc')
            grid_T = nc.Dataset(filename)
            res_mod, t_model, ssh_corr, ssh_mod = model_residual_ssh(
                grid_T, j, i, ttide)
            # Truncate
            res_mod_trun, t_mod_trun = analyze.truncate_data(
                res_mod, t_model, sdt, edt)
            # Error
            error_mod = analyze.calculate_error(res_mod_trun, t_mod_trun,
                                                res_obs_trun, time_obs_trun)
            error_mod_dict[name][mode] = error_mod
            t_mod_dict[name][mode] = t_mod_trun

    return error_mod_dict, t_mod_dict
コード例 #18
0
def plot_residual_model(axs, names, runs_list, grid_B, t_orig):
    """ Plots the observed sea surface height residual against the
    sea surface height model residual (calculate_residual) at
    specified stations. Function may produce none, any, or all
    (nowcast, forecast, forecast 2) model residuals depending on
    availability for specified date (runs_list).

    :arg ax: The axis where the residuals are plotted.
    :type ax: list of axes

    :arg names: Names of station.
    :type names: list of names

    :arg runs_list: Runs that have been verified as complete.
    :type runs_list: list

    :arg grid_B: Bathymetry dataset for the Salish Sea NEMO model.
    :type grid_B: :class:`netCDF4.Dataset`

    :arg t_orig: Date being considered.
    :type t_orig: datetime object

    """

    bathy, X, Y = tidetools.get_bathy_data(grid_B)
    t_orig_obs = t_orig + datetime.timedelta(days=-1)
    t_final_obs = t_orig + datetime.timedelta(days=1)

    # truncation times
    sdt = t_orig.replace(tzinfo=tz.tzutc())
    edt = sdt + datetime.timedelta(days=1)

    for ax, name in zip(axs, names):
        # Identify model grid point
        lat = figures.SITES[name]['lat']
        lon = figures.SITES[name]['lon']
        j, i = geo_tools.find_closest_model_point(lon,
                                                  lat,
                                                  X,
                                                  Y,
                                                  land_mask=bathy.mask)
        # Observed residuals and wlevs and tides
        ttide = figures.shared.get_tides(name, path=paths['tides'])
        res_obs, wlev_meas = obs_residual_ssh(name, ttide, t_orig_obs,
                                              t_final_obs)
        # truncate and plot
        res_obs_trun, time_obs_trun = analyze.truncate_data(
            np.array(res_obs), np.array(wlev_meas.time), sdt, edt)
        ax.plot(time_obs_trun,
                res_obs_trun,
                c=colours['observed'],
                lw=2.5,
                label='observed')

        for mode in runs_list:
            filename, run_date = analyze.create_path(
                mode, t_orig, 'SalishSea_1h_*_grid_T.nc')
            grid_T = nc.Dataset(filename)
            res_mod, t_model, ssh_corr, ssh_mod = model_residual_ssh(
                grid_T, j, i, ttide)
            # truncate and plot
            res_mod_trun, t_mod_trun = analyze.truncate_data(
                res_mod, t_model, sdt, edt)
            ax.plot(t_mod_trun,
                    res_mod_trun,
                    label=mode,
                    c=colours[mode],
                    lw=2.5)

        ax.set_title('Comparison of modelled sea surface height residuals at'
                     ' {station}: {t:%d-%b-%Y}'.format(station=name, t=t_orig))
コード例 #19
0
def compare_VENUS(station, grid_T, grid_B, figsize=(6, 10)):
    """Compares the model's temperature and salinity with observations from
    VENUS station.

    :arg station: Name of the station ('East' or 'Central')
    :type station: string

    :arg grid_T: Hourly tracer results dataset from NEMO.
    :type grid_T: :class:`netCDF4.Dataset`

    :arg grid_B: Bathymetry dataset for the Salish Sea NEMO model.
    :type grid_B: :class:`netCDF4.Dataset`

    :arg figsize: Figure size (width, height) in inches.
    :type figsize: 2-tuple

    :returns: matplotlib figure object instance (fig).
    """

    # Time range
    t_orig, t_end, t = figures.get_model_time_variables(grid_T)

    # Bathymetry
    bathy, X, Y = tt.get_bathy_data(grid_B)

    # VENUS data
    fig, (ax_sal, ax_temp) = plt.subplots(2, 1, figsize=figsize, sharex=True)
    fig.patch.set_facecolor('#2B3E50')
    fig.autofmt_xdate()
    lon = SITES['VENUS'][station]['lon']
    lat = SITES['VENUS'][station]['lat']
    depth = SITES['VENUS'][station]['depth']

    # Plotting observations
    plot_VENUS(ax_sal, ax_temp, station, t_orig, t_end)

    # Grid point of VENUS station
    [j, i] = geo_tools.find_closest_model_point(
        lon, lat, X, Y)

    # Model data
    sal = grid_T.variables['vosaline'][:, :, j, i]
    temp = grid_T.variables['votemper'][:, :, j, i]
    ds = grid_T.variables['deptht']

    # Interpolating data
    salc = []
    tempc = []
    for ind in np.arange(0, sal.shape[0]):
        salc.append(figures.interpolate_depth(sal[ind, :], ds, depth))
        tempc.append(figures.interpolate_depth(temp[ind, :], ds, depth))

    # Plot model data
    ax_sal.plot(t, salc, '-b', label='Model')
    ax_temp.plot(t, tempc, '-b', label='Model')

    # Axis
    ax_sal.set_title(f'VENUS {station} - {t[0].strftime("%d-%b-%Y")}')
    ax_sal.set_ylim([29, 32])
    ax_sal.set_ylabel('Practical Salinity [psu]', **axis_font)
    ax_sal.legend(loc=0)
    ax_temp.set_ylim([7, 13])
    ax_temp.set_xlabel('Time [UTC]', **axis_font)
    ax_temp.set_ylabel('Temperature [deg C]', **axis_font)
    figures.axis_colors(ax_sal, 'gray')
    figures.axis_colors(ax_temp, 'gray')

    # Text box
    ax_temp.text(0.25, -0.3, 'Observations from Ocean Networks Canada',
                 transform=ax_temp.transAxes, color='white')

    return fig
コード例 #20
0
 def test_raises_value_error(self):
     with pytest.raises(ValueError):
         # lat and lon values that aren't on this grid (0, 0)
         geo_tools.find_closest_model_point(0, 0, self.model_lons,
                                            self.model_lats)
コード例 #21
0
def compare_model(to,
                  tf,
                  lighthouse,
                  mode,
                  period,
                  grid_B,
                  smin=28,
                  smax=33,
                  tmin=6,
                  tmax=14):
    """Compare model surface salinity with lighthouse observations in a date
    range.

    :arg to: the beginning of the date range
    :type to: datetime object

    :arg tf: the end of the date range
    :type tf: datetime object

    :arg lighthouse: the name of the lighthouse
    :type lighthouse: string

    :arg mode: the model simulation mode - nowcast or spinup or nowcast-green
    :type mode: string

    :arg period: the averaging period for model results - 1h or 1d
    :type period: string

    :arg grid_B: NEMO bathymetry grid
    :type grid_B: netCDF4 handle

    :arg smin: minumum salinity for axis limits
    :type smin: float

    :arg smax: maximium salinity for axis limits
    :type smax: float

    :arg tmin: minumum temperature for axis limits
    :type tmin: float

    :arg tmax: maximium temperature for axis limits
    :type tmax: float

    :returns: fig, a figure object
    """
    # Load observations
    data, lat, lon = load_lighthouse(LIGHTHOUSES[lighthouse])
    # Look up modle grid point
    X = grid_B.variables['nav_lon'][:]
    Y = grid_B.variables['nav_lat'][:]
    j, i = geo_tools.find_closest_model_point(lon, lat, X, Y)

    # load model
    files = analyze.get_filenames(to, tf, period, 'grid_T', MODEL_PATHS[mode])
    sal, time = analyze.combine_files(files, 'vosaline', 0, j, i)
    if mode == 'nowcast-green':
        sal = teos_tools.teos_psu(sal)
    temp, time = analyze.combine_files(files, 'votemper', 0, j, i)
    if period == '1h':
        # look up times of high tides
        ssh, times = analyze.combine_files(files, 'sossheig', 'None', j, i)
        max_inds = daytime_hightide(ssh, times)
        sal = sal[max_inds]
        temp = temp[max_inds]
        time = time[max_inds]
        title_str = 'max daytime tides'
    else:
        title_str = 'daily average'

    # plotting
    fig, axs = plt.subplots(1, 2, figsize=(15, 5))
    # plot time series
    # salinity
    ax = axs[0]
    ax.plot(time, sal, label=mode)
    ax.plot(data['date'], data['Salinity(psu)'], label='observations')
    ax.legend(loc=0)
    ax.set_title('{} Salinity - {}'.format(lighthouse, title_str))
    ax.set_xlim([to, tf])
    ax.set_ylim([smin, smax])
    ax.set_ylabel('Salinity [psu]')
    # temperature
    ax = axs[1]
    ax.plot(time, temp, label=mode)
    ax.plot(data['date'], data['Temperature(C)'], label='observations')
    ax.legend(loc=0)
    ax.set_title('{} Temperature - {}'.format(lighthouse, title_str))
    ax.set_xlim([to, tf])
    ax.set_ylim([tmin, tmax])
    ax.set_ylabel('Temperature [deg C]')
    fig.autofmt_xdate()

    return fig
コード例 #22
0
def find_model_dat(w, fname, datname, firstmo, yr, path_to_ncs):
    "Usage: "
    model_dat = np.nan

    #if the stn has lat, lons not findable in model (ie, out of model domain) this will change to the # of the station
    stn_with_nans = 9999

    #if the observations have data but the model has a 0, these (_f = faulty) record model lat,lon,depth
    w_f = 9999
    d_f = 9999
    i_f = 9999
    j_f = 9999

    #find closest model point, check that it's not nan, if it is, record it
    j, i = geo_tools.find_closest_model_point(lon[w], lat[w], nav_lon, nav_lat)
    j_ref = j
    i_ref = i
    if (np.isnan(i) | np.isnan(j)):
        stn_with_nans = stn[w]

    #extract model depths from model, for comparison with obs
    q2 = nc.Dataset(
        '/results2/SalishSea/hindcast.201905/07apr10/SalishSea_1h_20100407_20100407_grid_T.nc'
    )

    dep = q2.variables['deptht']
    d_mod = dep[:]

    month = mon[w]

    #TJ check for month in first month or later, findable station, and good quality flag, and dic>0 (should be redundant)
    if ((month >= firstmo) & (~np.isnan(j)) & (~np.isnan(i)) &
        ((dic_qf[w] == 2) | (dic_qf[w] == 6)) & (dic[w] > 0)):

        #from month and day, make string to
        #mon_name = str(mons[int(month)-1])
        mon_name = str(int(mon[w]))
        if len(mon_name) == 1:
            mon_name = '0' + mon_name
        day_name = str(int(day[w]))
        if len(day_name) == 1:
            day_name = '0' + day_name
        #modpath = day_name+mon_name+ yr+'/'
        start = '20' + yr + '-' + mon_name + '-' + day_name
        tdate = arrow.get(start)
        ymd = tdate.format('YYYYMMDD')
        print(ymd)

        bigpath = path_to_ncs
        #print(datname)
        ncpath = '/' + datname + '_1d_' + ymd + '.nc'
        q = glob.glob(bigpath + ncpath)

        #depths of observations
        dtt = P[w]

        #find closest depth in model - print if necesary
        close = np.abs(d_mod - dtt)
        t_depth = np.argmin(close)
        depth_mod = d_mod[t_depth]
        #         print('DEPTH IND: '+str(t_depth))
        #         print('DEPTH : '+str(depth_mod))

        #open dataset, record relevant model DIC
        qnc = nc.Dataset(q[0])
        #print(qnc)
        #print(fname)

        model_dat = qnc['model_output'][fname][t_depth, j, i]
        # flag spots where model gives 0s.
        if (model_dat == 0):
            # we have
            #             print('*******')
            #             print('index of grl data: '+str(w))
            #             print('depth in grl data: '+str(P[w]))
            #             print('j index: '+str(j))
            #             print('i index: '+str(i))
            #             print('DEPTH IND: '+str(t_depth))
            #             print('DEPTH : '+str(depth_mod))
            w_f = w
            j_f = j
            i_f = i
            d_f = t_depth

#         print('Data dic: '+str( dic[w]))
#         print('Data dic qf: '+str( dic_qf[w]))
#         print('Model dic '+str(model_dat))

    return model_dat, stn_with_nans, j_f, i_f, d_f, w_f, j_ref, i_ref