From 272f35e7ce2e4173fd261202cd9741ed3ce1c1ab Mon Sep 17 00:00:00 2001
From: akrherz
Date: Tue, 28 Jan 2025 12:16:11 -0600
Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Sundry=20updates=20per=20review?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
htdocs/COOP/current.phtml | 3 +++
htdocs/COOP/extremes.php | 12 +++++-------
htdocs/COOP/index.phtml | 4 ++--
htdocs/COOP/periods.phtml | 4 ++--
htdocs/COOP/snowd_duration.phtml | 10 +++++-----
htdocs/GIS/apps/agclimate/month.php | 12 +++++++-----
htdocs/RWIS/currentSF.phtml | 3 +++
pylib/iemweb/autoplot/scripts/p49.py | 6 ++----
pylib/iemweb/autoplot/scripts/p50.py | 23 +++++++++++++----------
pylib/iemweb/autoplot/scripts/p51.py | 2 +-
pylib/iemweb/autoplot/scripts100/p134.py | 8 +++-----
scripts/prism/grid_climate_prism.py | 9 +++++----
tests/iemweb/autoplot/urllist.txt | 2 ++
13 files changed, 53 insertions(+), 45 deletions(-)
diff --git a/htdocs/COOP/current.phtml b/htdocs/COOP/current.phtml
index d029291b61..8130d62880 100644
--- a/htdocs/COOP/current.phtml
+++ b/htdocs/COOP/current.phtml
@@ -154,6 +154,9 @@ $cols = array(
"snowd" => "Snowfall Depth", "pday" => "24 hour rainfall",
"phour" => "Rainfall One Hour", "snoww" => "Snow Water Equivalent"
);
+if (!array_key_exists($sortcol, $cols)) {
+ xssafe("");
+}
$t->current_network = "COOP";
$nselect = '
+Download Daily Climatology.
+
The data found in this table was derived from the following
JSON webservice:
{$URI}
@@ -247,5 +245,5 @@
{$table}
-EOF;
+EOM;
$t->render('single.phtml');
diff --git a/htdocs/COOP/index.phtml b/htdocs/COOP/index.phtml
index dd506e9752..596c1a5023 100644
--- a/htdocs/COOP/index.phtml
+++ b/htdocs/COOP/index.phtml
@@ -97,7 +97,7 @@ EOF;
$news = get_news_by_tag("coop");
-$t->content = <<content = <<National Weather Service Cooperative Observer Program (COOP)
@@ -216,5 +216,5 @@ div.tease a {
-EOF;
+EOM;
$t->render('full.phtml');
diff --git a/htdocs/COOP/periods.phtml b/htdocs/COOP/periods.phtml
index 2a47c011db..62c0d07ee2 100644
--- a/htdocs/COOP/periods.phtml
+++ b/htdocs/COOP/periods.phtml
@@ -74,7 +74,7 @@ $emonthselect = monthSelect($emonth, "emonth");
$edayselect = daySelect2($eday, "eday");
$nselect = networkSelect($network, $station);
$sselect = selectClimodatNetwork($network, "network");
-$t->content = <<content = <<
NWS COOP
Yearly time period averages
@@ -111,5 +111,5 @@ like.
Errors exist in this dataset and you should evaluate the observations
before using...
-EOF;
+EOM;
$t->render('single.phtml');
diff --git a/htdocs/COOP/snowd_duration.phtml b/htdocs/COOP/snowd_duration.phtml
index d8e057c04d..c709eb6748 100644
--- a/htdocs/COOP/snowd_duration.phtml
+++ b/htdocs/COOP/snowd_duration.phtml
@@ -12,7 +12,7 @@ $station = isset($_GET["station"]) ? xssafe($_GET["station"]) : 'IA0200';
$month = get_int404("month", 12);
$day = get_int404("day", 25);
-$ts = strtotime("2000-${month}-${day}");
+$ts = strtotime("2000-{$month}-{$day}");
$sday = date('md', $ts);
$rs = pg_prepare($coopdb, "FIND", "SELECT * from alldata_ia
@@ -21,11 +21,11 @@ $rs = pg_prepare($coopdb, "FIND", "SELECT * from alldata_ia
$rs = pg_prepare($coopdb, "FIND2", "SELECT min(day) as m from alldata_ia
WHERE day > $1 and station = $2 and snowd = 0");
-$table = <<
Start Day | Depth [inch] | End Date |
Duration [days] |
-EOF;
+EOM;
/* Find all snow days for this date! */
$rs = pg_execute($coopdb, "FIND", array(strtoupper($station), $sday));
@@ -54,7 +54,7 @@ $t->title = "COOP Snow Depth Duration";
$nselect = networkSelect("IACLIMATE", $station);
$mselect = monthSelect($month);
$dselect = daySelect($day);
-$t->content = <<content = <<
NWS COOP Network
Snow Depth Duration
@@ -82,5 +82,5 @@ ground for Christmas in Ames, how long does it stick around for?"
{$table}
-EOF;
+EOM;
$t->render('single.phtml');
diff --git a/htdocs/GIS/apps/agclimate/month.php b/htdocs/GIS/apps/agclimate/month.php
index 94579c636c..b429596251 100644
--- a/htdocs/GIS/apps/agclimate/month.php
+++ b/htdocs/GIS/apps/agclimate/month.php
@@ -68,12 +68,14 @@
for ($i = 0; $row = pg_fetch_assoc($rs); $i++) {
$key = $row["station"];
if ($key == "AMFI4" or $key == "AHTI4") continue;
+ $minv = strtotime($row["min_valid"]);
+ $maxv = strtotime($row["max_valid"]);
- if (is_null($minvalid) || $row["min_valid"] < $minvalid) {
- $minvalid = $row["min_valid"];
+ if (is_null($minvalid) || $minv < $minvalid) {
+ $minvalid = $minv;
}
- if (is_null($maxvalid) || $row["max_valid"] > $maxvalid) {
- $maxvalid = $row["max_valid"];
+ if (is_null($maxvalid) || $maxv > $maxvalid) {
+ $maxvalid = $maxv;
}
if ($dvar == "rain_in_tot") {
$val = round($row["s"], 2);
@@ -104,7 +106,7 @@
$minvalid = date("Y-m-d", $minvalid);
$maxvalid = date("Y-m-d", $maxvalid);
iemmap_title($map, $img, $title[$dvar] . " [ " .
- date("d M", $minvalid) . " thru " . date("d M Y", $maxvalid) . " ]");
+ $minvalid . " thru " . $maxvalid . " ]");
}
$map->drawLabelCache($img);
diff --git a/htdocs/RWIS/currentSF.phtml b/htdocs/RWIS/currentSF.phtml
index f1516645a6..e139c5e324 100644
--- a/htdocs/RWIS/currentSF.phtml
+++ b/htdocs/RWIS/currentSF.phtml
@@ -29,6 +29,9 @@ $vals = array(
"ts" => "Observation Time",
"name" => "Site Name",
);
+if (!array_key_exists($sortcol, $vals)) {
+ xssafe("");
+}
$t->breadcrumbs = <<
diff --git a/pylib/iemweb/autoplot/scripts/p49.py b/pylib/iemweb/autoplot/scripts/p49.py
index 3a193ecc8c..9124ee4deb 100644
--- a/pylib/iemweb/autoplot/scripts/p49.py
+++ b/pylib/iemweb/autoplot/scripts/p49.py
@@ -131,9 +131,8 @@ def plotter(ctx: dict):
func = "avg" if days == 1 else ctx["f"]
with get_sqlalchemy_conn("coop") as conn:
df = pd.read_sql(
- (
- text(
- f"""
+ text(
+ f"""
WITH data as (
SELECT sday, {func}({varname})
OVER (ORDER by day ASC ROWS between
@@ -145,7 +144,6 @@ def plotter(ctx: dict):
min(day) as min_date, max(day) as max_date from data
WHERE sday != '0229' GROUP by sday ORDER by sday ASC
"""
- )
),
conn,
params=params,
diff --git a/pylib/iemweb/autoplot/scripts/p50.py b/pylib/iemweb/autoplot/scripts/p50.py
index 541b20e9b9..c1f3fc2f0d 100644
--- a/pylib/iemweb/autoplot/scripts/p50.py
+++ b/pylib/iemweb/autoplot/scripts/p50.py
@@ -16,6 +16,7 @@
from pyiem.plot import figure_axes
from pyiem.plot.use_agg import plt
from pyiem.reference import state_names
+from sqlalchemy import text
PDICT = {"state": "Aggregate by State", "wfo": "Aggregate by WFO"}
PDICT2 = {"percent": "Frequency [%]", "count": "Count"}
@@ -91,9 +92,12 @@ def plotter(ctx: dict):
state = ctx["state"]
date1 = ctx.get("date1", date(2010, 4, 1))
date2 = ctx.get("date2", date.today() + timedelta(days=1))
- wfo_limiter = (
- f"and wfo = '{station if len(station) == 3 else station[1:]}' "
- )
+ params = {
+ "sts": date1,
+ "ets": date2,
+ "wfo": station if len(station) == 3 else station[1:],
+ }
+ wfo_limiter = "and wfo = :wfo "
if station == "_ALL":
wfo_limiter = ""
status_limiter = "and status = 'NEW'"
@@ -104,8 +108,8 @@ def plotter(ctx: dict):
SELECT wfo, eventid, vtec_year,
min(polygon_begin) as min_issue,
max(windtag) as max_windtag, max(hailtag) as max_hailtag
- from sbw WHERE polygon_begin >= %s and
- polygon_begin <= %s {wfo_limiter}
+ from sbw WHERE polygon_begin >= :sts and
+ polygon_begin <= :ets {wfo_limiter}
and (windtag > 0 or hailtag > 0) and phenomena = 'SV' and
significance = 'W' {status_limiter}
GROUP by wfo, eventid, vtec_year
@@ -115,7 +119,6 @@ def plotter(ctx: dict):
max(min_issue at time zone 'UTC') as max_issue, count(*)
from data GROUP by windtag, hailtag
"""
- args = (date1, date2)
supextra = ""
if opt == "wfo" and station != "_ALL":
supextra = (
@@ -134,8 +137,8 @@ def plotter(ctx: dict):
min(polygon_begin) as min_issue,
max(windtag) as max_windtag, max(hailtag) as max_hailtag
from sbw w, states s
- WHERE polygon_begin >= %s and polygon_begin <= %s and
- s.state_abbr = %s and ST_Intersects(s.the_geom, w.geom)
+ WHERE polygon_begin >= :sts and polygon_begin <= :ets and
+ s.state_abbr = :state and ST_Intersects(s.the_geom, w.geom)
and (windtag > 0 or hailtag > 0) and phenomena = 'SV' and
significance = 'W' {status_limiter}
GROUP by wfo, eventid, vtec_year
@@ -145,9 +148,9 @@ def plotter(ctx: dict):
max(min_issue at time zone 'UTC') as max_issue, count(*)
from data GROUP by windtag, hailtag
"""
- args = (date1, date2, state)
+ params["state"] = state
with get_sqlalchemy_conn("postgis") as conn:
- df = pd.read_sql(sql, conn, params=args, index_col=None)
+ df = pd.read_sql(text(sql), conn, params=params, index_col=None)
if df.empty:
raise NoDataFound("No data was found.")
minvalid = df["min_issue"].min()
diff --git a/pylib/iemweb/autoplot/scripts/p51.py b/pylib/iemweb/autoplot/scripts/p51.py
index b5147538ad..ba0bdef4ab 100644
--- a/pylib/iemweb/autoplot/scripts/p51.py
+++ b/pylib/iemweb/autoplot/scripts/p51.py
@@ -194,7 +194,7 @@ def plotter(ctx: dict):
gddxx(:gddbase, :gddceil, c2f(tair_c_max_qc), c2f(tair_c_min_qc))
as o{glabel},
coalesce(rain_in_tot_qc, 0) as oprecip,
- sdd86( c2f(tair_c_max_qc), c2f(tair_c_min_qc)) as osdd86
+ sdd86(c2f(tair_c_max_qc), c2f(tair_c_min_qc)) as osdd86
from sm_daily
WHERE station = :station and to_char(valid, 'mmdd') != '0229'
ORDER by day ASC"""),
diff --git a/pylib/iemweb/autoplot/scripts100/p134.py b/pylib/iemweb/autoplot/scripts100/p134.py
index 0b786763a9..c435b8e9e9 100644
--- a/pylib/iemweb/autoplot/scripts100/p134.py
+++ b/pylib/iemweb/autoplot/scripts100/p134.py
@@ -216,9 +216,7 @@ def plotter(ctx: dict):
minval = df[XREF[varname]].min() - 1.0
maxval = df[XREF[varname]].max() + 1.0
if varname in ["wettest", "driest"]:
- if minval < 0:
- minval = 0
- ramp = pretty_bins(minval, maxval)
+ ramp = pretty_bins(max(0, minval), maxval)
else:
ramp = np.linspace(
minval, maxval, min([int(maxval - minval), 10]), dtype="i"
@@ -232,7 +230,7 @@ def plotter(ctx: dict):
df.index.values,
[days] * len(df.index),
left=df["doy"].values,
- color=cmap(norm(df[XREF[varname]].values)),
+ color=cmap(norm(df[XREF[varname]].to_numpy())),
)
ax.grid(True)
lax.grid(True)
@@ -280,7 +278,7 @@ def plotter(ctx: dict):
# CDF
ax = fig.add_axes((0.59, 0.1, 0.4, 0.3))
- X2 = np.sort(series.values)
+ X2 = np.sort(series.to_numpy())
ptile = np.percentile(X2, [0, 5, 50, 95, 100])
N = len(series.values)
F2 = np.array(range(N)) / float(N) * 100.0
diff --git a/scripts/prism/grid_climate_prism.py b/scripts/prism/grid_climate_prism.py
index 37a7a9bd21..22480c88cb 100644
--- a/scripts/prism/grid_climate_prism.py
+++ b/scripts/prism/grid_climate_prism.py
@@ -55,7 +55,7 @@ def grid_day(nc, ts):
I proctor the gridding of data on an hourly basis
@param ts Timestamp of the analysis, we'll consider a 20 minute window
"""
- COOP, cursor = get_dbconnc("coop")
+ pgconn, cursor = get_dbconnc("coop")
offset = iemre.daily_offset(ts)
if ts.day == 29 and ts.month == 2:
ts = datetime(2000, 3, 1)
@@ -83,6 +83,8 @@ def grid_day(nc, ts):
("%s has %02i entries, FAIL")
% (ts.strftime("%Y-%m-%d"), cursor.rowcount)
)
+ cursor.close()
+ pgconn.close()
def workflow(ts):
@@ -90,9 +92,8 @@ def workflow(ts):
# Load up a station table we are interested in
# Load up our netcdf file!
- nc = ncopen("/mesonet/data/prism/prism_dailyc.nc", "a")
- grid_day(nc, ts)
- nc.close()
+ with ncopen("/mesonet/data/prism/prism_dailyc.nc", "a") as nc:
+ grid_day(nc, ts)
@click.command()
diff --git a/tests/iemweb/autoplot/urllist.txt b/tests/iemweb/autoplot/urllist.txt
index 162b714dfb..c70e6b50f6 100644
--- a/tests/iemweb/autoplot/urllist.txt
+++ b/tests/iemweb/autoplot/urllist.txt
@@ -48,6 +48,8 @@
/plotting/auto/plot/44/plot:line::opt:fema::network:WFO::station:DMX::state:IA::fema:7::limit:no::c:svrtor::phenomena:TO::significance:W::syear:1986::eyear:2024::s:jan1::_r:t::dpi:100.png
/plotting/auto/plot/44/plot:bar::opt:state::network:WFO::station:_ALL::state:VA::fema:7::limit:no::c:single::phenomena:FW::significance:W::syear:1986::eyear:2024::s:jul1::_r:43::dpi:100.png
/plotting/auto/plot/48/ugc:IAC169::phenomena:TO::significance:W::_r:t::dpi:100.png
+/plotting/auto/plot/50/network:WFO::station:OAX::state:IA::opt:wfo::p:count::agg:issuance::date1:2010-04-01::date2:2025-01-29::_r:43::dpi:100.png
+/plotting/auto/plot/50/network:WFO::station:DMX::state:IA::opt:state::p:count::agg:max::date1:2010-04-01::date2:2025-01-29::_r:43::dpi:100.png
/plotting/auto/plot/51/network:ISUSM::station:BOOI4::sdate:2024-05-01::edate:2024-07-27::base:50::ceil:86::which:all::_r:t::dpi:100.png
/plotting/auto/plot/51/network:ISUSM::station:BOOI4::sdate:2024-05-01::edate:2024-07-27::base:50::ceil:86::which:gdd::_r:t::dpi:100.png
/plotting/auto/plot/51/network:ISUSM::station:BOOI4::sdate:2024-05-01::edate:2024-07-27::base:50::ceil:86::which:precip::_r:t::dpi:100.png