def test_ij(self): """Can we get valid indices back!""" res = prism.find_ij(-98.0, 32) self.assertEquals(res[0], 647) res = prism.find_ij(98.0, 32) self.assertTrue(res[0] is None)
def test_ij(): """Can we get valid indices back!""" res = prism.find_ij(-98.0, 32) assert res[0] == 647 res = prism.find_ij(98.0, 32) assert res[0] is None
def dowork(form): """Do work!""" dates = compute_dates(form.getfirst('valid')) lat = float(form.getfirst("lat")) lon = float(form.getfirst("lon")) i, j = prism.find_ij(lon, lat) res = { 'gridi': int(i), 'gridj': int(j), 'data': [], 'disclaimer': ("PRISM Climate Group, Oregon State University, " "http://prism.oregonstate.edu, created 4 Feb 2004.") } if i is None or j is None: ssw(json.dumps({'error': 'Coordinates outside of domain'})) return for dpair in dates: sts = dpair[0] ets = dpair[-1] sidx = prism.daily_offset(sts) eidx = prism.daily_offset(ets) + 1 ncfn = "/mesonet/data/prism/%s_daily.nc" % (sts.year, ) if not os.path.isfile(ncfn): continue nc = ncopen(ncfn) tmax = nc.variables['tmax'][sidx:eidx, j, i] tmin = nc.variables['tmin'][sidx:eidx, j, i] ppt = nc.variables['ppt'][sidx:eidx, j, i] nc.close() for tx, (mt, nt, pt) in enumerate(zip(tmax, tmin, ppt)): valid = sts + datetime.timedelta(days=tx) res['data'].append({ 'valid': valid.strftime("%Y-%m-%dT12:00:00Z"), 'high_f': myrounder(datatypes.temperature(mt, 'C').value('F'), 1), 'low_f': myrounder(datatypes.temperature(nt, 'C').value('F'), 1), 'precip_in': myrounder(datatypes.distance(pt, 'MM').value('IN'), 2) }) return json.dumps(res)
def dowork(valid, lon, lat): """Do work!""" dates = compute_dates(valid) i, j = prism.find_ij(lon, lat) res = { "gridi": int(i), "gridj": int(j), "data": [], "disclaimer": ("PRISM Climate Group, Oregon State University, " "http://prism.oregonstate.edu, created 4 Feb 2004."), } if i is None or j is None: return "Coordinates outside of domain" for dpair in dates: sts = dpair[0] ets = dpair[-1] sidx = prism.daily_offset(sts) eidx = prism.daily_offset(ets) + 1 ncfn = "/mesonet/data/prism/%s_daily.nc" % (sts.year, ) if not os.path.isfile(ncfn): continue with ncopen(ncfn) as nc: tmax = nc.variables["tmax"][sidx:eidx, j, i] tmin = nc.variables["tmin"][sidx:eidx, j, i] ppt = nc.variables["ppt"][sidx:eidx, j, i] for tx, (mt, nt, pt) in enumerate(zip(tmax, tmin, ppt)): valid = sts + datetime.timedelta(days=tx) res["data"].append({ "valid": valid.strftime("%Y-%m-%dT12:00:00Z"), "high_f": myrounder(datatypes.temperature(mt, "C").value("F"), 1), "low_f": myrounder(datatypes.temperature(nt, "C").value("F"), 1), "precip_in": myrounder(datatypes.distance(pt, "MM").value("IN"), 2), }) return json.dumps(res)
def do(form): """Do work!""" dates = compute_dates(form.getfirst('valid')) lat = float(form.getfirst("lat")) lon = float(form.getfirst("lon")) i, j = prism.find_ij(lon, lat) res = {'gridi': i, 'gridj': j, 'data': [], 'disclaimer': ("PRISM Climate Group, Oregon State University, " "http://prism.oregonstate.edu, created 4 Feb 2004.")} if i is None or j is None: sys.stdout.write(json.dumps({'error': 'Coordinates outside of domain'} )) return for dpair in dates: sts = dpair[0] ets = dpair[-1] sidx = prism.daily_offset(sts) eidx = prism.daily_offset(ets) + 1 ncfn = "/mesonet/data/prism/%s_daily.nc" % (sts.year, ) nc = netCDF4.Dataset(ncfn, 'r') tmax = nc.variables['tmax'][sidx:eidx, j, i] tmin = nc.variables['tmin'][sidx:eidx, j, i] ppt = nc.variables['ppt'][sidx:eidx, j, i] nc.close() for tx, (mt, nt, pt) in enumerate(zip(tmax, tmin, ppt)): valid = sts + datetime.timedelta(days=tx) res['data'].append({ 'valid': valid.strftime("%Y-%m-%dT12:00:00Z"), 'high_f': myrounder( datatypes.temperature(mt, 'C').value('F'), 1), 'low_f': myrounder( datatypes.temperature(nt, 'C').value('F'), 1), 'precip_in': myrounder( datatypes.distance(pt, 'MM').value('IN'), 2) }) return json.dumps(res)
def workflow(valid): """Our workflow""" if valid.month == 1 and valid.day == 1: print("prism_adjust_stage4, sorry Jan 1 processing is a TODO!") return # read prism tidx = daily_offset(valid) nc = ncopen("/mesonet/data/prism/%s_daily.nc" % (valid.year, ), 'r') ppt = nc.variables['ppt'][tidx, :, :] # missing as zero ppt = np.where(ppt.mask, 0, ppt) lons = nc.variables['lon'][:] lats = nc.variables['lat'][:] nc.close() (lons, lats) = np.meshgrid(lons, lats) i, j = prismutil.find_ij(DEBUGLON, DEBUGLAT) LOG.debug("prism debug point ppt: %.3f", ppt[j, i]) # Interpolate this onto the stage4 grid nc = ncopen(("/mesonet/data/stage4/%s_stage4_hourly.nc" ) % (valid.year, ), 'a', timeout=300) p01m = nc.variables['p01m'] p01m_status = nc.variables['p01m_status'] s4lons = nc.variables['lon'][:] s4lats = nc.variables['lat'][:] i, j = find_ij(s4lons, s4lats, DEBUGLON, DEBUGLAT) # Values are in the hourly arrears, so start at -23 and thru current hour sts_tidx = hourly_offset(valid - datetime.timedelta(hours=23)) ets_tidx = hourly_offset(valid + datetime.timedelta(hours=1)) s4total = np.sum(p01m[sts_tidx:ets_tidx, :, :], axis=0) LOG.debug( "stage4 s4total: %.3f lon: %.2f (%.2f) lat: %.2f (%.2f)", s4total[i, j], s4lons[i, j], DEBUGLON, s4lats[i, j], DEBUGLAT ) # make sure the s4total does not have zeros s4total = np.where(s4total < 0.001, 0.001, s4total) nn = NearestNDInterpolator((lons.flatten(), lats.flatten()), ppt.flat) prism_on_s4grid = nn(s4lons, s4lats) LOG.debug( "shape of prism_on_s4grid: %s s4lons: %s ll: %.2f s4lats: %s ll: %.2f", np.shape(prism_on_s4grid), np.shape(s4lons), s4lons[0, 0], np.shape(s4lats), s4lats[0, 0] ) multiplier = prism_on_s4grid / s4total LOG.debug( "prism avg: %.3f stageIV avg: %.3f prismons4grid avg: %.3f mul: %.3f", np.mean(ppt), np.mean(s4total), np.mean(prism_on_s4grid), np.mean(multiplier) ) LOG.debug( "Boone IA0807 prism: %.3f stageIV: %.4f prismons4grid: %.3f mul: %.3f", ppt[431, 746], s4total[i, j], prism_on_s4grid[i, j], multiplier[i, j] ) # Do the work now, we should not have to worry about the scale factor for tidx in range(sts_tidx, ets_tidx): oldval = p01m[tidx, :, :] # we threshold the s4total to at least 0.001, so we divide by 24 here # and denote that if the multiplier is zero, then we net zero newval = np.where(oldval < 0.001, 0.00004, oldval) * multiplier nc.variables['p01m'][tidx, :, :] = newval LOG.debug( "adjust tidx: %s oldval: %.3f newval: %.3f", tidx, oldval[i, j], newval[i, j] ) # make sure have data if np.ma.max(newval) > 0: p01m_status[tidx] = 2 else: print(("prism_adjust_stage4 NOOP for time %s[idx:%s]" ) % ((datetime.datetime(valid.year, 1, 1, 0) + datetime.timedelta(hours=tidx) ).strftime("%Y-%m-%dT%H"), tidx)) nc.close() """
def main(): """Go Main Go""" form = cgi.FieldStorage() ts1 = datetime.datetime.strptime(form.getfirst("date1"), "%Y-%m-%d") ts2 = datetime.datetime.strptime(form.getfirst("date2"), "%Y-%m-%d") if ts1 > ts2: send_error("date1 larger than date2") if ts1.year != ts2.year: send_error("multi-year query not supported yet...") # Make sure we aren't in the future tsend = datetime.date.today() if ts2.date() > tsend: ts2 = datetime.datetime.now() - datetime.timedelta(days=1) lat = float(form.getfirst("lat")) lon = float(form.getfirst("lon")) if lon < iemre.WEST or lon > iemre.EAST: send_error("lon value outside of bounds: %s to %s" % (iemre.WEST, iemre.EAST)) if lat < iemre.SOUTH or lat > iemre.NORTH: send_error("lat value outside of bounds: %s to %s" % (iemre.SOUTH, iemre.NORTH)) # fmt = form["format"][0] i, j = iemre.find_ij(lon, lat) offset1 = iemre.daily_offset(ts1) offset2 = iemre.daily_offset(ts2) + 1 # Get our netCDF vars with ncopen(iemre.get_daily_ncname(ts1.year)) as nc: hightemp = datatypes.temperature( nc.variables['high_tmpk'][offset1:offset2, j, i], 'K').value("F") high12temp = datatypes.temperature( nc.variables['high_tmpk_12z'][offset1:offset2, j, i], 'K').value("F") lowtemp = datatypes.temperature( nc.variables['low_tmpk'][offset1:offset2, j, i], 'K').value("F") low12temp = datatypes.temperature( nc.variables['low_tmpk_12z'][offset1:offset2, j, i], 'K').value("F") precip = nc.variables['p01d'][offset1:offset2, j, i] / 25.4 precip12 = nc.variables['p01d_12z'][offset1:offset2, j, i] / 25.4 # Get our climatology vars c2000 = ts1.replace(year=2000) coffset1 = iemre.daily_offset(c2000) c2000 = ts2.replace(year=2000) coffset2 = iemre.daily_offset(c2000) + 1 cnc = ncopen(iemre.get_dailyc_ncname()) chigh = datatypes.temperature( cnc.variables['high_tmpk'][coffset1:coffset2, j, i], 'K').value("F") clow = datatypes.temperature( cnc.variables['low_tmpk'][coffset1:coffset2, j, i], 'K').value("F") cprecip = cnc.variables['p01d'][coffset1:coffset2, j, i] / 25.4 cnc.close() if ts1.year > 1980: nc = ncopen("/mesonet/data/prism/%s_daily.nc" % (ts1.year, )) i2, j2 = prismutil.find_ij(lon, lat) prism_precip = nc.variables['ppt'][offset1:offset2, j2, i2] / 25.4 nc.close() else: prism_precip = [None] * (offset2 - offset1) if ts1.year > 2010: nc = ncopen(iemre.get_daily_mrms_ncname(ts1.year)) j2 = int((lat - iemre.SOUTH) * 100.0) i2 = int((lon - iemre.WEST) * 100.0) mrms_precip = nc.variables['p01d'][offset1:offset2, j2, i2] / 25.4 nc.close() else: mrms_precip = [None] * (offset2 - offset1) res = { 'data': [], } for i in range(0, offset2 - offset1): now = ts1 + datetime.timedelta(days=i) res['data'].append({ 'date': now.strftime("%Y-%m-%d"), 'mrms_precip_in': clean(mrms_precip[i]), 'prism_precip_in': clean(prism_precip[i]), 'daily_high_f': clean(hightemp[i]), '12z_high_f': clean(high12temp[i]), 'climate_daily_high_f': clean(chigh[i]), 'daily_low_f': clean(lowtemp[i]), '12z_low_f': clean(low12temp[i]), 'climate_daily_low_f': clean(clow[i]), 'daily_precip_in': clean(precip[i]), '12z_precip_in': clean(precip12[i]), 'climate_daily_precip_in': clean(cprecip[i]) }) ssw('Content-type: application/json\n\n') ssw(json.dumps(res))
def main(): """Do Something Fun!""" form = cgi.FieldStorage() ts = datetime.datetime.strptime(form.getfirst("date"), "%Y-%m-%d") lat = float(form.getfirst("lat")) lon = float(form.getfirst("lon")) fmt = form.getfirst("format") if fmt != 'json': ssw("Content-type: text/plain\n\n") ssw("ERROR: Service only emits json at this time") return i, j = iemre.find_ij(lon, lat) offset = iemre.daily_offset(ts) res = { 'data': [], } fn = iemre.get_daily_ncname(ts.year) ssw('Content-type: application/json\n\n') if not os.path.isfile(fn): ssw(json.dumps(res)) sys.exit() if i is None or j is None: ssw(json.dumps({'error': 'Coordinates outside of domain'})) return if ts.year > 1980: ncfn = "/mesonet/data/prism/%s_daily.nc" % (ts.year, ) if not os.path.isfile(ncfn): prism_precip = None else: i2, j2 = prismutil.find_ij(lon, lat) with ncopen(ncfn) as nc: prism_precip = nc.variables['ppt'][offset, j2, i2] / 25.4 else: prism_precip = None if ts.year > 2010: ncfn = iemre.get_daily_mrms_ncname(ts.year) if not os.path.isfile(ncfn): mrms_precip = None else: j2 = int((lat - iemre.SOUTH) * 100.0) i2 = int((lon - iemre.WEST) * 100.0) with ncopen(ncfn) as nc: mrms_precip = nc.variables['p01d'][offset, j2, i2] / 25.4 else: mrms_precip = None nc = ncopen(fn) c2000 = ts.replace(year=2000) coffset = iemre.daily_offset(c2000) cnc = ncopen(iemre.get_dailyc_ncname()) res['data'].append({ 'prism_precip_in': myrounder(prism_precip, 2), 'mrms_precip_in': myrounder(mrms_precip, 2), 'daily_high_f': myrounder( datatypes.temperature(nc.variables['high_tmpk'][offset, j, i], 'K').value('F'), 1), '12z_high_f': myrounder( datatypes.temperature(nc.variables['high_tmpk_12z'][offset, j, i], 'K').value('F'), 1), 'climate_daily_high_f': myrounder( datatypes.temperature(cnc.variables['high_tmpk'][coffset, j, i], 'K').value("F"), 1), 'daily_low_f': myrounder( datatypes.temperature(nc.variables['low_tmpk'][offset, j, i], 'K').value("F"), 1), '12z_low_f': myrounder( datatypes.temperature(nc.variables['low_tmpk_12z'][offset, j, i], 'K').value('F'), 1), 'avg_dewpoint_f': myrounder( datatypes.temperature(nc.variables['avg_dwpk'][offset, j, i], 'K').value('F'), 1), 'climate_daily_low_f': myrounder( datatypes.temperature(cnc.variables['low_tmpk'][coffset, j, i], 'K').value("F"), 1), 'daily_precip_in': myrounder(nc.variables['p01d'][offset, j, i] / 25.4, 2), '12z_precip_in': myrounder(nc.variables['p01d_12z'][offset, j, i] / 25.4, 2), 'climate_daily_precip_in': myrounder(cnc.variables['p01d'][coffset, j, i] / 25.4, 2), 'srad_mj': myrounder(nc.variables['rsds'][offset, j, i] * 86400. / 1000000., 2), 'avg_windspeed_mps': myrounder(nc.variables['wind_speed'][offset, j, i], 2), }) nc.close() cnc.close() ssw(json.dumps(res))
def application(environ, start_response): """Do Something Fun!""" form = parse_formvars(environ) ts = datetime.datetime.strptime(form.get("date", "2019-03-01"), "%Y-%m-%d") lat = float(form.get("lat", 41.99)) lon = float(form.get("lon", -95.1)) fmt = form.get("format", "json") if fmt != "json": headers = [("Content-type", "text/plain")] start_response("200 OK", headers) return [b"ERROR: Service only emits json at this time"] i, j = iemre.find_ij(lon, lat) offset = iemre.daily_offset(ts) res = {"data": []} fn = iemre.get_daily_ncname(ts.year) headers = [("Content-type", "application/json")] start_response("200 OK", headers) if not os.path.isfile(fn): return [json.dumps(res).encode("ascii")] if i is None or j is None: data = {"error": "Coordinates outside of domain"} return [json.dumps(data).encode("ascii")] if ts.year > 1980: ncfn = "/mesonet/data/prism/%s_daily.nc" % (ts.year, ) if not os.path.isfile(ncfn): prism_precip = None else: i2, j2 = prismutil.find_ij(lon, lat) with ncopen(ncfn) as nc: prism_precip = nc.variables["ppt"][offset, j2, i2] / 25.4 else: prism_precip = None if ts.year > 2010: ncfn = iemre.get_daily_mrms_ncname(ts.year) if not os.path.isfile(ncfn): mrms_precip = None else: j2 = int((lat - iemre.SOUTH) * 100.0) i2 = int((lon - iemre.WEST) * 100.0) with ncopen(ncfn) as nc: mrms_precip = nc.variables["p01d"][offset, j2, i2] / 25.4 else: mrms_precip = None c2000 = ts.replace(year=2000) coffset = iemre.daily_offset(c2000) with ncopen(fn) as nc: with ncopen(iemre.get_dailyc_ncname()) as cnc: res["data"].append({ "prism_precip_in": myrounder(prism_precip, 2), "mrms_precip_in": myrounder(mrms_precip, 2), "daily_high_f": myrounder( datatypes.temperature( nc.variables["high_tmpk"][offset, j, i], "K").value("F"), 1, ), "12z_high_f": myrounder( datatypes.temperature( nc.variables["high_tmpk_12z"][offset, j, i], "K").value("F"), 1, ), "climate_daily_high_f": myrounder( datatypes.temperature( cnc.variables["high_tmpk"][coffset, j, i], "K").value("F"), 1, ), "daily_low_f": myrounder( datatypes.temperature( nc.variables["low_tmpk"][offset, j, i], "K").value("F"), 1, ), "12z_low_f": myrounder( datatypes.temperature( nc.variables["low_tmpk_12z"][offset, j, i], "K").value("F"), 1, ), "avg_dewpoint_f": myrounder( datatypes.temperature( nc.variables["avg_dwpk"][offset, j, i], "K").value("F"), 1, ), "climate_daily_low_f": myrounder( datatypes.temperature( cnc.variables["low_tmpk"][coffset, j, i], "K").value("F"), 1, ), "daily_precip_in": myrounder(nc.variables["p01d"][offset, j, i] / 25.4, 2), "12z_precip_in": myrounder(nc.variables["p01d_12z"][offset, j, i] / 25.4, 2), "climate_daily_precip_in": myrounder(cnc.variables["p01d"][coffset, j, i] / 25.4, 2), "srad_mj": myrounder( nc.variables["rsds"][offset, j, i] * 86400.0 / 1000000.0, 2, ), "avg_windspeed_mps": myrounder(nc.variables["wind_speed"][offset, j, i], 2), }) return [json.dumps(res).encode("ascii")]
def application(environ, start_response): """Go Main Go""" form = parse_formvars(environ) ts1 = datetime.datetime.strptime(form.get("date1"), "%Y-%m-%d") ts2 = datetime.datetime.strptime(form.get("date2"), "%Y-%m-%d") if ts1 > ts2: return [send_error(start_response, "date1 larger than date2")] if ts1.year != ts2.year: return [ send_error(start_response, "multi-year query not supported yet...") ] # Make sure we aren't in the future tsend = datetime.date.today() if ts2.date() > tsend: ts2 = datetime.datetime.now() - datetime.timedelta(days=1) lat = float(form.get("lat")) lon = float(form.get("lon")) if lon < iemre.WEST or lon > iemre.EAST: return [ send_error( start_response, "lon value outside of bounds: %s to %s" % (iemre.WEST, iemre.EAST), ) ] if lat < iemre.SOUTH or lat > iemre.NORTH: return [ send_error( start_response, "lat value outside of bounds: %s to %s" % (iemre.SOUTH, iemre.NORTH), ) ] # fmt = form["format"][0] i, j = iemre.find_ij(lon, lat) offset1 = iemre.daily_offset(ts1) offset2 = iemre.daily_offset(ts2) + 1 # Get our netCDF vars with ncopen(iemre.get_daily_ncname(ts1.year)) as nc: hightemp = datatypes.temperature( nc.variables["high_tmpk"][offset1:offset2, j, i], "K" ).value("F") high12temp = datatypes.temperature( nc.variables["high_tmpk_12z"][offset1:offset2, j, i], "K" ).value("F") lowtemp = datatypes.temperature( nc.variables["low_tmpk"][offset1:offset2, j, i], "K" ).value("F") low12temp = datatypes.temperature( nc.variables["low_tmpk_12z"][offset1:offset2, j, i], "K" ).value("F") precip = nc.variables["p01d"][offset1:offset2, j, i] / 25.4 precip12 = nc.variables["p01d_12z"][offset1:offset2, j, i] / 25.4 # Get our climatology vars c2000 = ts1.replace(year=2000) coffset1 = iemre.daily_offset(c2000) c2000 = ts2.replace(year=2000) coffset2 = iemre.daily_offset(c2000) + 1 with ncopen(iemre.get_dailyc_ncname()) as cnc: chigh = datatypes.temperature( cnc.variables["high_tmpk"][coffset1:coffset2, j, i], "K" ).value("F") clow = datatypes.temperature( cnc.variables["low_tmpk"][coffset1:coffset2, j, i], "K" ).value("F") cprecip = cnc.variables["p01d"][coffset1:coffset2, j, i] / 25.4 if ts1.year > 1980: i2, j2 = prismutil.find_ij(lon, lat) with ncopen("/mesonet/data/prism/%s_daily.nc" % (ts1.year,)) as nc: prism_precip = nc.variables["ppt"][offset1:offset2, j2, i2] / 25.4 else: prism_precip = [None] * (offset2 - offset1) if ts1.year > 2010: j2 = int((lat - iemre.SOUTH) * 100.0) i2 = int((lon - iemre.WEST) * 100.0) with ncopen(iemre.get_daily_mrms_ncname(ts1.year)) as nc: mrms_precip = nc.variables["p01d"][offset1:offset2, j2, i2] / 25.4 else: mrms_precip = [None] * (offset2 - offset1) res = {"data": []} for i in range(0, offset2 - offset1): now = ts1 + datetime.timedelta(days=i) res["data"].append( { "date": now.strftime("%Y-%m-%d"), "mrms_precip_in": clean(mrms_precip[i]), "prism_precip_in": clean(prism_precip[i]), "daily_high_f": clean(hightemp[i]), "12z_high_f": clean(high12temp[i]), "climate_daily_high_f": clean(chigh[i]), "daily_low_f": clean(lowtemp[i]), "12z_low_f": clean(low12temp[i]), "climate_daily_low_f": clean(clow[i]), "daily_precip_in": clean(precip[i]), "12z_precip_in": clean(precip12[i]), "climate_daily_precip_in": clean(cprecip[i]), } ) start_response("200 OK", [("Content-type", "application/json")]) return [json.dumps(res).encode("ascii")]
def service( fmt: SupportedFormatsNoGeoJSON, sdate: datetime.date = Query(..., description="Start Date."), edate: datetime.date = Query(..., description="End Date."), lon: float = Query(..., description="Longitude of point of interest"), lat: float = Query(..., description="Latitude of point of interest"), ): """Go Main Go""" # Make sure we aren't in the future tsend = datetime.date.today() if edate > tsend: edate = datetime.date.today() - datetime.timedelta(days=1) i, j = iemre.find_ij(lon, lat) offset1 = iemre.daily_offset(sdate) offset2 = iemre.daily_offset(edate) + 1 # Get our netCDF vars with ncopen(iemre.get_daily_ncname(sdate.year)) as nc: hightemp = convert_value( nc.variables["high_tmpk"][offset1:offset2, j, i], "degK", "degF" ) high12temp = convert_value( nc.variables["high_tmpk_12z"][offset1:offset2, j, i], "degK", "degF", ) lowtemp = convert_value( nc.variables["low_tmpk"][offset1:offset2, j, i], "degK", "degF" ) low12temp = convert_value( nc.variables["low_tmpk_12z"][offset1:offset2, j, i], "degK", "degF" ) precip = mm2inch(nc.variables["p01d"][offset1:offset2, j, i]) precip12 = mm2inch(nc.variables["p01d_12z"][offset1:offset2, j, i]) # Get our climatology vars c2000 = sdate.replace(year=2000) coffset1 = iemre.daily_offset(c2000) c2000 = edate.replace(year=2000) coffset2 = iemre.daily_offset(c2000) + 1 with ncopen(iemre.get_dailyc_ncname()) as cnc: chigh = convert_value( cnc.variables["high_tmpk"][coffset1:coffset2, j, i], "degK", "degF" ) clow = convert_value( cnc.variables["low_tmpk"][coffset1:coffset2, j, i], "degK", "degF" ) cprecip = mm2inch( cnc.variables["p01d"][coffset1:coffset2, j, i], ) if sdate.year > 1980: i2, j2 = prismutil.find_ij(lon, lat) with ncopen(f"/mesonet/data/prism/{sdate.year}_daily.nc") as nc: prism_precip = mm2inch( nc.variables["ppt"][offset1:offset2, j2, i2], ) else: prism_precip = [None] * (offset2 - offset1) if sdate.year > 2000: j2 = int((lat - iemre.SOUTH) * 100.0) i2 = int((lon - iemre.WEST) * 100.0) with ncopen(iemre.get_daily_mrms_ncname(sdate.year)) as nc: mrms_precip = mm2inch( nc.variables["p01d"][offset1:offset2, j2, i2], ) else: mrms_precip = [None] * (offset2 - offset1) res = [] for i in range(0, offset2 - offset1): now = sdate + datetime.timedelta(days=i) res.append( { "date": now.strftime("%Y-%m-%d"), "mrms_precip_in": clean(mrms_precip[i]), "prism_precip_in": clean(prism_precip[i]), "daily_high_f": clean(hightemp[i]), "12z_high_f": clean(high12temp[i]), "climate_daily_high_f": clean(chigh[i]), "daily_low_f": clean(lowtemp[i]), "12z_low_f": clean(low12temp[i]), "climate_daily_low_f": clean(clow[i]), "daily_precip_in": clean(precip[i]), "12z_precip_in": clean(precip12[i]), "climate_daily_precip_in": clean(cprecip[i]), } ) return deliver_df(pd.DataFrame(res), fmt)
def service( fmt: SupportedFormatsNoGeoJSON, date: datetime.date = Query(..., description="The date of interest."), lon: float = Query(..., description="Longitude of point of interest"), lat: float = Query(..., description="Latitude of point of interest"), ): """Do Something Fun!""" i, j = iemre.find_ij(lon, lat) offset = iemre.daily_offset(date) res = [] fn = iemre.get_daily_ncname(date.year) if date.year > 1980: ncfn = f"/mesonet/data/prism/{date.year}_daily.nc" if not os.path.isfile(ncfn): prism_precip = None else: i2, j2 = prismutil.find_ij(lon, lat) with ncopen(ncfn) as nc: prism_precip = mm2inch(nc.variables["ppt"][offset, j2, i2]) else: prism_precip = None if date.year > 2000: ncfn = iemre.get_daily_mrms_ncname(date.year) if not os.path.isfile(ncfn): mrms_precip = None else: j2 = int((lat - iemre.SOUTH) * 100.0) i2 = int((lon - iemre.WEST) * 100.0) with ncopen(ncfn) as nc: mrms_precip = mm2inch(nc.variables["p01d"][offset, j2, i2]) else: mrms_precip = None c2000 = date.replace(year=2000) coffset = iemre.daily_offset(c2000) with ncopen(fn) as nc: with ncopen(iemre.get_dailyc_ncname()) as cnc: res.append({ "prism_precip_in": myrounder(prism_precip, 2), "mrms_precip_in": myrounder(mrms_precip, 2), "daily_high_f": myrounder( convert_value( nc.variables["high_tmpk"][offset, j, i], "degK", "degF", ), 1, ), "12z_high_f": myrounder( convert_value( nc.variables["high_tmpk_12z"][offset, j, i], "degK", "degF", ), 1, ), "climate_daily_high_f": myrounder( convert_value( cnc.variables["high_tmpk"][coffset, j, i], "degK", "degF", ), 1, ), "daily_low_f": myrounder( convert_value( nc.variables["low_tmpk"][offset, j, i], "degK", "degF", ), 1, ), "12z_low_f": myrounder( convert_value( nc.variables["low_tmpk_12z"][offset, j, i], "degK", "degF", ), 1, ), "avg_dewpoint_f": myrounder( convert_value( nc.variables["avg_dwpk"][offset, j, i], "degK", "degF", ), 1, ), "climate_daily_low_f": myrounder( convert_value( cnc.variables["low_tmpk"][coffset, j, i], "degK", "degF", ), 1, ), "daily_precip_in": myrounder(mm2inch(nc.variables["p01d"][offset, j, i]), 2), "12z_precip_in": myrounder(mm2inch(nc.variables["p01d_12z"][offset, j, i]), 2), "climate_daily_precip_in": myrounder(mm2inch(cnc.variables["p01d"][coffset, j, i]), 2), "srad_mj": myrounder( nc.variables["rsds"][offset, j, i] * 86400.0 / 1000000.0, 2, ), "avg_windspeed_mps": myrounder(nc.variables["wind_speed"][offset, j, i], 2), }) return deliver_df(pd.DataFrame(res), fmt)