Esempio n. 1
0
def workflow(ts):
    """Do Work"""

    # Load up our netcdf file!
    nc = ncopen(iemre.get_dailyc_ncname(), "a", timeout=300)
    grid_day(nc, ts)
    nc.close()

    nc = ncopen(iemre.get_dailyc_mrms_ncname(), "a", timeout=300)
    grid_day(nc, ts)
    nc.close()
Esempio n. 2
0
def plotter(fdict):
    """ Go """
    ctx = util.get_autoplot_context(fdict, get_description())
    ptype = ctx["ptype"]
    sdate = ctx["sdate"]
    edate = ctx["edate"]
    src = ctx["src"]
    opt = ctx["opt"]
    usdm = ctx["usdm"]
    if sdate.year != edate.year:
        raise NoDataFound("Sorry, do not support multi-year plots yet!")
    days = (edate - sdate).days
    sector = ctx["sector"]

    x0 = 0
    x1 = -1
    y0 = 0
    y1 = -1
    state = None
    if len(sector) == 2:
        state = sector
        sector = "state"

    title = compute_title(src, sdate, edate)
    if src == "mrms":
        ncfn = iemre.get_daily_mrms_ncname(sdate.year)
        clncfn = iemre.get_dailyc_mrms_ncname()
        ncvar = "p01d"
        source = "MRMS Q3"
        subtitle = "NOAA MRMS Project, GaugeCorr and RadarOnly"
    elif src == "iemre":
        ncfn = iemre.get_daily_ncname(sdate.year)
        clncfn = iemre.get_dailyc_ncname()
        ncvar = "p01d_12z"
        source = "IEM Reanalysis"
        subtitle = "IEM Reanalysis is derived from various NOAA datasets"
    else:
        ncfn = "/mesonet/data/prism/%s_daily.nc" % (sdate.year, )
        clncfn = "/mesonet/data/prism/prism_dailyc.nc"
        ncvar = "ppt"
        source = "OSU PRISM"
        subtitle = ("PRISM Climate Group, Oregon State Univ., "
                    "http://prism.oregonstate.edu, created 4 Feb 2004.")

    mp = MapPlot(
        sector=sector,
        state=state,
        axisbg="white",
        nocaption=True,
        title="%s:: %s Precip %s" % (source, title, PDICT3[opt]),
        subtitle="Data from %s" % (subtitle, ),
        titlefontsize=14,
    )

    idx0 = iemre.daily_offset(sdate)
    idx1 = iemre.daily_offset(edate) + 1
    if not os.path.isfile(ncfn):
        raise NoDataFound("No data for that year, sorry.")
    with util.ncopen(ncfn) as nc:
        if state is not None:
            x0, y0, x1, y1 = util.grid_bounds(
                nc.variables["lon"][:],
                nc.variables["lat"][:],
                state_bounds[state],
            )
        elif sector in SECTORS:
            bnds = SECTORS[sector]
            x0, y0, x1, y1 = util.grid_bounds(
                nc.variables["lon"][:],
                nc.variables["lat"][:],
                [bnds[0], bnds[2], bnds[1], bnds[3]],
            )
        lats = nc.variables["lat"][y0:y1]
        lons = nc.variables["lon"][x0:x1]
        if sdate == edate:
            p01d = mm2inch(nc.variables[ncvar][idx0, y0:y1, x0:x1])
        elif (idx1 - idx0) < 32:
            p01d = mm2inch(
                np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0))
        else:
            # Too much data can overwhelm this app, need to chunk it
            for i in range(idx0, idx1, 10):
                i2 = min([i + 10, idx1])
                if idx0 == i:
                    p01d = mm2inch(
                        np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0))
                else:
                    p01d += mm2inch(
                        np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0))
    if np.ma.is_masked(np.max(p01d)):
        raise NoDataFound("Data Unavailable")
    plot_units = "inches"
    cmap = get_cmap(ctx["cmap"])
    cmap.set_bad("white")
    if opt == "dep":
        # Do departure work now
        with util.ncopen(clncfn) as nc:
            climo = mm2inch(
                np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0))
        p01d = p01d - climo
        [maxv] = np.percentile(np.abs(p01d), [99])
        clevs = np.around(np.linspace(0 - maxv, maxv, 11), decimals=2)
    elif opt == "per":
        with util.ncopen(clncfn) as nc:
            climo = mm2inch(
                np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0))
        p01d = p01d / climo * 100.0
        cmap.set_under("white")
        cmap.set_over("black")
        clevs = [1, 10, 25, 50, 75, 100, 125, 150, 200, 300, 500]
        plot_units = "percent"
    else:
        p01d = np.where(p01d < 0.001, np.nan, p01d)
        cmap.set_under("white")
        clevs = [0.01, 0.1, 0.3, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 8, 10]
        if days > 6:
            clevs = [0.01, 0.3, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15, 20]
        if days > 29:
            clevs = [0.01, 0.5, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35]
        if days > 90:
            clevs = [0.01, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35, 40]

    x2d, y2d = np.meshgrid(lons, lats)
    if ptype == "c":
        mp.contourf(x2d,
                    y2d,
                    p01d,
                    clevs,
                    cmap=cmap,
                    units=plot_units,
                    iline=False)
    else:
        res = mp.pcolormesh(x2d, y2d, p01d, clevs, cmap=cmap, units=plot_units)
        res.set_rasterized(True)
    if sector != "midwest":
        mp.drawcounties()
        mp.drawcities()
    if usdm == "yes":
        mp.draw_usdm(edate, filled=False, hatched=True)

    return mp.fig
Esempio n. 3
0
def plotter(fdict):
    """ Go """
    ctx = util.get_autoplot_context(fdict, get_description())
    date = ctx['date']
    sector = ctx['sector']
    days = ctx['trailing']
    threshold = ctx['threshold']
    window_sts = date - datetime.timedelta(days=days)
    if window_sts.year != date.year:
        raise ValueError('Sorry, do not support multi-year plots yet!')
    if len(sector) != 2:
        raise ValueError("Sorry, this does not support multi-state plots yet.")

    idx0 = iemre.daily_offset(window_sts)
    idx1 = iemre.daily_offset(date)
    ncfn = iemre.get_daily_mrms_ncname(date.year)
    ncvar = 'p01d'
    if not os.path.isfile(ncfn):
        raise ValueError("No data for that year, sorry.")
    nc = util.ncopen(ncfn)
    # Get the state weight
    df = gpd.GeoDataFrame.from_postgis("""
    SELECT the_geom from states where state_abbr = %s
    """,
                                       util.get_dbconn('postgis'),
                                       params=(sector, ),
                                       index_col=None,
                                       geom_col='the_geom')
    czs = CachingZonalStats(iemre.MRMS_AFFINE)
    czs.gen_stats(
        np.zeros((nc.variables['lat'].size, nc.variables['lon'].size)),
        df['the_geom'])
    hasdata = None
    jslice = None
    islice = None
    for nav in czs.gridnav:
        hasdata = np.ones((nav.ysz, nav.xsz))
        hasdata[nav.mask] = 0.
        # careful here as y is flipped in this context
        jslice = slice(nc.variables['lat'].size - (nav.y0 + nav.ysz),
                       nc.variables['lat'].size - nav.y0)
        islice = slice(nav.x0, nav.x0 + nav.xsz)
    hasdata = np.flipud(hasdata)

    today = distance(nc.variables[ncvar][idx1, jslice, islice],
                     'MM').value('IN')
    if (idx1 - idx0) < 32:
        p01d = distance(
            np.sum(nc.variables[ncvar][idx0:idx1, jslice, islice], 0),
            'MM').value('IN')
    else:
        # Too much data can overwhelm this app, need to chunk it
        for i in range(idx0, idx1, 10):
            i2 = min([i + 10, idx1])
            if idx0 == i:
                p01d = distance(
                    np.sum(nc.variables[ncvar][i:i2, jslice, islice], 0),
                    'MM').value('IN')
            else:
                p01d += distance(
                    np.sum(nc.variables[ncvar][i:i2, jslice, islice], 0),
                    'MM').value('IN')
    nc.close()

    # Get climatology
    nc = util.ncopen(iemre.get_dailyc_mrms_ncname())
    if (idx1 - idx0) < 32:
        c_p01d = distance(
            np.sum(nc.variables[ncvar][idx0:idx1, jslice, islice], 0),
            'MM').value('IN')
    else:
        # Too much data can overwhelm this app, need to chunk it
        for i in range(idx0, idx1, 10):
            i2 = min([i + 10, idx1])
            if idx0 == i:
                c_p01d = distance(
                    np.sum(nc.variables[ncvar][i:i2, jslice, islice], 0),
                    'MM').value('IN')
            else:
                c_p01d += distance(
                    np.sum(nc.variables[ncvar][i:i2, jslice, islice], 0),
                    'MM').value('IN')

    nc.close()

    # we actually don't care about weights at this fine of scale
    cells = np.sum(np.where(hasdata > 0, 1, 0))
    departure = p01d - c_p01d
    # Update departure and today to values unconsidered below when out of state
    departure = np.where(hasdata > 0, departure, -9999)
    today = np.where(hasdata > 0, today, 0)
    ranges = [[-99, -3], [-3, -2], [-2, -1], [-1, 0], [0, 1], [1, 2], [2, 3],
              [3, 99]]
    x = []
    x2 = []
    labels = []
    for (minv, maxv) in ranges:
        labels.append("%.0f to %.0f" % (minv, maxv))
        # How many departure cells in this range
        hits = np.logical_and(departure < maxv, departure > minv)
        hits2 = np.logical_and(hits, today > threshold)
        x.append(np.sum(np.where(hits, 1, 0)) / float(cells) * 100.)
        x2.append(np.sum(np.where(hits2, 1, 0)) / float(cells) * 100.)

    (fig, ax) = plt.subplots(1, 1)
    ax.set_title(("%s NOAA MRMS %s %.2f inch Precip Coverage") %
                 (state_names[sector], date.strftime("%-d %b %Y"), threshold))
    ax.bar(np.arange(8) - 0.2,
           x,
           align='center',
           width=0.4,
           label='Trailing %s Day Departure' % (days, ))
    ax.bar(np.arange(8) + 0.2,
           x2,
           align='center',
           width=0.4,
           label='%s Coverage (%.1f%% Tot)' %
           (date.strftime("%-d %b %Y"), sum(x2)))
    for i, (_x1, _x2) in enumerate(zip(x, x2)):
        ax.text(i - 0.2, _x1 + 1, "%.1f" % (_x1, ), ha='center')
        ax.text(i + 0.2, _x2 + 1, "%.1f" % (_x2, ), ha='center')
    ax.set_xticks(np.arange(8))
    ax.set_xticklabels(labels)
    ax.set_xlabel("Trailing %s Day Precip Departure [in]" % (days, ))
    ax.set_position([0.1, 0.2, 0.8, 0.7])
    ax.legend(loc=(0., -0.2), ncol=2)
    ax.set_ylabel("Areal Coverage of %s [%%]" % (state_names[sector], ))
    ax.grid(True)
    ax.set_xlim(-0.5, 7.5)
    ax.set_ylim(0, max([max(x2), max(x)]) + 5)
    return fig
Esempio n. 4
0
def plotter(fdict):
    """ Go """
    ctx = util.get_autoplot_context(fdict, get_description())
    ptype = ctx['ptype']
    sdate = ctx['sdate']
    edate = ctx['edate']
    src = ctx['src']
    opt = ctx['opt']
    usdm = ctx['usdm']
    if sdate.year != edate.year:
        raise NoDataFound('Sorry, do not support multi-year plots yet!')
    days = (edate - sdate).days
    sector = ctx['sector']

    if sdate == edate:
        title = sdate.strftime("%-d %B %Y")
    else:
        title = "%s to %s (inclusive)" % (sdate.strftime("%-d %b"),
                                          edate.strftime("%-d %b %Y"))
    x0 = 0
    x1 = -1
    y0 = 0
    y1 = -1
    state = None
    if len(sector) == 2:
        state = sector
        sector = 'state'

    if src == 'mrms':
        ncfn = iemre.get_daily_mrms_ncname(sdate.year)
        clncfn = iemre.get_dailyc_mrms_ncname()
        ncvar = 'p01d'
        source = 'MRMS Q3'
        subtitle = 'NOAA MRMS Project, GaugeCorr and RadarOnly'
    elif src == 'iemre':
        ncfn = iemre.get_daily_ncname(sdate.year)
        clncfn = iemre.get_dailyc_ncname()
        ncvar = 'p01d_12z'
        source = 'IEM Reanalysis'
        subtitle = 'IEM Reanalysis is derived from various NOAA datasets'
    else:
        ncfn = "/mesonet/data/prism/%s_daily.nc" % (sdate.year, )
        clncfn = "/mesonet/data/prism/prism_dailyc.nc"
        ncvar = 'ppt'
        source = 'OSU PRISM'
        subtitle = ('PRISM Climate Group, Oregon State Univ., '
                    'http://prism.oregonstate.edu, created 4 Feb 2004.')

    mp = MapPlot(sector=sector,
                 state=state,
                 axisbg='white',
                 nocaption=True,
                 title='%s:: %s Precip %s' % (source, title, PDICT3[opt]),
                 subtitle='Data from %s' % (subtitle, ),
                 titlefontsize=14)

    idx0 = iemre.daily_offset(sdate)
    idx1 = iemre.daily_offset(edate) + 1
    if not os.path.isfile(ncfn):
        raise NoDataFound("No data for that year, sorry.")
    with util.ncopen(ncfn) as nc:
        if state is not None:
            x0, y0, x1, y1 = util.grid_bounds(nc.variables['lon'][:],
                                              nc.variables['lat'][:],
                                              state_bounds[state])
        elif sector in SECTORS:
            bnds = SECTORS[sector]
            x0, y0, x1, y1 = util.grid_bounds(
                nc.variables['lon'][:], nc.variables['lat'][:],
                [bnds[0], bnds[2], bnds[1], bnds[3]])
        lats = nc.variables['lat'][y0:y1]
        lons = nc.variables['lon'][x0:x1]
        if sdate == edate:
            p01d = distance(nc.variables[ncvar][idx0, y0:y1, x0:x1],
                            'MM').value('IN')
        elif (idx1 - idx0) < 32:
            p01d = distance(
                np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0),
                'MM').value('IN')
        else:
            # Too much data can overwhelm this app, need to chunk it
            for i in range(idx0, idx1, 10):
                i2 = min([i + 10, idx1])
                if idx0 == i:
                    p01d = distance(
                        np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0),
                        'MM').value('IN')
                else:
                    p01d += distance(
                        np.sum(nc.variables[ncvar][i:i2, y0:y1, x0:x1], 0),
                        'MM').value('IN')
    if np.ma.is_masked(np.max(p01d)):
        raise NoDataFound("Data Unavailable")
    units = 'inches'
    cmap = plt.get_cmap(ctx['cmap'])
    cmap.set_bad('white')
    if opt == 'dep':
        # Do departure work now
        with util.ncopen(clncfn) as nc:
            climo = distance(
                np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0),
                'MM').value('IN')
        p01d = p01d - climo
        [maxv] = np.percentile(np.abs(p01d), [
            99,
        ])
        clevs = np.around(np.linspace(0 - maxv, maxv, 11), decimals=2)
    elif opt == 'per':
        with util.ncopen(clncfn) as nc:
            climo = distance(
                np.sum(nc.variables[ncvar][idx0:idx1, y0:y1, x0:x1], 0),
                'MM').value('IN')
        p01d = p01d / climo * 100.
        cmap.set_under('white')
        cmap.set_over('black')
        clevs = [1, 10, 25, 50, 75, 100, 125, 150, 200, 300, 500]
        units = 'percent'
    else:
        p01d = np.where(p01d < 0.001, np.nan, p01d)
        cmap.set_under('white')
        clevs = [0.01, 0.1, 0.3, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 8, 10]
        if days > 6:
            clevs = [0.01, 0.3, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 10, 15, 20]
        if days > 29:
            clevs = [0.01, 0.5, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35]
        if days > 90:
            clevs = [0.01, 1, 2, 3, 4, 5, 6, 8, 10, 15, 20, 25, 30, 35, 40]

    x2d, y2d = np.meshgrid(lons, lats)
    if ptype == 'c':
        mp.contourf(x2d, y2d, p01d, clevs, cmap=cmap, units=units, iline=False)
    else:
        res = mp.pcolormesh(x2d, y2d, p01d, clevs, cmap=cmap, units=units)
        res.set_rasterized(True)
    if sector != 'midwest':
        mp.drawcounties()
        mp.drawcities()
    if usdm == 'yes':
        mp.draw_usdm(edate, filled=False, hatched=True)

    return mp.fig
Esempio n. 5
0
def init_year(ts):
    """
    Create a new NetCDF file for a year of our specification!
    """
    fn = iemre.get_dailyc_mrms_ncname()
    nc = ncopen(fn, "w")
    nc.title = "IEM Daily Reanalysis Climatology %s" % (ts.year, )
    nc.platform = "Grided Climatology"
    nc.description = "IEM daily analysis on a 0.01 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"  # *cough*
    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.NORTH - iemre.SOUTH) * 100.0)
    nc.createDimension("lon", (iemre.EAST - iemre.WEST) * 100.0)
    ts2 = datetime.datetime(ts.year + 1, 1, 1)
    days = (ts2 - ts).days
    nc.createDimension("time", int(days))
    nc.createDimension("nv", 2)

    # Setup Coordinate Variables
    lat = nc.createVariable("lat", np.float, ("lat", ))
    lat.units = "degrees_north"
    lat.long_name = "Latitude"
    lat.standard_name = "latitude"
    lat.bounds = "lat_bnds"
    lat.axis = "Y"
    # Grid centers
    lat[:] = np.arange(iemre.SOUTH + 0.005, iemre.NORTH, 0.01)

    lat_bnds = nc.createVariable("lat_bnds", np.float, ("lat", "nv"))
    lat_bnds[:, 0] = np.arange(iemre.SOUTH, iemre.NORTH, 0.01)
    lat_bnds[:, 1] = np.arange(iemre.SOUTH + 0.01, iemre.NORTH + 0.01, 0.01)

    lon = nc.createVariable("lon", np.float, ("lon", ))
    lon.units = "degrees_east"
    lon.long_name = "Longitude"
    lon.standard_name = "longitude"
    lon.bounds = "lon_bnds"
    lon.axis = "X"
    lon[:] = np.arange(iemre.WEST, iemre.EAST, 0.01)

    lon_bnds = nc.createVariable("lon_bnds", np.float, ("lon", "nv"))
    lon_bnds[:, 0] = np.arange(iemre.WEST, iemre.EAST, 0.01)
    lon_bnds[:, 1] = np.arange(iemre.WEST + 0.01, iemre.EAST + 0.01, 0.01)

    tm = nc.createVariable("time", np.float, ("time", ))
    tm.units = "Days 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))

    p01d = nc.createVariable("p01d",
                             np.uint16, ("time", "lat", "lon"),
                             fill_value=65535)
    p01d.units = "mm"
    p01d.scale_factor = 0.01
    p01d.long_name = "Precipitation"
    p01d.standard_name = "Precipitation"
    p01d.coordinates = "lon lat"
    p01d.description = "Precipitation accumulation for the day"

    nc.close()