Exemplo n.º 1
0
def do_precip12(ts):
    """Compute the 24 Hour precip at 12 UTC, we do some more tricks though"""
    offset = iemre.daily_offset(ts)
    ets = utc(ts.year, ts.month, ts.day, 12)
    sts = ets - datetime.timedelta(hours=24)
    offset1 = iemre.hourly_offset(sts)
    offset2 = iemre.hourly_offset(ets)
    if ts.month == 1 and ts.day == 1:
        if sts.year >= 1900:
            print(("p01d_12z  for %s [idx:%s] %s(%s)->%s(%s) SPECIAL") %
                  (ts, offset, sts.strftime("%Y%m%d%H"), offset1,
                   ets.strftime("%Y%m%d%H"), offset2))
        ncfn = iemre.get_hourly_ncname(ets.year)
        if not os.path.isfile(ncfn):
            print("Missing %s" % (ncfn, ))
            return
        hnc = ncopen(ncfn, timeout=600)
        phour = np.sum(hnc.variables['p01m'][:offset2, :, :], 0)
        hnc.close()
        hnc = ncopen(iemre.get_hourly_ncname(sts.year), timeout=600)
        phour += np.sum(hnc.variables['p01m'][offset1:, :, :], 0)
        hnc.close()
    else:
        ncfn = iemre.get_hourly_ncname(ts.year)
        if not os.path.isfile(ncfn):
            print("Missing %s" % (ncfn, ))
            return
        hnc = ncopen(ncfn, timeout=600)
        phour = np.sum(hnc.variables['p01m'][offset1:offset2, :, :], 0)
        hnc.close()
    write_grid(ts, 'p01d_12z', np.where(phour < 0, 0, phour))
Exemplo n.º 2
0
def do_precip12(ts, ds):
    """Compute the 24 Hour precip at 12 UTC, we do some more tricks though"""
    offset = iemre.daily_offset(ts)
    ets = utc(ts.year, ts.month, ts.day, 12)
    sts = ets - datetime.timedelta(hours=24)
    offset1 = iemre.hourly_offset(sts)
    offset2 = iemre.hourly_offset(ets)
    if ts.month == 1 and ts.day == 1:
        if sts.year >= 1900:
            LOG.warning(
                "p01d_12z  for %s [idx:%s] %s(%s)->%s(%s) SPECIAL",
                ts,
                offset,
                sts.strftime("%Y%m%d%H"),
                offset1,
                ets.strftime("%Y%m%d%H"),
                offset2,
            )
        ncfn = iemre.get_hourly_ncname(ets.year)
        if not os.path.isfile(ncfn):
            LOG.warning("Missing %s", ncfn)
            return
        with ncopen(ncfn, timeout=600) as hnc:
            phour = np.sum(hnc.variables["p01m"][:offset2, :, :], 0)
        with ncopen(iemre.get_hourly_ncname(sts.year), timeout=600) as hnc:
            phour += np.sum(hnc.variables["p01m"][offset1:, :, :], 0)
    else:
        ncfn = iemre.get_hourly_ncname(ts.year)
        if not os.path.isfile(ncfn):
            LOG.warning("Missing %s", ncfn)
            return
        with ncopen(ncfn, timeout=600) as hnc:
            phour = np.sum(hnc.variables["p01m"][offset1:offset2, :, :], 0)
    ds["p01d_12z"].values = np.where(phour < 0, 0, phour)
Exemplo n.º 3
0
def copy_to_iemre(valid):
    """verbatim copy over to IEMRE."""
    tidx = iemre.hourly_offset(valid)
    nc = ncopen(("/mesonet/data/stage4/%s_stage4_hourly.nc") % (valid.year, ),
                'a',
                timeout=300)
    lats = nc.variables['lat'][:]
    lons = nc.variables['lon'][:]
    val = nc.variables['p01m'][tidx]
    nc.close()

    # Our data is 4km, iemre is 0.125deg, so we stride some to cut down on mem
    stride = slice(None, None, 3)
    lats = np.ravel(lats[stride, stride])
    lons = np.ravel(lons[stride, stride])
    vals = np.ravel(val[stride, stride])
    nn = NearestNDInterpolator((lons, lats), vals)
    xi, yi = np.meshgrid(iemre.XAXIS, iemre.YAXIS)
    res = nn(xi, yi)

    # Lets clip bad data
    # 10 inches per hour is bad data
    res = np.where(np.logical_or(res < 0, res > 250), 0., res)

    # Open up our RE file
    nc = ncopen(iemre.get_hourly_ncname(valid.year), 'a', timeout=300)
    nc.variables["p01m"][tidx, :, :] = res
    LOG.debug("wrote data to hourly IEMRE min: %.2f avg: %.2f max: %.2f",
              np.min(res), np.mean(res), np.max(res))
    nc.close()
Exemplo n.º 4
0
def merge(valid):
    """
    Process an hour's worth of stage4 data into the hourly RE
    """
    nc = ncopen(("/mesonet/data/stage4/%s_stage4_hourly.nc"
                 ) % (valid.year, ), 'r')
    tidx = iemre.hourly_offset(valid)
    val = nc.variables['p01m'][tidx, :, :]
    # print("stage4 mean: %.2f max: %.2f" % (np.mean(val), np.max(val)))
    lats = nc.variables['lat'][:]
    lons = nc.variables['lon'][:]

    # Our data is 4km, iemre is 0.125deg, so we stride some to cut down on mem
    stride = slice(None, None, 3)
    lats = np.ravel(lats[stride, stride])
    lons = np.ravel(lons[stride, stride])
    vals = np.ravel(val[stride, stride])
    nn = NearestNDInterpolator((lons, lats), vals)
    xi, yi = np.meshgrid(iemre.XAXIS, iemre.YAXIS)
    res = nn(xi, yi)

    # Lets clip bad data
    # 10 inches per hour is bad data
    res = np.where(np.logical_or(res < 0, res > 250), 0., res)
    # print("Resulting mean: %.2f max: %.2f" % (np.mean(res), np.max(res)))

    # Open up our RE file
    nc = ncopen(iemre.get_hourly_ncname(valid.year), 'a', timeout=300)
    nc.variables["p01m"][tidx, :, :] = res
    # print(("Readback mean: %.2f max: %.2f"
    #      ) % (np.mean(nc.variables["p01m"][tidx, :, :]),
    #           np.max(nc.variables["p01m"][tidx, :, :])))
    nc.close()
Exemplo n.º 5
0
def write_grid(valid, vname, grid):
    """Atomic write of data to our netcdf storage

    This is isolated so that we don't 'lock' up our file while intensive
    work is done
    """
    offset = iemre.hourly_offset(valid)
    with ncopen(iemre.get_hourly_ncname(valid.year), "a", timeout=300) as nc:
        nc.variables[vname][offset] = grid
Exemplo n.º 6
0
def do_precip(ts, ds):
    """Compute the 6 UTC to 6 UTC precip

    We need to be careful here as the timestamp sent to this app is today,
    we are actually creating the analysis for yesterday
    """
    sts = utc(ts.year, ts.month, ts.day, 6)
    ets = sts + datetime.timedelta(hours=24)
    offset = iemre.daily_offset(ts)
    offset1 = iemre.hourly_offset(sts)
    offset2 = iemre.hourly_offset(ets)
    if ts.month == 12 and ts.day == 31:
        LOG.warning(
            "p01d      for %s [idx:%s] %s(%s)->%s(%s) SPECIAL",
            ts,
            offset,
            sts.strftime("%Y%m%d%H"),
            offset1,
            ets.strftime("%Y%m%d%H"),
            offset2,
        )
        ncfn = iemre.get_hourly_ncname(ets.year)
        if not os.path.isfile(ncfn):
            LOG.warning("Missing %s", ncfn)
            return
        with ncopen(ncfn, timeout=600) as hnc:
            phour = np.sum(hnc.variables["p01m"][:offset2, :, :], 0)
        ncfn = iemre.get_hourly_ncname(sts.year)
        if os.path.isfile(ncfn):
            with ncopen(ncfn, timeout=600) as hnc:
                phour += np.sum(hnc.variables["p01m"][offset1:, :, :], 0)
    else:
        ncfn = iemre.get_hourly_ncname(sts.year)
        if not os.path.isfile(ncfn):
            LOG.warning("Missing %s", ncfn)
            return
        with ncopen(ncfn, timeout=600) as hnc:
            # for offset in range(offset1, offset2):
            #    LOG.info(
            #        "offset: %s min: %s max: %s",
            #        offset, np.ma.min(hnc.variables['p01m'][offset, :, :]),
            #        np.max(hnc.variables['p01m'][offset, :, :]))
            phour = np.sum(hnc.variables["p01m"][offset1:offset2, :, :], 0)
    ds["p01d"].values = np.where(phour < 0, 0, phour)
Exemplo n.º 7
0
def merge(ts):
    """
    Process an hour's worth of stage4 data into the hourly RE
    """

    # Load up the 12z 24h total, this is what we base our deltas on
    fn = ("/mesonet/ARCHIVE/data/%s/stage4/ST4.%s.24h.grib") % (
        ts.strftime("%Y/%m/%d"),
        ts.strftime("%Y%m%d%H"),
    )
    if not os.path.isfile(fn):
        LOG.info("stage4_12z_adjust %s is missing", fn)
        return False

    grbs = pygrib.open(fn)
    grb = grbs[1]
    val = grb.values
    lats, lons = grb.latlons()
    # can save a bit of memory as we don't need all data
    stride = slice(None, None, 3)
    lats = np.ravel(lats[stride, stride])
    lons = np.ravel(lons[stride, stride])
    vals = np.ravel(val[stride, stride])
    # Clip large values
    vals = np.where(vals > 250.0, 0, vals)
    nn = NearestNDInterpolator((lons, lats), vals)
    xi, yi = np.meshgrid(iemre.XAXIS, iemre.YAXIS)
    stage4 = nn(xi, yi)
    # Prevent Large numbers, negative numbers
    stage4 = np.where(stage4 < 10000.0, stage4, 0.0)
    stage4 = np.where(stage4 < 0.0, 0.0, stage4)

    ts0 = ts - datetime.timedelta(days=1)
    offset0 = iemre.hourly_offset(ts0)
    offset1 = iemre.hourly_offset(ts)
    # Running at 12 UTC 1 Jan
    if offset0 > offset1:
        offset0 = 0
    # Open up our RE file
    with ncopen(iemre.get_hourly_ncname(ts.year), "a", timeout=300) as nc:
        iemre_total = np.sum(nc.variables["p01m"][offset0:offset1, :, :],
                             axis=0)
        iemre_total = np.where(iemre_total > 0.0, iemre_total, 0.00024)
        iemre_total = np.where(iemre_total < 10000.0, iemre_total, 0.00024)
        multiplier = stage4 / iemre_total
        for offset in range(offset0, offset1):
            # Get the unmasked dadta
            data = nc.variables["p01m"][offset, :, :]

            # Keep data within reason
            data = np.where(data > 10000.0, 0.0, data)
            # 0.00024 / 24
            adjust = np.where(data > 0, data, 0.00001) * multiplier
            adjust = np.where(adjust > 250.0, 0, adjust)
            nc.variables["p01m"][offset, :, :] = np.where(
                adjust < 0.01, 0, adjust)
Exemplo n.º 8
0
def main():
    """Go Main Go"""
    sts = datetime.datetime(2018, 4, 20, 0)
    sts = sts.replace(tzinfo=pytz.utc)
    ets = datetime.datetime(2018, 5, 11, 0)
    ets = ets.replace(tzinfo=pytz.utc)

    nc = ncopen(iemre.get_hourly_ncname(sts.year))
    lons = nc.variables['lon'][:]
    lats = nc.variables['lat'][:]
    running = np.zeros((len(nc.dimensions['lat']), len(nc.dimensions['lon'])))
    maxval = np.zeros((len(nc.dimensions['lat']), len(nc.dimensions['lon'])))
    interval = datetime.timedelta(hours=1)
    now = sts
    i, j = iemre.find_ij(-93.61, 41.99)
    while now < ets:
        offset = iemre.hourly_offset(now)
        p01m = np.sum(nc.variables['p01m'][offset - 24:offset], axis=0)
        # 0.05in is 1.27 mm
        this = np.where(p01m > THRESHOLD, 1, 0)
        running = np.where(this == 1, 0, running + 1)
        maxval = np.where(running > maxval, running, maxval)
        print("%s %s %s" % (now, running[j, i], maxval[j, i]))

        now += interval

    # maxval = numpy.where(domain == 1, maxval, 1.e20)

    m = plot.MapPlot(sector='midwest',
                     title=('Max Period '
                            'between 24 Hour 0.25+ inch Total Precipitation'),
                     subtitle=('Period of 20 Apr - 11 May 2018, '
                               'based on NCEP Stage IV data'))

    extra = lons[-1] + (lons[-1] - lons[-2])
    lons[-1] = extra
    # lons = np.concatenate([lons, [extra, ]])

    extra = lats[-1] + (lats[-1] - lats[-2])
    lats[-1] = extra
    # lats = np.concatenate([lats, [extra, ]])

    lons, lats = np.meshgrid(lons, lats)
    # m.pcolormesh(x, y, maxval / 24.0, numpy.arange(0,25,1), units='days')
    maxval = np.where(maxval > 800, 73., maxval)
    cmap = plt.get_cmap('terrain')
    m.contourf(lons, lats, maxval / 24.0, np.arange(1, 11.1, 1), cmap=cmap,
               units='days', clip_on=False)
    m.postprocess(filename='test.png')
Exemplo n.º 9
0
def do_precip(ts):
    """Compute the 6 UTC to 6 UTC precip

    We need to be careful here as the timestamp sent to this app is today,
    we are actually creating the analysis for yesterday
    """
    sts = utc(ts.year, ts.month, ts.day, 6)
    ets = sts + datetime.timedelta(hours=24)
    offset = iemre.daily_offset(ts)
    offset1 = iemre.hourly_offset(sts)
    offset2 = iemre.hourly_offset(ets)
    if ts.month == 12 and ts.day == 31:
        print(("p01d      for %s [idx:%s] %s(%s)->%s(%s) SPECIAL") %
              (ts, offset, sts.strftime("%Y%m%d%H"), offset1,
               ets.strftime("%Y%m%d%H"), offset2))
        ncfn = iemre.get_hourly_ncname(ets.year)
        if not os.path.isfile(ncfn):
            print("Missing %s" % (ncfn, ))
            return
        hnc = ncopen(ncfn, timeout=600)
        phour = np.sum(hnc.variables['p01m'][:offset2, :, :], 0)
        hnc.close()
        ncfn = iemre.get_hourly_ncname(sts.year)
        if os.path.isfile(ncfn):
            hnc = ncopen(ncfn, timeout=600)
            phour += np.sum(hnc.variables['p01m'][offset1:, :, :], 0)
            hnc.close()
    else:
        ncfn = iemre.get_hourly_ncname(sts.year)
        if not os.path.isfile(ncfn):
            print("Missing %s" % (ncfn, ))
            return
        hnc = ncopen(ncfn, timeout=600)
        phour = np.sum(hnc.variables['p01m'][offset1:offset2, :, :], 0)
        hnc.close()
    write_grid(ts, 'p01d', np.where(phour < 0, 0, phour))
Exemplo n.º 10
0
def workflow(sts, ets, i, j):
    """Return a dict of our data."""
    res = []

    # BUG here for Dec 31.
    fn = iemre.get_hourly_ncname(sts.year)

    if not os.path.isfile(fn):
        return res

    if i is None or j is None:
        return {"error": "Coordinates outside of domain"}

    UTC = ZoneInfo("UTC")
    with ncopen(fn) as nc:
        now = sts
        while now <= ets:
            offset = iemre.hourly_offset(now)
            res.append(
                {
                    "valid_utc": now.astimezone(UTC).strftime(ISO),
                    "valid_local": now.strftime(ISO[:-1]),
                    "skyc_%": myrounder(nc.variables["skyc"][offset, j, i], 1),
                    "air_temp_f": myrounder(
                        convert_value(
                            nc.variables["tmpk"][offset, j, i], "degK", "degF"
                        ),
                        1,
                    ),
                    "dew_point_f": myrounder(
                        convert_value(
                            nc.variables["dwpk"][offset, j, i], "degK", "degF"
                        ),
                        1,
                    ),
                    "uwnd_mps": myrounder(
                        nc.variables["uwnd"][offset, j, i], 2
                    ),
                    "vwnd_mps": myrounder(
                        nc.variables["vwnd"][offset, j, i], 2
                    ),
                    "hourly_precip_in": myrounder(
                        mm2inch(nc.variables["p01m"][offset, j, i]), 2
                    ),
                }
            )
            now += datetime.timedelta(hours=1)
    return pd.DataFrame(res)
Exemplo n.º 11
0
def workflow(sts, ets, i, j):
    """Return a dict of our data."""
    res = {"data": [], "generated_at": utc().strftime(ISO)}

    # BUG here for Dec 31.
    fn = iemre.get_hourly_ncname(sts.year)

    if not os.path.isfile(fn):
        return res

    if i is None or j is None:
        return {"error": "Coordinates outside of domain"}

    with ncopen(fn) as nc:
        now = sts
        while now <= ets:
            offset = iemre.hourly_offset(now)
            res["data"].append(
                {
                    "valid_utc": now.astimezone(pytz.UTC).strftime(ISO),
                    "valid_local": now.strftime(ISO),
                    "skyc_%": myrounder(nc.variables["skyc"][offset, j, i], 1),
                    "air_temp_f": myrounder(
                        datatypes.temperature(
                            nc.variables["tmpk"][offset, j, i], "K"
                        ).value("F"),
                        1,
                    ),
                    "dew_point_f": myrounder(
                        datatypes.temperature(
                            nc.variables["dwpk"][offset, j, i], "K"
                        ).value("F"),
                        1,
                    ),
                    "uwnd_mps": myrounder(
                        nc.variables["uwnd"][offset, j, i], 2
                    ),
                    "vwnd_mps": myrounder(
                        nc.variables["vwnd"][offset, j, i], 2
                    ),
                    "hourly_precip_in": myrounder(
                        nc.variables["p01m"][offset, j, i] / 25.4, 2
                    ),
                }
            )
            now += datetime.timedelta(hours=1)
    return res
Exemplo n.º 12
0
def main(argv):
    """Go Main Go."""
    log = logger()
    if len(argv) == 6:
        valid = utc(int(argv[1]), int(argv[2]), int(argv[3]), int(argv[4]))
        ncfn = iemre.get_hourly_ncname(valid.year)
        idx = iemre.hourly_offset(valid)
    else:
        valid = datetime.date(int(argv[1]), int(argv[2]), int(argv[3]))
        ncfn = iemre.get_daily_ncname(valid.year)
        idx = iemre.daily_offset(valid)
    ds = iemre.get_grids(valid)
    with ncopen(ncfn, 'a', timeout=600) as nc:
        for vname in ds:
            if vname not in nc.variables:
                continue
            log.debug("copying database var %s to netcdf", vname)
            nc.variables[vname][idx, :, :] = ds[vname].values
Exemplo n.º 13
0
def compute_hasdata(year):
    """Compute the has_data grid"""
    nc = ncopen(iemre.get_hourly_ncname(year), 'a', timeout=300)
    czs = CachingZonalStats(iemre.AFFINE)
    pgconn = get_dbconn('postgis')
    states = gpd.GeoDataFrame.from_postgis("""
    SELECT the_geom, state_abbr from states
    where state_abbr not in ('AK', 'HI')
    """,
                                           pgconn,
                                           index_col='state_abbr',
                                           geom_col='the_geom')
    data = np.flipud(nc.variables['hasdata'][:, :])
    czs.gen_stats(data, states['the_geom'])
    for nav in czs.gridnav:
        grid = np.ones((nav.ysz, nav.xsz))
        grid[nav.mask] = 0.
        jslice = slice(nav.y0, nav.y0 + nav.ysz)
        islice = slice(nav.x0, nav.x0 + nav.xsz)
        data[jslice, islice] = np.where(grid > 0, 1, data[jslice, islice])
    nc.variables['hasdata'][:, :] = np.flipud(data)
    nc.close()
Exemplo n.º 14
0
def grid_hour(ts):
    """
    I proctor the gridding of data on an hourly basis
    @param ts Timestamp of the analysis, we'll consider a 20 minute window
    """
    pprint("grid_hour called...")
    nc = ncopen(iemre.get_hourly_ncname(ts.year), "a", timeout=300)
    domain = nc.variables["hasdata"][:, :]
    nc.close()
    ts0 = ts - datetime.timedelta(minutes=10)
    ts1 = ts + datetime.timedelta(minutes=10)
    utcnow = datetime.datetime.utcnow()
    utcnow = utcnow.replace(tzinfo=pytz.utc) - datetime.timedelta(hours=36)

    # If we are near realtime, look in IEMAccess instead of ASOS database
    mybuf = 2.0
    params = (
        iemre.WEST - mybuf,
        iemre.SOUTH - mybuf,
        iemre.WEST - mybuf,
        iemre.NORTH + mybuf,
        iemre.EAST + mybuf,
        iemre.NORTH + mybuf,
        iemre.EAST + mybuf,
        iemre.SOUTH - mybuf,
        iemre.WEST - mybuf,
        iemre.SOUTH - mybuf,
        ts0,
        ts1,
    )
    if utcnow < ts:
        dbconn = get_dbconn("iem", user="******")
        sql = """SELECT t.id as station, ST_x(geom) as lon,
        ST_y(geom) as lat,
 max(case when tmpf > -60 and tmpf < 130 THEN tmpf else null end) as max_tmpf,
 max(case when sknt > 0 and sknt < 100 then sknt else 0 end) as max_sknt,
 max(getskyc(skyc1)) as max_skyc1,
 max(getskyc(skyc2)) as max_skyc2,
 max(getskyc(skyc3)) as max_skyc3,
 max(case when phour > 0 and phour < 1000 then phour else 0 end) as phour,
 max(case when dwpf > -60 and dwpf < 100 THEN dwpf else null end) as max_dwpf,
 max(case when sknt >= 0 then sknt else 0 end) as sknt,
 max(case when sknt >= 0 then drct else 0 end) as drct
 from current_log s JOIN stations t on (s.iemid = t.iemid)
 WHERE ST_Contains(
  ST_GeomFromEWKT('SRID=4326;POLYGON((%s %s, %s  %s, %s %s, %s %s, %s %s))'),
  geom) and valid >= %s and valid < %s GROUP by station, lon, lat
         """
    else:
        dbconn = get_dbconn("asos", user="******")
        sql = """SELECT station, ST_x(geom) as lon, st_y(geom) as lat,
 max(case when tmpf > -60 and tmpf < 130 THEN tmpf else null end) as max_tmpf,
 max(case when sknt > 0 and sknt < 100 then sknt else 0 end) as max_sknt,
 max(getskyc(skyc1)) as max_skyc1,
 max(getskyc(skyc2)) as max_skyc2,
 max(getskyc(skyc3)) as max_skyc3,
 max(case when p01i > 0 and p01i < 1000 then p01i else 0 end) as phour,
 max(case when dwpf > -60 and dwpf < 100 THEN dwpf else null end) as max_dwpf,
 max(case when sknt >= 0 then sknt else 0 end) as sknt,
 max(case when sknt >= 0 then drct else 0 end) as drct
 from alldata a JOIN stations t on (a.station = t.id) WHERE
 ST_Contains(
  ST_GeomFromEWKT('SRID=4326;POLYGON((%s %s, %s  %s, %s %s, %s %s, %s %s))'),
  geom) and (t.network ~* 'ASOS' or t.network = 'AWOS') and
 valid >= %s and valid < %s GROUP by station, lon, lat"""

    df = read_sql(sql, dbconn, params=params, index_col="station")
    pprint("got database results")
    if df.empty:
        print(("%s has no entries, FAIL") % (ts.strftime("%Y-%m-%d %H:%M"), ))
        return
    ures, vres = grid_wind(df, domain)
    pprint("grid_wind is done")
    if ures is None:
        print("iemre.hourly_analysis failure for uwnd at %s" % (ts, ))
    else:
        write_grid(ts, "uwnd", ures)
        write_grid(ts, "vwnd", vres)

    tmpf = generic_gridder(df, "max_tmpf", domain)
    pprint("grid tmpf is done")
    if tmpf is None:
        print("iemre.hourly_analysis failure for tmpk at %s" % (ts, ))
    else:
        dwpf = generic_gridder(df, "max_dwpf", domain)
        pprint("grid dwpf is done")
        # require that dwpk <= tmpk
        mask = ~np.isnan(dwpf)
        mask[mask] &= dwpf[mask] > tmpf[mask]
        dwpf = np.where(mask, tmpf, dwpf)
        write_grid(ts, "tmpk",
                   masked_array(tmpf, data_units="degF").to("degK"))
        write_grid(ts, "dwpk",
                   masked_array(dwpf, data_units="degF").to("degK"))

    res = grid_skyc(df, domain)
    pprint("grid skyc is done")
    if res is None:
        print("iemre.hourly_analysis failure for skyc at %s" % (ts, ))
    else:
        write_grid(ts, "skyc", res)
Exemplo n.º 15
0
def init_year(ts):
    """
    Create a new NetCDF file for a year of our specification!
    """

    fn = iemre.get_hourly_ncname(ts.year)
    nc = ncopen(fn, 'w')
    nc.title = "IEM Hourly Reanalysis %s" % (ts.year, )
    nc.platform = "Grided Observations"
    nc.description = "IEM hourly analysis on a 0.125 degree grid"
    nc.institution = "Iowa State University, Ames, IA, USA"
    nc.source = "Iowa Environmental Mesonet"
    nc.project_id = "IEM"
    nc.realization = 1
    nc.Conventions = 'CF-1.0'
    nc.contact = "Daryl Herzmann, [email protected], 515-294-5978"
    nc.history = ("%s Generated") % (
        datetime.datetime.now().strftime("%d %B %Y"), )
    nc.comment = "No Comment at this time"

    # Setup Dimensions
    nc.createDimension('lat', iemre.NY)
    nc.createDimension('lon', iemre.NX)
    ts2 = datetime.datetime(ts.year + 1, 1, 1)
    days = (ts2 - ts).days
    print('Year %s has %s days' % (ts.year, days))
    nc.createDimension('time', int(days) * 24)

    # Setup Coordinate Variables
    lat = nc.createVariable('lat', np.float, ('lat', ))
    lat.units = "degrees_north"
    lat.long_name = "Latitude"
    lat.standard_name = "latitude"
    lat.axis = "Y"
    lat[:] = iemre.YAXIS

    lon = nc.createVariable('lon', np.float, ('lon', ))
    lon.units = "degrees_east"
    lon.long_name = "Longitude"
    lon.standard_name = "longitude"
    lon.axis = "X"
    lon[:] = iemre.XAXIS

    tm = nc.createVariable('time', np.float, ('time', ))
    tm.units = "Hours since %s-01-01 00:00:0.0" % (ts.year, )
    tm.long_name = "Time"
    tm.standard_name = "time"
    tm.axis = "T"
    tm.calendar = "gregorian"
    tm[:] = np.arange(0, int(days) * 24)

    # Tracked variables
    hasdata = nc.createVariable('hasdata', np.int8, ('lat', 'lon'))
    hasdata.units = '1'
    hasdata.long_name = 'Analysis Available for Grid Cell'
    hasdata.coordinates = "lon lat"
    hasdata[:] = 0

    # can storage -128->127 actual values are 0 to 100
    skyc = nc.createVariable('skyc',
                             np.int8, ('time', 'lat', 'lon'),
                             fill_value=-128)
    skyc.long_name = "ASOS Sky Coverage"
    skyc.stanard_name = "ASOS Sky Coverage"
    skyc.units = "%"
    skyc.valid_range = [0, 100]
    skyc.coordinates = "lon lat"

    # 0->65535
    tmpk = nc.createVariable('tmpk',
                             np.uint16, ('time', 'lat', 'lon'),
                             fill_value=65535)
    tmpk.units = "K"
    tmpk.scale_factor = 0.01
    tmpk.long_name = "2m Air Temperature"
    tmpk.standard_name = "2m Air Temperature"
    tmpk.coordinates = "lon lat"

    # 0->65535  0 to 655.35
    dwpk = nc.createVariable('dwpk',
                             np.uint16, ('time', 'lat', 'lon'),
                             fill_value=65335)
    dwpk.units = "K"
    dwpk.scale_factor = 0.01
    dwpk.long_name = "2m Air Dew Point Temperature"
    dwpk.standard_name = "2m Air Dew Point Temperature"
    dwpk.coordinates = "lon lat"

    # 0->65535 0 to 65.535
    uwnd = nc.createVariable('uwnd',
                             np.uint16, ('time', 'lat', 'lon'),
                             fill_value=65335)
    uwnd.units = "meters per second"
    uwnd.scale_factor = 0.001
    uwnd.long_name = "U component of the wind"
    uwnd.standard_name = "U component of the wind"
    uwnd.coordinates = "lon lat"

    # 0->65535 0 to 65.535
    vwnd = nc.createVariable('vwnd',
                             np.uint16, ('time', 'lat', 'lon'),
                             fill_value=65535)
    vwnd.units = "meters per second"
    vwnd.scale_factor = 0.001
    vwnd.long_name = "V component of the wind"
    vwnd.standard_name = "V component of the wind"
    vwnd.coordinates = "lon lat"

    # 0->65535  0 to 655.35
    p01m = nc.createVariable('p01m',
                             np.uint16, ('time', 'lat', 'lon'),
                             fill_value=65535)
    p01m.units = 'mm'
    p01m.scale_factor = 0.01
    p01m.long_name = 'Precipitation'
    p01m.standard_name = 'Precipitation'
    p01m.coordinates = "lon lat"
    p01m.description = "Precipitation accumulation for the hour valid time"

    nc.close()
Exemplo n.º 16
0
def test_ncname():
    """Test the responses for get_names."""
    assert iemre.get_daily_ncname(2020) is not None
    assert iemre.get_hourly_ncname(2020) is not None
    assert iemre.get_daily_mrms_ncname(2020) is not None