Esempio n. 1
0
def roms_davg(val):
    dim = val.get_axis_num('depth')
    dz = utils.center_to_interval(val.depth.values)
    weighted = np.nansum((val * dz).values, axis=dim)
    unit = np.sum(np.isfinite(val) * dz, axis=dim)
    return weighted / unit


# Compare tides at point reyes:

_, t_start, t_stop = mdu.time_range()

pr_tides_noaa_fn = "noaa_9415020-%s_%s.nc" % (utils.to_datetime(
    t_start).strftime('%Y%m%d'), utils.to_datetime(t_stop).strftime('%Y%m%d'))
if not os.path.exists(pr_tides_noaa_fn):
    ds = noaa_coops.coops_dataset("9415020", t_start, t_stop, ["water_level"])
    ds.to_netcdf(pr_tides_noaa_fn)
    ds.close()
pr_tides_noaa = xr.open_dataset(pr_tides_noaa_fn)

feat = obs_pnts[np.nonzero(obs_pnts['name'] == 'NOAA_PointReyes')[0][0]]
xy = np.array(feat['geom'])
ll = utm2ll(xy)

ll_idx = [
    np.searchsorted(src.lon % 360, ll[0] % 360),
    np.searchsorted(src.lat, ll[1])
]
##

#dfm_map=xr.open_dataset(os.path.join(run_base_dir,
Esempio n. 2
0
def add_ocean(run_base_dir,
              rel_bc_dir,
              run_start,
              run_stop,
              ref_date,
              static_dir,
              grid,
              old_bc_fn,
              all_flows_unit=False,
              lag_seconds=0.0,
              factor=1.0):
    """
    Ocean:
    Silvia used:
        Water level data from station 46214 (apparently from Yi Chao's ROMS?)
          no spatial variation
        Maybe salinity from Yi Chao ROMS?  That's what the thesis says, but the
        actual inputs look like constant 33
    Here I'm using data from NOAA Point Reyes.
        waterlevel, water temperature from Point Reyes.
    When temperature is not available, use constant 15 degrees

    factor: a scaling factor applied to tide data to adjust amplitude around MSL.
    lag_seconds: to shift ocean boundary condition in time, a positive value 
    applying it later in time.
    """
    # get a few extra days of data to allow for transients in the low pass filter.
    pad_time = np.timedelta64(5, 'D')

    if 1:
        if 0:  # This was temporary, while NOAA had an issue with their website.
            log.warning("TEMPORARILY USING FORT POINT TIDES")
            tide_gage = "9414290"  # Fort Point
        else:
            tide_gage = "9415020"  # Pt Reyes

        if common.cache_dir is None:
            tides_raw_fn = os.path.join(run_base_dir, rel_bc_dir,
                                        'tides-%s-raw.nc' % tide_gage)
            if not os.path.exists(tides_raw_fn):
                tides = noaa_coops.coops_dataset(
                    tide_gage,
                    run_start - pad_time,
                    run_stop + pad_time, ["water_level", "water_temperature"],
                    days_per_request=30)

                tides.to_netcdf(tides_raw_fn, engine='scipy')
            else:
                tides = xr.open_dataset(tides_raw_fn)
        else:
            # rely on caching within noaa_coops
            tides = noaa_coops.coops_dataset(
                tide_gage,
                run_start - pad_time,
                run_stop + pad_time, ["water_level", "water_temperature"],
                days_per_request='M',
                cache_dir=common.cache_dir)
    # Those retain station as a dimension of length 1 - drop that dimension
    # here:
    tides = tides.isel(station=0)

    # Fort Point mean tide range is 1.248m, vs. 1.193 at Point Reyes.
    # apply rough correction to amplitude.
    # S2 phase 316.2 at Pt Reyes, 336.2 for Ft. Point.
    # 20 deg difference for a 12h tide, or 30 deg/hr, so
    # that's a lag of 40 minutes.
    # First go I got this backwards, and wound up with lags
    # at Presidio and Alameda of 4600 and 4400s.  That was
    # with lag_seconds -= 40*60.
    # Also got amplitudes 13% high at Presidio, so further correction...
    if tide_gage == "9414290":
        #
        factor *= 1.193 / 1.248 * 1.0 / 1.13
        lag_seconds += 35 * 60.

    if 1:
        # Clean that up, fabricate salinity
        water_level = utils.fill_tidal_data(tides.water_level)

        # IIR butterworth.  Nicer than FIR, with minor artifacts at ends
        # 3 hours, defaults to 4th order.
        water_level[:] = filters.lowpass(water_level[:].values,
                                         utils.to_dnum(water_level.time),
                                         cutoff=3. / 24)

        if 1:  # apply factor:
            msl = 2.152 - 1.214  # MSL(m) - NAVD88(m) for Point Reyes
            if factor != 1.0:
                log.info("Scaling tidal forcing amplitude by %.3f" % factor)
            water_level[:] = msl + factor * (water_level[:].values - msl)

        if 1:  # apply lag
            if lag_seconds != 0.0:
                # sign:  if lag_seconds is positive, then I want the result
                # for time.values[0] to come from original data at time.valules[0]-lag_seconds
                if 0:  # Why interpolate here? Just alter the timebase.
                    water_level[:] = np.interp(
                        utils.to_dnum(tides.time.values),
                        utils.to_dnum(tides.time.values) -
                        lag_seconds / 86400., tides.water_level.values)
                else:
                    # Adjust time base directly.
                    water_level.time.values[:] = water_level.time.values + np.timedelta64(
                        lag_seconds, 's')

        if 'water_temperature' not in tides:
            log.warning(
                "Water temperature was not found in NOAA data.  Will use constant 15"
            )
            water_temp = 15 + 0 * tides.water_level
            water_temp.name = 'water_temperature'
        else:
            fill_data(tides.water_temperature)
            water_temp = tides.water_temperature

        if all_flows_unit:
            print("-=-=-=- USING 35 PPT WHILE TESTING! -=-=-=-")
            salinity = 35 + 0 * water_level
        else:
            salinity = 33 + 0 * water_level
        salinity.name = 'salinity'

    if 1:  # Write it all out
        # Add a stanza to FlowFMold_bnd.ext:
        src_name = 'Sea'

        src_feat = dio.read_pli(os.path.join(static_dir,
                                             '%s.pli' % src_name))[0]

        forcing_data = [('waterlevelbnd', water_level, '_ssh'),
                        ('salinitybnd', salinity, '_salt'),
                        ('temperaturebnd', water_temp, '_temp')]

        for quant, da, suffix in forcing_data:
            with open(old_bc_fn, 'at') as fp:
                lines = [
                    "QUANTITY=%s" % quant,
                    "FILENAME=%s/%s%s.pli" % (rel_bc_dir, src_name, suffix),
                    "FILETYPE=9", "METHOD=3", "OPERAND=O", ""
                ]
                fp.write("\n".join(lines))

            feat_suffix = dio.add_suffix_to_feature(src_feat, suffix)
            dio.write_pli(
                os.path.join(run_base_dir, rel_bc_dir,
                             '%s%s.pli' % (src_name, suffix)), [feat_suffix])

            # Write the data:
            columns = ['elapsed_minutes', da.name]

            df = da.to_dataframe().reset_index()
            df['elapsed_minutes'] = (df.time.values -
                                     ref_date) / np.timedelta64(60, 's')

            if len(feat_suffix) == 3:
                node_names = feat_suffix[2]
            else:
                node_names = [""] * len(feat_suffix[1])

            for node_idx, node_name in enumerate(node_names):
                # if no node names are known, create the default name of <feature name>_0001
                if not node_name:
                    node_name = "%s%s_%04d" % (src_name, suffix, 1 + node_idx)

                tim_fn = os.path.join(run_base_dir, rel_bc_dir,
                                      node_name + ".tim")
                df.to_csv(tim_fn,
                          sep=' ',
                          index=False,
                          header=False,
                          columns=columns)
Esempio n. 3
0

dfm_short27 = pr_dfm_s1(
    'short_27'
)  # probably misconfigured to have velo only shallower than 1000m deep.
# dfm_short26=pr_dfm_s1('short_26') # corrected by water level forcing.
# dfm_short25=pr_dfm_s1('short_25') # test run, not tidal.

t_start = dfm_short27.time.values[0]
t_stop = dfm_short27.time.values[-1]

##

pr_tides_noaa = noaa_coops.coops_dataset("9415020",
                                         t_start,
                                         t_stop, ["water_level"],
                                         cache_dir='cache',
                                         days_per_request='M')
pr_tides_noaa = pr_tides_noaa.isel(station=0)

##

# And OTPS comparison:
# May move more of this to sfb_dfm_utils in the future
Otps = otps.otps_model.OTPS(
    '/home/rusty/src/otps/OTPS2',  # Locations of the OTPS software
    '/opt/data/otps')  # location of the data

pr_ll = [pr_tides_noaa.lon.values[0], pr_tides_noaa.lat.values[0]]
z_harmonics = Otps.extract_HC([pr_ll])
Esempio n. 4
0
from stompy.model.delft import dfm_grid
from stompy.io.local import noaa_coops
from stompy.grid import unstructured_grid

##

map_nc = "/hpcvol1/rusty/dfm/sfb_ocean/runs/short_21_norm_orig/DFM_OUTPUT_short_21/short_21_map.nc"
map_rev_nc = "/hpcvol1/rusty/dfm/sfb_ocean/runs/short_21/DFM_OUTPUT_short_21/short_21_map.nc"

map_ds = xr.open_dataset(map_nc)
map_rev_ds = xr.open_dataset(map_rev_nc)

##
ptreyes = noaa_coops.coops_dataset('9415020',
                                   map_ds.time[0],
                                   map_ds.time[-1], ['water_level'],
                                   cache_dir='cache',
                                   days_per_request='M')

g = dfm_grid.DFMGrid(map_ds)
##

plt.figure(1).clf()
fig, ax = plt.subplots(num=1)

g.plot_edges(ax=ax, color='k', lw=0.5)

##

# middle of the domain
samp_point = np.array([464675., 4146109.])
ds['waterlevel_orig'].attrs['units'] = 'm'

##

from stompy.io.local import noaa_coops

start = np.datetime64("2010-07-07")
stop = np.datetime64("2016-06-01")
noaa_monterey = 9413450
noaa_sf = 9414290

# Check for lags against USGS data and adjust
ds_monterey, ds_sf = [
    noaa_coops.coops_dataset(station=station,
                             start_date=start,
                             end_date=stop,
                             days_per_request='M',
                             cache_dir="../forcing/tides/cache",
                             products=['water_level'])
    for station in [noaa_monterey, noaa_sf]
]

##

import matplotlib.pyplot as plt

plt.figure(2).clf()
fig, ax = plt.subplots(num=2)

ax.plot(ds_monterey.time,
        ds_monterey.water_level.isel(station=0),
        label='NOAA Monterey')
Esempio n. 6
0
import numpy as np
from stompy.io.local import noaa_coops

##
ds=noaa_coops.coops_dataset("9414290",
                            np.datetime64("2015-12-10"),
                            np.datetime64("2016-02-28"),
                            ["water_level","water_temperature"],
                            days_per_request=30)

# The merge is failing, but the real problem is that the water_level data
# has duplicates within itself.