From c463cbd9bb684542eb5ccdcdbe31b1254dca9850 Mon Sep 17 00:00:00 2001 From: sclaw Date: Wed, 16 Apr 2025 13:11:42 -0400 Subject: [PATCH 01/24] gh-6 --- hydroshift/text/changepoint.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hydroshift/text/changepoint.py b/hydroshift/text/changepoint.py index a88be2f..f69200b 100644 --- a/hydroshift/text/changepoint.py +++ b/hydroshift/text/changepoint.py @@ -15,6 +15,8 @@ - The threshold for identifying changepoints in the streaming analysis is defined using an Average Run Length (ARL0) parameter. ARL0 reflects the frequency with which a false positive would be raised on a stationary timeseries (e.g., for an ARL0 of 1,000 a false changepoint would be identified on a stationary timeseries on average every 1,000 samples.). For this analysis, an ARL0 of {} was used. - A burn-in period of {} years was selected to ignore singificant change points in the first {} years of the record due to the influence of small sample sizes. +If the flood peak series contained any gaps, the data around the gap was joined as if there was no gap between the data points. For large data gaps, this assumption could lead to inaccurate results. + """ references = """ Gordon J. Ross (2015)., "Parametric and Nonparametric Sequential Change Detection in R: The cpm Package.", Journal of Statistical Software, 66(3), 1-20., https://www.jstatsoft.org/v66/i03/. From db17c6764f4f3d1f2868f602d1eb0f10def0bf43 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 22 Apr 2025 16:15:01 -0400 Subject: [PATCH 02/24] gh-2 --- hydroshift/plots.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/hydroshift/plots.py b/hydroshift/plots.py index ac01f2c..dc5ca7f 100644 --- a/hydroshift/plots.py +++ b/hydroshift/plots.py @@ -4,6 +4,7 @@ import plotly.graph_objects as go import streamlit as st from plotly.subplots import make_subplots +from scipy.stats import norm def plot_ams(ams_df, gage_id, cps: dict = {}): @@ -161,9 +162,10 @@ def plot_lp3(data: dict | list, gage_id: str, multi_series: bool = False): peaks.sort() aep = np.arange(1, len(peaks) + 1)[::-1] / (len(peaks) + 1) ri = 1 / aep + z = norm.ppf(1 - aep) fig.add_trace( go.Scatter( - x=ri, + x=z, y=peaks, mode="markers", marker=dict(size=8, symbol="circle-open"), @@ -173,11 +175,13 @@ def plot_lp3(data: dict | list, gage_id: str, multi_series: bool = False): name = i + " - Log-Pearson III Fit" lp3 = data[i]["lp3"] - return_periods = list(map(int, lp3.keys())) + + return_periods = [int(i) if i.is_integer() else round(i, 1) for i in lp3.keys()] + z2 = [norm.ppf(1 - (1 / i)) for i in return_periods] peak_flows = list(lp3.values()) fig.add_trace( go.Scatter( - x=return_periods, + x=z2, y=peak_flows, mode="markers+lines", marker=dict(size=8), @@ -190,11 +194,10 @@ def plot_lp3(data: dict | list, gage_id: str, multi_series: bool = False): title=f"{gage_id} | Log-Pearson Type III Estimates (No Regional Skew)", xaxis=dict( title="Return Period (years)", - type="log", - tickvals=return_periods, - ticktext=[str(rp) for rp in return_periods], + tickvals=z2, + ticktext=return_periods, ), - yaxis=dict(title="Peak Flow (cfs)"), + yaxis=dict(title="Peak Flow (cfs)", type="log"), showlegend=True, template="plotly_white", ) @@ -400,7 +403,7 @@ def combo_cpm(ams_df: pd.DataFrame, pval_df: pd.DataFrame, cps: dict = {}): ), legend_tracegroupgap=10, xaxis2=dict(title="Date"), - yaxis=dict(title="Peak Flow"), + yaxis=dict(title="Peak Flow (cfs)"), yaxis2=dict(title="Statistical Test"), legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="left", x=0), height=600, From 99f56edcea149c79b6618378473b518d7c7414d6 Mon Sep 17 00:00:00 2001 From: sclaw Date: Wed, 23 Apr 2025 12:29:26 -0400 Subject: [PATCH 03/24] incremental refactor commit --- hydroshift/_pages/__init__.py | 1 + hydroshift/_pages/changepoint.py | 27 +++++++---- hydroshift/_pages/homepage.py | 40 ++++++++++++++++ hydroshift/_pages/summary.py | 36 +++++++-------- hydroshift/consts.py | 12 +++++ hydroshift/data_retrieval.py | 34 +++++--------- hydroshift/stats/ffa.py | 64 ++++++++++++++++++++++++++ hydroshift/streamlit_app.py | 46 +------------------ hydroshift/utils/data_models.py | 69 ++++++++++++++++++++++++++++ hydroshift/utils/jinja.py | 33 +++++++++++++ templates/app_description.md | 4 ++ templates/changepoint_description.md | 16 +++++++ templates/changepoint_references.md | 1 + templates/data_sources_side_bar.html | 10 ++++ templates/footer.html | 33 +++++++++++++ templates/site_summary.md | 6 +++ 16 files changed, 337 insertions(+), 95 deletions(-) create mode 100644 hydroshift/_pages/homepage.py create mode 100644 hydroshift/stats/ffa.py create mode 100644 hydroshift/utils/data_models.py create mode 100644 hydroshift/utils/jinja.py create mode 100644 templates/app_description.md create mode 100644 templates/changepoint_description.md create mode 100644 templates/changepoint_references.md create mode 100644 templates/data_sources_side_bar.html create mode 100644 templates/footer.html create mode 100644 templates/site_summary.md diff --git a/hydroshift/_pages/__init__.py b/hydroshift/_pages/__init__.py index f8097f9..6548600 100644 --- a/hydroshift/_pages/__init__.py +++ b/hydroshift/_pages/__init__.py @@ -1,2 +1,3 @@ from hydroshift._pages.changepoint import changepoint +from hydroshift._pages.homepage import homepage from hydroshift._pages.summary import summary diff --git a/hydroshift/_pages/changepoint.py b/hydroshift/_pages/changepoint.py index 319a1df..152854c 100644 --- a/hydroshift/_pages/changepoint.py +++ b/hydroshift/_pages/changepoint.py @@ -16,10 +16,18 @@ from plotly import graph_objects from plots import combo_cpm, plot_lp3 -from hydroshift.consts import METRICS, VALID_ARL0S +from hydroshift.consts import ( + CP_F1_CAPTION, + CP_F2_CAPTION, + CP_T1_CAPTION, + CP_T2_CAPTION, + METRICS, + VALID_ARL0S, +) from hydroshift.data_retrieval import log_pearson_iii from hydroshift.stats.tests import cp_pvalue_batch, cpm_process_stream from hydroshift.text.changepoint import references, test_description +from hydroshift.utils.jinja import write_template @dataclass @@ -377,6 +385,9 @@ def make_sidebar(): column_config={"Regime Start": start_config, "Regime End": end_config}, ) + st.divider() + write_template("footer.html") + def run_analysis(): """Run the change point model analysis.""" @@ -441,10 +452,10 @@ def make_body(): st.header("Summary") st.markdown(cpa.summary_text) st.plotly_chart(cpa.summary_plot, use_container_width=True) - st.markdown("**Figure 1.** Statistical changepoint analysis.") + st.markdown(CP_F1_CAPTION) st.header("Changepoint detection method") - st.markdown( - test_description.format(st.session_state.arlo_slider, st.session_state.burn_in, st.session_state.burn_in) + write_template( + "changepoint_description.md", {"arl0": st.session_state.arlo_slider, "burnin": st.session_state.burn_in} ) if len(cpa.cp_dict) > 0: @@ -452,9 +463,7 @@ def make_body(): st.markdown(cpa.results_text) if len(cpa.cp_dict) > 1: st.table(cpa.cp_df) - st.markdown( - "**Table 1.** Results of the changepoint analysis, listing dates when a significant change was identified for each test statistic." - ) + st.markdown(CP_T1_CAPTION) st.header("Modified flood frequency analysis") if len(st.session_state.ffa_regimes["added_rows"]) > 0: @@ -464,8 +473,8 @@ def make_body(): cpa.ffa_plot = ffa_plot cpa.ffa_df = ffa_df st.plotly_chart(ffa_plot, use_container_width=True) - st.markdown("**Figure 2.** Modified flood frequency analysis.") - st.markdown("**Table 2.** Modified flood quantiles.") + st.markdown(CP_F2_CAPTION) + st.markdown(CP_T2_CAPTION) st.table(ffa_df) else: st.info( diff --git a/hydroshift/_pages/homepage.py b/hydroshift/_pages/homepage.py new file mode 100644 index 0000000..f3c2a00 --- /dev/null +++ b/hydroshift/_pages/homepage.py @@ -0,0 +1,40 @@ +import streamlit as st + +from hydroshift.consts import DEFAULT_GAGE +from hydroshift.utils.jinja import write_template + + +def homepage(): + """Landing page for app.""" + st.set_page_config(page_title="HydroShift", layout="wide") + + left_col, right_col, _ = st.columns([2, 1.5, 0.2], gap="large") + + with left_col: + st.title("HydroShift") + st.subheader("USGS Streamflow Change Detection Tool") + write_template("app_description.md") + + st.write("") # blank line for more space + gage_input = st.text_input("Enter a USGS Gage Number to begin:") + col1, col2 = st.columns([1, 8]) + with col1: + submit = st.button("Submit") + with col2: + demo = st.button("Use Demo Data") + + if submit and gage_input: + st.session_state["gage_id"] = gage_input + if demo: + st.session_state["gage_id"] = DEFAULT_GAGE + if st.session_state["gage_id"] is not None: + # try: + # st.session_state["site_data"] = load_site_data(st.session_state["gage_id"]) + # except ValueError: + # st.error(f"Data not found for gage: {st.session_state['gage_id']}") + st.rerun() + with right_col: + st.title("") + st.image("hydroshift/images/logo_base.png") + + write_template("footer.html") diff --git a/hydroshift/_pages/summary.py b/hydroshift/_pages/summary.py index f1259b1..8df1182 100644 --- a/hydroshift/_pages/summary.py +++ b/hydroshift/_pages/summary.py @@ -16,6 +16,9 @@ ) from streamlit_folium import st_folium +from hydroshift.utils.data_models import Gage +from hydroshift.utils.jinja import write_template + def summary(): """Display summary plots for various timeseries associated with this gage.""" @@ -24,6 +27,7 @@ def summary(): with st.sidebar: st.title("Settings") st.session_state["gage_id"] = st.text_input("Enter USGS Gage Number:", st.session_state["gage_id"]) + gage = Gage(st.session_state["gage_id"]) # Toggle plots st.markdown("### Toggle Plots") @@ -34,22 +38,26 @@ def summary(): show_daily_mean = st.checkbox("Daily Mean Streamflow", value=True) show_monthly_mean = st.checkbox("Monthly Mean Streamflow", value=True) + # Data sources + st.divider() + write_template("data_sources_side_bar.html") + if st.session_state["gage_id"]: with st.spinner("Loading gage data..."): # This is mainly here to clear previous pages while data loads. try: if st.session_state["gage_id"] == "testing": site_data = { - "Site Number": "-99999", - "Station Name": "Wet River", - "Latitude": 45, - "Longitude": -103, - "Drainage Area": 0, - "HUC Code": 0, - "Elevation Datum": "NAVD88", + "site_no": "-99999", + "station_nm": "Wet River", + "dec_lat_va": 45, + "dec_long_va": -103, + "drain_area_va": 0, + "huc_cd": 0, + "alt_datum_cd": "NAVD88", } else: site_data = st.session_state["site_data"] - lat, lon = site_data["Latitude"], site_data["Longitude"] + lat, lon = site_data["dec_lat_va"], site_data["dec_long_va"] except ValueError as e: lat, lon = None, None st.error(f"{e}") @@ -69,17 +77,7 @@ def summary(): # Display site metadata st.subheader("Site Information") - st.markdown( - f""" - **Site Number:** {site_data["Site Number"]}
- **Station Name:** {site_data["Station Name"]}
- **Latitude:** {site_data["Latitude"]}
- **Longitude:** {site_data["Longitude"]}
- **Drainage Area (sq.mi.):** {site_data["Drainage Area"]}
- **HUC Code:** {site_data["HUC Code"]}
- """, - unsafe_allow_html=True, - ) + write_template("site_summary.md", site_data) with col2: # Center column for plots if show_ams: diff --git a/hydroshift/consts.py b/hydroshift/consts.py index d239930..49d5071 100644 --- a/hydroshift/consts.py +++ b/hydroshift/consts.py @@ -31,3 +31,15 @@ 50000, ] METRICS = ["Cramer-von-Mises", "Kolmogorov-Smirnov", "Lepage", "Mann-Whitney", "Mood"] + +### External URLs ### +NWIS_URL = "https://waterdata.usgs.gov/nwis?" +PEAKFQ_URL = "https://www.usgs.gov/tools/peakfq" + +### Text snippets ### +DATA_SOURCES_STR = f"Data: [USGS NWIS]({NWIS_URL}) and [USGS PEAKFQ]({PEAKFQ_URL})" + +CP_F1_CAPTION = "**Figure 1.** Statistical changepoint analysis." +CP_T1_CAPTION = "**Table 1.** Results of the changepoint analysis, listing dates when a significant change was identified for each test statistic." +CP_F2_CAPTION = "**Figure 2.** Modified flood frequency analysis." +CP_T2_CAPTION = "**Table 2.** Modified flood quantiles." diff --git a/hydroshift/data_retrieval.py b/hydroshift/data_retrieval.py index 2b41355..1c91a04 100644 --- a/hydroshift/data_retrieval.py +++ b/hydroshift/data_retrieval.py @@ -2,11 +2,12 @@ import numpy as np import pandas as pd -import scipy.stats as stats import streamlit as st from dataretrieval import NoSitesError, nwis from scipy.stats import genpareto +from hydroshift.stats.ffa import log_pearson_iii + @st.cache_data def get_ams(gage_id): @@ -20,7 +21,9 @@ def get_ams(gage_id): logging.warning(f"Peaks could not be found for gage id: {gage_id}") return {"peaks": None, "lp3": None, "missing_years": None} - df["season"] = ((df.index.month % 12 + 3) // 3).map({1: "Winter", 2: "Spring", 3: "Summer", 4: "Fall"}) + df["season"] = ((df.index.month % 12 + 3) // 3).map( + {1: "Winter", 2: "Spring", 3: "Summer", 4: "Fall"} + ) # TODO: should add labels like Winter(JFM), Spring(AMJ), etc missing_years = check_missing_dates(df, "water_year") @@ -50,26 +53,13 @@ def load_site_data(gage_number: str) -> dict: raise ValueError(f"Gage {gage_number} not found") return { - "Site Number": resp["site_no"].iloc[0], - "Station Name": resp["station_nm"].iloc[0], - "Latitude": float(resp["dec_lat_va"].iloc[0]), - "Longitude": float(resp["dec_long_va"].iloc[0]), - "Drainage Area": resp["drain_area_va"].iloc[0], - "HUC Code": resp["huc_cd"].iloc[0], - "Elevation Datum": resp["alt_datum_cd"].iloc[0], - } - - -@st.cache_data -def log_pearson_iii(peak_flows: pd.Series, standard_return_periods: list = [2, 5, 10, 25, 50, 100, 500]): - log_flows = np.log10(peak_flows.values) - mean_log = np.mean(log_flows) - std_log = np.std(log_flows, ddof=1) - skew_log = stats.skew(log_flows) - - return { - str(rp): int(10 ** (mean_log + stats.pearson3.ppf(1 - 1 / rp, skew_log) * std_log)) - for rp in standard_return_periods + "site_no": resp["site_no"].iloc[0], + "station_nm": resp["station_nm"].iloc[0], + "dec_lat_va": float(resp["dec_lat_va"].iloc[0]), + "dec_long_va": float(resp["dec_long_va"].iloc[0]), + "drain_area_va": resp["drain_area_va"].iloc[0], + "huc_cd": resp["huc_cd"].iloc[0], + "alt_datum_cd": resp["alt_datum_cd"].iloc[0], } diff --git a/hydroshift/stats/ffa.py b/hydroshift/stats/ffa.py new file mode 100644 index 0000000..d8714b0 --- /dev/null +++ b/hydroshift/stats/ffa.py @@ -0,0 +1,64 @@ +from math import comb + +import numpy as np +import pandas as pd +import rasterio +import streamlit as st +from scipy import stats + + +@st.cache_data +def get_skew_raster(): + """Load the skew raster into memory.""" + return rasterio.open(__file__.replace("ffa.py", "skewmap_4326.tif")) + + +def l_moments(series): + """Calculate first three L moments.""" + ### From Stedinger 1993 around page 7 (section 18.6.1) ### + series = np.sort(series)[::-1] + n = len(series) + b_values = list() + # This method could be streamlined, but as-is, it's easily debugged + for r in range(4): + running_sum = list() + for j in range(n - r): + cur = (comb(n - (j + 1), r) * series[j]) / comb(n - 1, r) + running_sum.append(cur) + running_sum = sum(running_sum) + b = running_sum / n + b_values.append(b) + + l1 = b_values[0] + l2 = (2 * b_values[1]) - b_values[0] + l3 = (6 * b_values[2]) - (6 * b_values[1]) + (1 * b_values[0]) + return l1, l2, l3 + + +@st.cache_data +def log_pearson_iii( + peak_flows: pd.Series, + standard_return_periods: list = [1.1, 2, 5, 10, 25, 50, 100, 500], + method: str = "MLE", + coords: list = None, +): + log_flows = np.log10(peak_flows.values) + if method == "MM": + skew_log, mean_log, std_log = stats.pearson3.fit(log_flows, method="MM") + elif method == "MLE": + skew_log, mean_log, std_log = stats.pearson3.fit(log_flows, method="MLE") + elif method == "LMOM": + mean_log, std_log, skew_log = l_moments(log_flows) + + if coords: + src = get_skew_raster() + tmp_skew = src.sample(coords[0:2]) + if tmp_skew == 9999: # CA Equation + tmp_skew = (0 - 0.62) + 1.3 * (1 - np.exp(0 - ((coords[2]) / 6500) ^ 2)) + if not np.isnan(tmp_skew): + skew_log = tmp_skew + + return { + rp: int(10 ** stats.pearson3(skew=skew_log, loc=mean_log, scale=std_log).ppf(1 - 1 / rp)) + for rp in standard_return_periods + } diff --git a/hydroshift/streamlit_app.py b/hydroshift/streamlit_app.py index d6c7d36..8647b21 100644 --- a/hydroshift/streamlit_app.py +++ b/hydroshift/streamlit_app.py @@ -1,51 +1,7 @@ import streamlit as st -from data_retrieval import load_site_data from session import init_session_state -from hydroshift._pages import changepoint, summary -from hydroshift.consts import DEFAULT_GAGE - - -def homepage(): - """Landing page for app.""" - st.set_page_config(page_title="HydroShift", layout="wide") - - left_col, right_col, _ = st.columns([2, 1.5, 0.2], gap="large") - - with left_col: - st.title("HydroShift") - st.subheader("USGS Streamflow Change Detection Tool") - st.markdown( - """ - **HydroShift** is a tool for exploring streamflow trends in USGS gage data. This web app - provides interactive plots of annual peak discharge, seasonality of flood peaks, and daily and monthly discharge - trends. Beyond data summary, the application includes a statistical changepoint analysis that will detect when - significant changes in the distribution of flood peaks have occured. - """ - ) - - st.write("") # blank line for more space - gage_input = st.text_input("Enter a USGS Gage Number to begin:") - col1, col2 = st.columns([1, 8]) - with col1: - submit = st.button("Submit") - with col2: - demo = st.button("Use Demo Data") - - if submit and gage_input: - st.session_state["gage_id"] = gage_input - if demo: - st.session_state["gage_id"] = DEFAULT_GAGE - - if st.session_state["gage_id"] is not None: - try: - st.session_state["site_data"] = load_site_data(st.session_state["gage_id"]) - except ValueError: - st.error(f"Data not found for gage: {st.session_state['gage_id']}") - st.rerun() - with right_col: - st.title("") - st.image("hydroshift/images/logo_base.png") +from hydroshift._pages import changepoint, homepage, summary def navigator(): diff --git a/hydroshift/utils/data_models.py b/hydroshift/utils/data_models.py new file mode 100644 index 0000000..b72ebf2 --- /dev/null +++ b/hydroshift/utils/data_models.py @@ -0,0 +1,69 @@ +import pandas as pd +import streamlit as st + +from hydroshift.data_retrieval import ( + check_missing_dates, + get_ams, + get_daily_values, + get_flow_stats, + get_monthly_values, + load_site_data, +) + + +class Gage: + """A USGS Gage.""" + + def __init__(self, gage_id: str): + """Construct class.""" + self.gage_id = gage_id + self.site_data = load_site_data(gage_id) + + @property + @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + def latitude(self) -> float: + """Latitude of gage.""" + return self.site_data.get("dec_lat_va") + + @property + @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + def longitude(self) -> float: + """Longitude of gage.""" + return self.site_data.get("dec_long_va") + + @property + @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + def ams(self) -> pd.DataFrame: + """Load AMS for this site.""" + return get_ams(self.gage_id) + + @property + def missing_dates_ams(self) -> list: + """Get missing dates for AMS.""" + return check_missing_dates(self.ams, "water_year") + + @property + @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + def flow_stats(self) -> pd.DataFrame: + """Load flow statistics for this site.""" + return get_flow_stats(self.gage_id) + + @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + def get_daily_values(self, start_date: str, end_date: str) -> pd.DataFrame: + """Load daily mean discharge for this site.""" + return get_daily_values(self.gage_id, start_date, end_date) + + @property + def missing_dates_daily_values(self, start_date: str, end_date: str) -> list: + """Get missing dates for mean daily value series.""" + return check_missing_dates(self.get_daily_values(start_date, end_date), "daily") + + @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + def get_monthly_values(self, start_date: str, end_date: str) -> pd.DataFrame: + """Load monthly mean discharge for this site.""" + return get_monthly_values(self.gage_id, start_date, end_date) + + @property + def missing_dates_monthly_values(self, start_date: str, end_date: str) -> list: + """Get missing dates for mean monthly value series.""" + return check_missing_dates(self.get_monthly_values(start_date, end_date), "monthly") diff --git a/hydroshift/utils/jinja.py b/hydroshift/utils/jinja.py new file mode 100644 index 0000000..f087be9 --- /dev/null +++ b/hydroshift/utils/jinja.py @@ -0,0 +1,33 @@ +from pathlib import Path + +import streamlit as st +from jinja2 import Environment, FileSystemLoader, meta, select_autoescape + +from hydroshift import consts + +template_dir = Path(__file__).resolve().parent.parent / "templates" + +env = Environment(loader=FileSystemLoader(template_dir), autoescape=select_autoescape(["html", "xml"])) + + +def check_for_consts(template_name: str, context: dict) -> dict: + """Check if any of the template vars are in consts.py.""" + vars = meta.find_undeclared_variables(env.parse(env.loader.get_source(env, template_name)[0])) + for var in vars: + if hasattr(consts, var): + context[var] = getattr(consts, var) + return context + + +@st.cache_data +def render_template(template_name: str, context: dict = {}) -> str: + """Load a template from the environment and format it.""" + context = check_for_consts(template_name, context) + template = env.get_template(template_name) + return template.render(context) + + +def write_template(template_name: str, context: dict = {}): + """Format a template and then write it with st.""" + st.markdown(render_template(template_name, context), unsafe_allow_html=True) + st.empty() diff --git a/templates/app_description.md b/templates/app_description.md new file mode 100644 index 0000000..cf6f1e0 --- /dev/null +++ b/templates/app_description.md @@ -0,0 +1,4 @@ +**HydroShift** is a tool for exploring streamflow trends in USGS gage data. This web app +provides interactive plots of annual peak discharge, seasonality of flood peaks, and daily and monthly discharge +trends. Beyond data summary, the application includes a statistical changepoint analysis that will detect when +significant changes in the distribution of flood peaks have occured. diff --git a/templates/changepoint_description.md b/templates/changepoint_description.md new file mode 100644 index 0000000..1527e89 --- /dev/null +++ b/templates/changepoint_description.md @@ -0,0 +1,16 @@ +A changepoint analysis was performed on the series of annual flood peaks Using the change point model of Ross (2015). For each date in the timeseries, the distribution of flood peaks leading up to that date were compared with the distribution after that date using a variety of statistical tests + + - **Mood**: Measures changes in the variance of the peak series. + - **Mann-Whitney**: Measures changes in the mean of the peak series. + - **Lepage**: Combines both Mood and Mann-Whitney statistics into one. + - **Kolmogorov-Smirnov**: Measures changes in the overall distribution of flood peaks. + - **Cramer-von-Mises**: Measures changes in the overall distribution of flood peaks. + +These test statistics were utilized in two distinct ways in this analysis. A static analysis was performed by evaluating the test statistic at each date of the timeseries and using a two-sample test to determine the statistical significance of the distribution differences. The P-values from this analysis are shown in the second panel of Figure 1. +A streaming analysis was performed by treating the data as a stream of values and repeating the static analysis after each new value was added. If the test statistic exceeds a specified threshold at any point within the subseries, a changepoint is marked, and a new data series is initialized for all further test statistics. The resulting change points are shown as dashed red lines in the top panel of Figure 1. + + - The threshold for identifying changepoints in the streaming analysis is defined using an Average Run Length (ARL0) parameter. ARL0 reflects the frequency with which a false positive would be raised on a stationary timeseries (e.g., for an ARL0 of 1,000 a false changepoint would be identified on a stationary timeseries on average every 1,000 samples.). For this analysis, an ARL0 of {{ arl0 }} was used. + - A burn-in period of {{ burnin }} years was selected to ignore singificant change points in the first {{ burnin }} years of the record due to the influence of small sample sizes. + +If the flood peak series contained any gaps, the data around the gap was joined as if there was no gap between the data points. For large data gaps, this assumption could lead to inaccurate results. + diff --git a/templates/changepoint_references.md b/templates/changepoint_references.md new file mode 100644 index 0000000..078a43d --- /dev/null +++ b/templates/changepoint_references.md @@ -0,0 +1 @@ +Gordon J. Ross (2015)., "Parametric and Nonparametric Sequential Change Detection in R: The cpm Package.", Journal of Statistical Software, 66(3), 1-20., [https://www.jstatsoft.org/v66/i03/](https://www.jstatsoft.org/v66/i03/). diff --git a/templates/data_sources_side_bar.html b/templates/data_sources_side_bar.html new file mode 100644 index 0000000..dcec97b --- /dev/null +++ b/templates/data_sources_side_bar.html @@ -0,0 +1,10 @@ +
+ Data: USGS NWIS and + USGS PEAKFQ +
diff --git a/templates/footer.html b/templates/footer.html new file mode 100644 index 0000000..8bac78e --- /dev/null +++ b/templates/footer.html @@ -0,0 +1,33 @@ + + + diff --git a/templates/site_summary.md b/templates/site_summary.md new file mode 100644 index 0000000..1a23880 --- /dev/null +++ b/templates/site_summary.md @@ -0,0 +1,6 @@ +**Site Number:** {{ site_no }}
+**Station Name:** {{ station_nm }}
+**Latitude:** {{ dec_lat_va }}
+**Longitude:** {{ dec_long_va }}
+**Drainage Area (sq.mi.):** {{ drain_area_va }}
+**HUC Code:** {{ huc_cd }}
From 1131606d3eb981dbb772b52831d40aa430f162d0 Mon Sep 17 00:00:00 2001 From: sclaw Date: Thu, 24 Apr 2025 08:13:13 -0400 Subject: [PATCH 04/24] incremental refactor --- hydroshift/_pages/changepoint.py | 11 +- hydroshift/_pages/summary.py | 209 ++++++++++-------- hydroshift/consts.py | 2 + hydroshift/data/skewmap_4326.tif | Bin 0 -> 15046405 bytes hydroshift/stats/__init__.py | 1 - .../templates}/app_description.md | 0 .../templates}/changepoint_description.md | 0 .../templates}/changepoint_references.md | 0 .../templates}/data_sources_side_bar.html | 0 .../templates}/footer.html | 0 .../templates}/site_summary.md | 0 hydroshift/utils/data_models.py | 95 +++++++- hydroshift/{ => utils}/data_retrieval.py | 13 +- hydroshift/{stats => utils}/ffa.py | 0 hydroshift/{ => utils}/plots.py | 35 +-- hydroshift/{stats => utils}/tests.py | 0 tests/stat_tests/changepoint_test.py | 2 +- 17 files changed, 231 insertions(+), 137 deletions(-) create mode 100644 hydroshift/data/skewmap_4326.tif delete mode 100644 hydroshift/stats/__init__.py rename {templates => hydroshift/templates}/app_description.md (100%) rename {templates => hydroshift/templates}/changepoint_description.md (100%) rename {templates => hydroshift/templates}/changepoint_references.md (100%) rename {templates => hydroshift/templates}/data_sources_side_bar.html (100%) rename {templates => hydroshift/templates}/footer.html (100%) rename {templates => hydroshift/templates}/site_summary.md (100%) rename hydroshift/{ => utils}/data_retrieval.py (92%) rename hydroshift/{stats => utils}/ffa.py (100%) rename hydroshift/{ => utils}/plots.py (93%) rename hydroshift/{stats => utils}/tests.py (100%) diff --git a/hydroshift/_pages/changepoint.py b/hydroshift/_pages/changepoint.py index 152854c..9edea08 100644 --- a/hydroshift/_pages/changepoint.py +++ b/hydroshift/_pages/changepoint.py @@ -8,13 +8,9 @@ import numpy as np import pandas as pd import streamlit as st -from data_retrieval import ( - get_ams, -) from docx import Document from docx.shared import Inches from plotly import graph_objects -from plots import combo_cpm, plot_lp3 from hydroshift.consts import ( CP_F1_CAPTION, @@ -24,10 +20,13 @@ METRICS, VALID_ARL0S, ) -from hydroshift.data_retrieval import log_pearson_iii -from hydroshift.stats.tests import cp_pvalue_batch, cpm_process_stream from hydroshift.text.changepoint import references, test_description +from hydroshift.utils.data_retrieval import ( + get_ams, +) from hydroshift.utils.jinja import write_template +from hydroshift.utils.plots import combo_cpm, plot_lp3 +from hydroshift.utils.tests import cp_pvalue_batch, cpm_process_stream @dataclass diff --git a/hydroshift/_pages/summary.py b/hydroshift/_pages/summary.py index 8df1182..6f1d6d3 100644 --- a/hydroshift/_pages/summary.py +++ b/hydroshift/_pages/summary.py @@ -1,12 +1,10 @@ import folium import streamlit as st -from data_retrieval import ( - get_ams, - get_daily_values, - get_flow_stats, - get_monthly_values, -) -from plots import ( +from streamlit_folium import st_folium + +from hydroshift.utils.data_models import Gage, LP3Analysis +from hydroshift.utils.jinja import write_template +from hydroshift.utils.plots import ( plot_ams, plot_ams_seasonal, plot_daily_mean, @@ -14,10 +12,100 @@ plot_lp3, plot_monthly_mean, ) -from streamlit_folium import st_folium -from hydroshift.utils.data_models import Gage -from hydroshift.utils.jinja import write_template + +def section_ams(gage: Gage): + """Display the AMS section.""" + if gage.ams is not None: + if gage.missing_dates_ams is not None: + st.warning(f"Missing {len(gage.missing_dates_ams)} AMS records") + st.plotly_chart(plot_ams(gage.ams, gage.gage_id)) + show_data = st.checkbox("Show AMS Data Table") + if show_data: + st.dataframe(gage.ams) + + +def section_flow_stats(gage: Gage): + """Display the flow statistics section.""" + if gage.flow_stats is not None: + st.plotly_chart(plot_flow_stats(gage.flow_stats, gage.gage_id)) + show_data = st.checkbox("Show Daily Stats Data Table") + if show_data: + st.dataframe(gage.flow_stats) + + +def section_lp3(gage: Gage): + """Display the FFA section.""" + if gage.ams is not None: + # Options + opt_col_1, opt_col_2 = st.columns(2) + with opt_col_1: + est_method = st.selectbox( + "Estimation Method", ["L-moments", "Method of moments", "Maximum Likelihood"], index=2 + ) + est_method = {"L-moments": "LMOM", "Method of moments": "MOM", "Maximum Likelihood": "MLE"}[est_method] + with opt_col_2: + st_skew = st.toggle("Use regional skew", value=False, disabled=not gage.has_regional_skew) + if st_skew: + skew = gage.regional_skew + else: + skew = None + + # Analysis and display + lp3 = LP3Analysis(gage.gage_id, gage.ams_vals, skew, est_method, "") + if gage.missing_dates_ams is not None: + st.warning(f"Missing {len(gage.missing_dates_ams)} LP3 records") + st.plotly_chart(plot_lp3(lp3), use_container_width=True) + show_data = st.checkbox("Show LP3 Data Table") + if show_data: + st.dataframe(lp3.quantile_df) + + +def section_ams_seasonal(gage: Gage): + """Display the ams with seasonal attributes section.""" + if gage.ams is not None: + if gage.missing_dates_ams: + st.warning(f"Missing {len(gage.missing_dates_ams)} AMS seasonal records") + st.plotly_chart(plot_ams_seasonal(gage.ams, gage.gage_id), use_container_width=True) + show_data = st.checkbox("Show Ranked Seasonal Data Table") + if show_data: + st.dataframe(gage.ams) + + +def section_daily_mean(gage: Gage): + """Display the daily mean discharge section.""" + plot_col, input_col = st.columns([8, 2]) + + with input_col: + st.write("") # blank line for more space + st.write("Daily Mean Input Dates") + start_date = st.text_input("Start Date (YYYY-MM-DD)", "2024-01-01") + end_date = st.text_input("End Date (YYYY-MM-DD)", "2024-12-31") + + data = gage.get_daily_values(start_date, end_date) + missing_dates = gage.missing_dates_daily_values(start_date, end_date) + with plot_col: + if data is not None: + if missing_dates: + st.warning(f"Missing {len(missing_dates)} daily mean records") + st.plotly_chart(plot_daily_mean(data, gage.gage_id), use_container_width=True) + show_data = st.checkbox("Show Daily Mean Data Table") + if show_data: + st.dataframe(data) + + +def section_monthly_mean(gage: Gage): + """Display the monthly mean discharge section.""" + data = gage.get_monthly_values() + missing_dates = gage.missing_dates_monthly_values() + if data is not None and "mean_va" in data.columns: + if missing_dates: + st.warning(f"Missing {len(missing_dates)} monthly records") + st.plotly_chart(plot_monthly_mean(data, st.session_state["gage_id"]), use_container_width=True) + + show_data = st.checkbox("Show Monthly Mean Data Table") + if show_data: + st.dataframe(data) def summary(): @@ -43,108 +131,39 @@ def summary(): write_template("data_sources_side_bar.html") if st.session_state["gage_id"]: - with st.spinner("Loading gage data..."): # This is mainly here to clear previous pages while data loads. - try: - if st.session_state["gage_id"] == "testing": - site_data = { - "site_no": "-99999", - "station_nm": "Wet River", - "dec_lat_va": 45, - "dec_long_va": -103, - "drain_area_va": 0, - "huc_cd": 0, - "alt_datum_cd": "NAVD88", - } - else: - site_data = st.session_state["site_data"] - lat, lon = site_data["dec_lat_va"], site_data["dec_long_va"] - except ValueError as e: - lat, lon = None, None - st.error(f"{e}") + with st.spinner("Loading gage data..."): # This is here to clear previous pages while data loads. + pass col2, col3 = st.columns([6, 2], gap="large") - if lat and lon: - with col3: + if gage.latitude and gage.longitude: + with col3: # Site map st.subheader("Gage Location") # Create Folium Map - mini_map = folium.Map(location=[lat, lon], zoom_start=7, width=200, height=200) + mini_map = folium.Map(location=[gage.latitude, gage.longitude], zoom_start=7, width=200, height=200) folium.Marker( - [lat, lon], popup=f"Gage {st.session_state['gage_id']}", icon=folium.Icon(color="green") + [gage.latitude, gage.longitude], + popup=f"Gage {st.session_state['gage_id']}", + icon=folium.Icon(color="green"), ).add_to(mini_map) st_folium(mini_map, width=250, height=250) # Display site metadata st.subheader("Site Information") - write_template("site_summary.md", site_data) + write_template("site_summary.md", gage.site_data) with col2: # Center column for plots + gage.raise_warnings() if show_ams: - ams = get_ams(st.session_state["gage_id"]) - data, missing_years = ams["peaks"], ams["missing_years"] - if data is not None and "peak_va" in data.columns: - if missing_years: - st.warning(f"Missing {len(missing_years)} AMS records") - st.plotly_chart(plot_ams(data, st.session_state["gage_id"]), use_container_width=True) - show_data = st.checkbox("Show AMS Data Table") - if show_data: - st.dataframe(data) - + section_ams(gage) if show_daily_stats: - data = get_flow_stats(st.session_state["gage_id"]) - if data is not None and "mean_va" in data.columns: - st.plotly_chart(plot_flow_stats(data, st.session_state["gage_id"]), use_container_width=True) - show_data = st.checkbox("Show Daily Stats Data Table") - if show_data: - st.dataframe(data) - + section_flow_stats(gage) if show_lp3: - ams = get_ams(st.session_state["gage_id"]) - if ams["peaks"] is not None: - if ams["missing_years"]: - st.warning(f"Missing {len(ams["missing_years"])} LP3 records") - st.plotly_chart(plot_lp3(ams, st.session_state["gage_id"]), use_container_width=True) - show_data = st.checkbox("Show LP3 Data Table") - if show_data: - st.dataframe(ams["lp3"]) + section_lp3(gage) if show_ams_seasonal: - ams = get_ams(st.session_state["gage_id"]) - data, missing_years = ams["peaks"], ams["missing_years"] - if data is not None and "peak_va" in data.columns: - if missing_years: - st.warning(f"Missing {len(missing_years)} AMS seasonal records") - st.plotly_chart(plot_ams_seasonal(data, st.session_state["gage_id"]), use_container_width=True) - show_data = st.checkbox("Show Ranked Seasonal Data Table") - if show_data: - st.dataframe(data) - + section_ams_seasonal(gage) if show_daily_mean: - plot_col, input_col = st.columns([8, 2]) - - with input_col: - st.write("") # blank line for more space - st.write("Daily Mean Input Dates") - start_date = st.text_input("Start Date (YYYY-MM-DD)", "2024-01-01") - end_date = st.text_input("End Date (YYYY-MM-DD)", "2024-12-31") - - data, missing_dates = get_daily_values(st.session_state["gage_id"], start_date, end_date) - with plot_col: - if data is not None: - if missing_dates: - st.warning(f"Missing {len(missing_dates)} daily mean records") - st.plotly_chart(plot_daily_mean(data, st.session_state["gage_id"]), use_container_width=True) - show_data = st.checkbox("Show Daily Mean Data Table") - if show_data: - st.dataframe(data) - + section_daily_mean(gage) if show_monthly_mean: - data, missing_dates = get_monthly_values(st.session_state["gage_id"]) - if data is not None and "mean_va" in data.columns: - if missing_dates: - st.warning(f"Missing {len(missing_dates)} monthly records") - st.plotly_chart(plot_monthly_mean(data, st.session_state["gage_id"]), use_container_width=True) - - show_data = st.checkbox("Show Monthly Mean Data Table") - if show_data: - st.dataframe(data) + section_monthly_mean(gage) diff --git a/hydroshift/consts.py b/hydroshift/consts.py index 49d5071..32a092e 100644 --- a/hydroshift/consts.py +++ b/hydroshift/consts.py @@ -7,6 +7,8 @@ R_SERVER_PORT = 9999 R_SERVER_URL = f"http://127.0.0.1:{R_SERVER_PORT}" +### FFA ### + ### Changepoint Analysis ### VALID_ARL0S = [ 370, diff --git a/hydroshift/data/skewmap_4326.tif b/hydroshift/data/skewmap_4326.tif new file mode 100644 index 0000000000000000000000000000000000000000..53b0fb7abf5164d38d54ec311ec8429d1fe1591a GIT binary patch literal 15046405 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%0Au%?k9YQ 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

v+R40 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 zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F z@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU| z0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BP zJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj# zzyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9F@W2BPJn+B+ z4?OU|0}nj#zyl9F@W2BPJn+B+4?OU|0}nj#zyl9Fpj|o;000005ae$?$i float: """Latitude of gage.""" return self.site_data.get("dec_lat_va") @property - @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) def longitude(self) -> float: """Longitude of gage.""" return self.site_data.get("dec_long_va") @property - @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) def ams(self) -> pd.DataFrame: """Load AMS for this site.""" return get_ams(self.gage_id) + @property + def ams_vals(self) -> np.ndarray: + """Convenient ams column selection.""" + return self.ams["peak_va"].values + @property def missing_dates_ams(self) -> list: """Get missing dates for AMS.""" return check_missing_dates(self.ams, "water_year") @property - @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) def flow_stats(self) -> pd.DataFrame: """Load flow statistics for this site.""" return get_flow_stats(self.gage_id) - @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) def get_daily_values(self, start_date: str, end_date: str) -> pd.DataFrame: """Load daily mean discharge for this site.""" return get_daily_values(self.gage_id, start_date, end_date) @@ -58,7 +69,7 @@ def missing_dates_daily_values(self, start_date: str, end_date: str) -> list: """Get missing dates for mean daily value series.""" return check_missing_dates(self.get_daily_values(start_date, end_date), "daily") - @st.cache_data(hash_funcs={"__main__.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) def get_monthly_values(self, start_date: str, end_date: str) -> pd.DataFrame: """Load monthly mean discharge for this site.""" return get_monthly_values(self.gage_id, start_date, end_date) @@ -67,3 +78,73 @@ def get_monthly_values(self, start_date: str, end_date: str) -> pd.DataFrame: def missing_dates_monthly_values(self, start_date: str, end_date: str) -> list: """Get missing dates for mean monthly value series.""" return check_missing_dates(self.get_monthly_values(start_date, end_date), "monthly") + + def raise_warnings(self): + """Create any high level data warnings.""" + pass + + @property + def has_regional_skew(self): + """Check if gage has regional skew available.""" + return False + + +@dataclass +class LP3Analysis: + """A log-pearson type 3 analysis.""" + + gage_id: str + peaks: list + regional_skew: float = None + est_method: str = "MLE" + label: str = "" + return_periods: List[str] = field(default_factory=lambda: [1.1, 2, 5, 10, 25, 50, 100, 500]) + + def __post_init__(self): + """Customize init.""" + self.peaks = np.sort(self.peaks) + + @property + def log_peaks(self) -> np.ndarray: + """Log 10 of peaks.""" + return np.log10(self.peaks) + + @property + def parameters(self) -> tuple[float]: + """Sample parameters for LP3 distribution.""" + if self.est_method == "MOM": + skew_log, mean_log, std_log = pearson3.fit(self.log_peaks, method="MM") + elif self.est_method == "MLE": + skew_log, mean_log, std_log = pearson3.fit(self.log_peaks, method="MLE") + elif self.est_method == "LMOM": + mean_log, std_log, l3 = l_moments(self.log_peaks) + skew_log = l3 / (std_log * 0.7797) # pseudo-stdev + if self.regional_skew is not None: + skew_log = self.regional_skew + return mean_log, std_log, skew_log + + @property + def distribution(self) -> rv_continuous: + """The fitted LP3 distribution.""" + params = self.parameters + return pearson3(params[2], params[0], params[1]) + + @property + def plotting_positions(self) -> tuple[np.ndarray]: + """Empirical flood frequency curve.""" + aep = np.arange(1, len(self.peaks) + 1)[::-1] / (len(self.peaks) + 1) + return (aep, self.peaks) + + @property + def ffa_quantiles(self) -> tuple[np.ndarray]: + """Calculate some recurrence intervals from fitted distribution.""" + ris = np.array(self.return_periods) + aeps = 1 / ris + qs = np.power(10, self.distribution.ppf(1 - aeps)).astype(int) + return (aeps, qs) + + @property + def quantile_df(self): + """Put quantiles into a dataframe.""" + _, qs = self.ffa_quantiles + return pd.DataFrame({"Recurrence Interval (years)": self.return_periods, "Discharge (cfs)": qs}) diff --git a/hydroshift/data_retrieval.py b/hydroshift/utils/data_retrieval.py similarity index 92% rename from hydroshift/data_retrieval.py rename to hydroshift/utils/data_retrieval.py index 1c91a04..bc811f4 100644 --- a/hydroshift/data_retrieval.py +++ b/hydroshift/utils/data_retrieval.py @@ -6,8 +6,6 @@ from dataretrieval import NoSitesError, nwis from scipy.stats import genpareto -from hydroshift.stats.ffa import log_pearson_iii - @st.cache_data def get_ams(gage_id): @@ -25,10 +23,8 @@ def get_ams(gage_id): {1: "Winter", 2: "Spring", 3: "Summer", 4: "Fall"} ) # TODO: should add labels like Winter(JFM), Spring(AMJ), etc - missing_years = check_missing_dates(df, "water_year") - df = df.dropna(subset="peak_va") - return {"peaks": df, "lp3": log_pearson_iii(df["peak_va"]), "missing_years": missing_years} + return df @st.cache_data @@ -72,9 +68,7 @@ def get_daily_values(gage_id, start_date, end_date): logging.warning(f"Daily Values could not be found for gage_id: {gage_id}") return None - missing_dates = check_missing_dates(dv, "daily") - - return dv, missing_dates + return dv @st.cache_data @@ -91,9 +85,8 @@ def get_monthly_values(gage_id): mv["date"] = pd.to_datetime(mv[["year", "month"]].assign(day=1)) mv = mv.sort_values("date") - missing_dates = check_missing_dates(mv, "monthly") - return mv, missing_dates + return mv def check_missing_dates(df, freq): diff --git a/hydroshift/stats/ffa.py b/hydroshift/utils/ffa.py similarity index 100% rename from hydroshift/stats/ffa.py rename to hydroshift/utils/ffa.py diff --git a/hydroshift/plots.py b/hydroshift/utils/plots.py similarity index 93% rename from hydroshift/plots.py rename to hydroshift/utils/plots.py index dc5ca7f..b33d12b 100644 --- a/hydroshift/plots.py +++ b/hydroshift/utils/plots.py @@ -1,4 +1,3 @@ -import numpy as np import pandas as pd import plotly.express as px import plotly.graph_objects as go @@ -6,6 +5,8 @@ from plotly.subplots import make_subplots from scipy.stats import norm +from hydroshift.utils.data_models import LP3Analysis + def plot_ams(ams_df, gage_id, cps: dict = {}): """Plots AMS (Annual Peak Flow) using Plotly with only markers (no line).""" @@ -148,20 +149,17 @@ def plot_flow_stats(stats_df, gage_id): return fig -def plot_lp3(data: dict | list, gage_id: str, multi_series: bool = False): +def plot_lp3(data: LP3Analysis | list[LP3Analysis]): """Creates a Plotly chart for Log-Pearson Type III return period vs. peak flow.""" # Convert dict to lists for plotting - if not multi_series: - data = {"": data} + if isinstance(data, LP3Analysis): + data = [data] fig = go.Figure() for i in data: - name = i + " - Peaks" - peaks = data[i]["peaks"]["peak_va"].values - peaks.sort() - aep = np.arange(1, len(peaks) + 1)[::-1] / (len(peaks) + 1) - ri = 1 / aep + name = i.label + " - Peaks" + aep, peaks = i.plotting_positions z = norm.ppf(1 - aep) fig.add_trace( go.Scatter( @@ -173,16 +171,13 @@ def plot_lp3(data: dict | list, gage_id: str, multi_series: bool = False): ) ) - name = i + " - Log-Pearson III Fit" - lp3 = data[i]["lp3"] - - return_periods = [int(i) if i.is_integer() else round(i, 1) for i in lp3.keys()] - z2 = [norm.ppf(1 - (1 / i)) for i in return_periods] - peak_flows = list(lp3.values()) + name = i.label + " - Log-Pearson III Fit" + aep2, peaks2 = i.ffa_quantiles + z2 = norm.ppf(1 - aep2) fig.add_trace( go.Scatter( x=z2, - y=peak_flows, + y=peaks2, mode="markers+lines", marker=dict(size=8), line=dict(dash="solid"), @@ -190,8 +185,14 @@ def plot_lp3(data: dict | list, gage_id: str, multi_series: bool = False): ) ) + # Formatting + return_periods = [int(i) if i.is_integer() else round(i, 1) for i in i.return_periods] + if i.regional_skew is not None: + skew_txt = "" + else: + skew_txt = " (No Regional Skew)" fig.update_layout( - title=f"{gage_id} | Log-Pearson Type III Estimates (No Regional Skew)", + title=f"{i.gage_id} | Log-Pearson Type III Estimates{skew_txt}", xaxis=dict( title="Return Period (years)", tickvals=z2, diff --git a/hydroshift/stats/tests.py b/hydroshift/utils/tests.py similarity index 100% rename from hydroshift/stats/tests.py rename to hydroshift/utils/tests.py diff --git a/tests/stat_tests/changepoint_test.py b/tests/stat_tests/changepoint_test.py index 3b604ff..6dd5305 100644 --- a/tests/stat_tests/changepoint_test.py +++ b/tests/stat_tests/changepoint_test.py @@ -5,7 +5,7 @@ from scipy.ndimage import gaussian_filter1d from scipy.stats import genpareto -from hydroshift.stats.tests import ( +from hydroshift.utils.tests import ( cpm_detect_change_point_batch, cpm_process_stream, get_batch_threshold, From 1a7b4a152f0c5e941d56a1c62763ba1d45fad522 Mon Sep 17 00:00:00 2001 From: sclaw Date: Thu, 24 Apr 2025 16:47:44 -0400 Subject: [PATCH 05/24] refactor nearly complete --- hydroshift/_pages/changepoint.py | 208 ++++++------------ hydroshift/_pages/summary.py | 3 +- .../templates/changepoint_description.md | 2 +- hydroshift/templates/changepoint_ffa.md | 2 + hydroshift/templates/changepoint_summary_1.md | 15 ++ hydroshift/templates/changepoint_summary_2.md | 16 ++ hydroshift/text/__init__.py | 1 - hydroshift/text/changepoint.py | 23 -- hydroshift/utils/{tests.py => changepoint.py} | 0 hydroshift/utils/common.py | 18 ++ hydroshift/utils/data_models.py | 150 ------------- hydroshift/utils/data_retrieval.py | 72 ++++++ hydroshift/utils/ffa.py | 64 ++++++ hydroshift/utils/plots.py | 5 +- tests/stat_tests/changepoint_test.py | 2 +- 15 files changed, 264 insertions(+), 317 deletions(-) create mode 100644 hydroshift/templates/changepoint_ffa.md create mode 100644 hydroshift/templates/changepoint_summary_1.md create mode 100644 hydroshift/templates/changepoint_summary_2.md delete mode 100644 hydroshift/text/__init__.py delete mode 100644 hydroshift/text/changepoint.py rename hydroshift/utils/{tests.py => changepoint.py} (100%) create mode 100644 hydroshift/utils/common.py delete mode 100644 hydroshift/utils/data_models.py diff --git a/hydroshift/_pages/changepoint.py b/hydroshift/_pages/changepoint.py index 9edea08..bc54cd4 100644 --- a/hydroshift/_pages/changepoint.py +++ b/hydroshift/_pages/changepoint.py @@ -5,12 +5,11 @@ from dataclasses import dataclass, field from io import BytesIO -import numpy as np import pandas as pd import streamlit as st from docx import Document from docx.shared import Inches -from plotly import graph_objects +from plotly.graph_objects import Figure from hydroshift.consts import ( CP_F1_CAPTION, @@ -20,31 +19,23 @@ METRICS, VALID_ARL0S, ) -from hydroshift.text.changepoint import references, test_description -from hydroshift.utils.data_retrieval import ( - get_ams, -) -from hydroshift.utils.jinja import write_template +from hydroshift.utils.changepoint import cp_pvalue_batch, cpm_process_stream +from hydroshift.utils.common import num_2_word +from hydroshift.utils.data_retrieval import Gage +from hydroshift.utils.jinja import render_template, write_template from hydroshift.utils.plots import combo_cpm, plot_lp3 -from hydroshift.utils.tests import cp_pvalue_batch, cpm_process_stream @dataclass class ChangePointAnalysis: """OOP representation of the changepoint analysis.""" - data: dict = field(default_factory=pd.DataFrame) - missing_years: int = 0 + gage: Gage = field(default_factory=Gage) pval_df: dict = None cp_dict: dict = field(default_factory=dict) ffa_plot = None ffa_df: dict = field(default_factory=pd.DataFrame) - @property - def ts(self) -> np.ndarray: - """Timeseries from data.""" - return self.data["peak_va"].values - @property def nonstationary(self) -> bool: """Whether or not a nonstationarity was identified.""" @@ -92,7 +83,7 @@ def get_change_windows(self, max_dist: float = 10) -> tuple: return groups, test_counts - def get_max_pvalue(self): + def get_max_pvalue(self) -> tuple[float, int]: """Get the minimum p value where all tests agree and count how often that occurred.""" all_tests = self.pval_df.fillna(1).max(axis=1).to_frame(name="pval") all_tests["run"] = ((all_tests != all_tests.shift(1)) * 1).cumsum() @@ -103,32 +94,12 @@ def get_max_pvalue(self): break return min_p, count - def num_2_word(self, number: int) -> str: - """Convert numbers less than 10 to words.""" - if number > 9: - return number - else: - d = { - 0: "no", - 1: "one", - 2: "two", - 3: "three", - 4: "four", - 5: "five", - 6: "six", - 7: "seven", - 8: "eight", - 9: "nine", - } - return d[number] - @property - def summary_plot(self) -> graph_objects: + def summary_plot(self) -> Figure: """Create plotly plot to summarize analysis.""" - return combo_cpm(self.data, self.pval_df, self.cp_dict) + return combo_cpm(self.gage.ams, self.pval_df, self.cp_dict) @property - @st.cache_resource def summary_png(self) -> BytesIO: """Export summary plot to png in memory.""" bio = BytesIO() @@ -143,7 +114,6 @@ def ffa_png(self): return bio @property - @st.cache_resource def cp_df(self): """Get a dataframe representing changepoints identified in the streaming analysis.""" cpa_df = pd.DataFrame.from_dict(self.cp_dict, orient="index", columns=["Tests Identifying Change"]) @@ -158,95 +128,61 @@ def title(self) -> str: @property def summary_text(self) -> str: """A text summary of the changepoint analysis.""" - if self.nonstationary: - end_text = """ - some form of nonstationarity (e.g., land use change, climate change, flow regulation, etc) may be influencing flow patterns at this site. - """ - else: - end_text = """an assumption of nonstationary conditions is likely reasonable.""" - cp_count = self.num_2_word(len(self.cp_dict)) - if len(self.cp_dict) == 1: - plural_text = "point was" - else: - plural_text = "points were" - return ( - """ - There is **{}** evidence that the annual maximum series data at USGS gage {} are nonstationary in time. Four change - point detection tests were completed to assess changes in the mean, variance, and overall distribution of flood - peaks across the period of record. Significant change points were identified using a Type I error rate of 1 in - {} and ignoring significant changes in the first {} years of data. {} statistically significant change - {} identified, indicating that {} - """ - ).format( - self.evidence_level, - st.session_state.gage_id, - st.session_state.arlo_slider, - st.session_state.burn_in, - cp_count, - plural_text, - end_text, - ) + payload = { + "evidence_level": self.evidence_level, + "gage_id": self.gage.gage_id, + "arl0": st.session_state.arlo_slider, + "burn_in": st.session_state.burn_in, + "cp_count": num_2_word(len(self.cp_dict)), + "plural": len(self.cp_dict) != 1, + "nonstationary": self.nonstationary, + } + return render_template("changepoint_summary_1.md", payload) + + @property + def test_description(self): + """Analysis methodology.""" + payload = {"alr0": st.session_state.arlo_slider, "burn_in": st.session_state.burn_in} + return render_template("changepoint_description.md", payload) @property def results_text(self) -> str: """A detailed description of the results.""" - # Static analysis + # Gather stats min_p, p_count = self.get_max_pvalue() if min_p == 0.001: evidence = "strong" elif min_p == 0.005: evidence = "moderate" + elif self.pval_df.isna().all().all(): + evidence = "no" elif min_p < 1: evidence = "minor" - if p_count > 1: - plural = "s" - else: - plural = "" - if min_p < 1: - sentence = "A minimum p-value of {} was obtained at {} contiguous time period{}.".format( - min_p, self.num_2_word(p_count), plural - ) - else: - sentence = "There were no time-periods where a p-value less than 0.05 was observed in all tests." - if self.pval_df.isna().all().all(): - evidence = "no" - else: - evidence = "minimal" - p1 = """ - The static changepoint test showed {} evidence of a changepoint in the timeseries. {} The p-value reflects the probability that the distribution of - flood peaks before that date has the **same** distribution as the flood peaks after the date. - """.format( - evidence, sentence - ) - - # Streaming analysis - if len(self.cp_dict) == 1: - p2 = """ - The streaming analysis identified one statistically significant changepoint. This changepoint was identified - by {} distinct tests: {}.""" - else: - groups, test_counts = self.get_change_windows() - if len(groups) > 0: - plural = "s" - else: - plural = "" - p2 = """ - The streaming analysis identified {} statistically significant changepoints. These changepoints broadly fell - into {} window{} where tests identified changepoints not more than 10 years apart. For a full summary of which - tests identified changes at which dates, see table 2. - """.format( - self.num_2_word(len(self.cp_dict)), self.num_2_word(len(groups)), plural - ) - return "\n\n".join([p1, p2]) + groups, _ = self.get_change_windows() + + # format + payload = { + "evidence": evidence, + "min_p": min_p, + "p_count": num_2_word(p_count), + "plural": p_count > 1, + "len_cp": len(self.cp_dict), + "len_cp_str": num_2_word(len(self.cp_dict)), + "test_count": num_2_word(len(self.cp_dict[next(iter(self.cp_dict))].split(","))), + "grp_count": num_2_word(len(groups)), + "plural_2": len(groups) > 0, + } + return render_template("changepoint_summary_2.md", payload) @property def ffa_text(self) -> str: - return """ - Based on the changepoint analysis results, a modified flood frequency analysis was conducted - using truncated periods of record. The truncated periods correspond with times when the - hydrologic regime appears to be stationary across time. Results from this analysis are shown - in Figure 2 and Table 2. - """ + """Methodology for the modified FFA.""" + return render_template("changepoint_ffa.md") + + @property + def references(self) -> str: + """Citations.""" + return render_template("changepoint_references.md") @property def word_data(self) -> BytesIO: @@ -257,10 +193,7 @@ def word_data(self) -> BytesIO: self.add_markdown_to_doc(document, self.summary_text) document.add_picture(self.summary_png, width=Inches(6.5)) document.add_heading("Changepoint detection method", level=2) - self.add_markdown_to_doc( - document, - test_description.format(st.session_state.arlo_slider, st.session_state.burn_in, st.session_state.burn_in), - ) + self.add_markdown_to_doc(document, self.test_description) if len(self.cp_dict) > 0: document.add_heading("Changepoint detection results", level=2) self.add_markdown_to_doc(document, self.results_text) @@ -276,7 +209,7 @@ def word_data(self) -> BytesIO: self.add_table_from_df(self.ffa_df, document, index_name="Regime Period") document.add_heading("References", level=2) - self.add_markdown_to_doc(document, references) + self.add_markdown_to_doc(document, self.references) out = BytesIO() document.save(out) @@ -308,18 +241,15 @@ def add_markdown_to_doc(self, document: Document, text: str): p.add_run(r).bold = bold bold = not bold - def get_data(self, gage_id: int): + def validate_data(self): """Cache results of get_ams.""" - data = get_ams(gage_id) + data = self.gage.ams # Validate if data is None: st.session_state.valid_data = False st.session_state.data_comment = "Unable to retrieve data." - elif data["peaks"] is None: - st.session_state.valid_data = False - st.session_state.data_comment = "Unable to retrieve data." - elif len(data["peaks"]) < st.session_state.burn_in: + elif len(data) < st.session_state.burn_in: st.session_state.valid_data = False st.session_state.data_comment = ( "Not enough peaks available for analysis. {} peaks found, but burn-in length was {}".format( @@ -327,7 +257,6 @@ def get_data(self, gage_id: int): ) ) else: - self.data, self.missing_years = data["peaks"], data["missing_years"] st.session_state.valid_data = True @@ -345,8 +274,8 @@ def define_variables(): # Instantiate analysis class and get data if "changepoint" not in st.session_state: - st.session_state.changepoint = ChangePointAnalysis(st.session_state.gage_id) - st.session_state.changepoint.get_data(st.session_state.gage_id) + st.session_state.changepoint = ChangePointAnalysis(st.session_state.gage) + st.session_state.changepoint.validate_data() def make_sidebar(): @@ -354,6 +283,7 @@ def make_sidebar(): with st.sidebar: st.title("Settings") st.session_state["gage_id"] = st.text_input("Enter USGS Gage Number:", st.session_state["gage_id"]) + st.session_state.gage = Gage(st.session_state["gage_id"]) st.select_slider( "False Positive Rate (1 in #)", options=VALID_ARL0S, @@ -391,8 +321,8 @@ def make_sidebar(): def run_analysis(): """Run the change point model analysis.""" cpa = st.session_state.changepoint - cpa.pval_df = get_pvalues(cpa.data) - cpa.cp_dict = get_changepoints(cpa.data, st.session_state.arlo_slider, st.session_state.burn_in) + cpa.pval_df = get_pvalues(cpa.gage.ams) + cpa.cp_dict = get_changepoints(cpa.gage.ams, st.session_state.arlo_slider, st.session_state.burn_in) @st.cache_data @@ -444,7 +374,7 @@ def make_body(): """Assemble main app body.""" left_col, right_col = st.columns([2, 1]) # Formatting with left_col: - cpa = st.session_state.changepoint + cpa: ChangePointAnalysis = st.session_state.changepoint st.title(cpa.title) warnings() @@ -453,9 +383,7 @@ def make_body(): st.plotly_chart(cpa.summary_plot, use_container_width=True) st.markdown(CP_F1_CAPTION) st.header("Changepoint detection method") - write_template( - "changepoint_description.md", {"arl0": st.session_state.arlo_slider, "burnin": st.session_state.burn_in} - ) + st.markdown(cpa.test_description) if len(cpa.cp_dict) > 0: st.header("Changepoint detection results") @@ -481,17 +409,21 @@ def make_body(): ) st.header("References") - st.markdown(references) + st.markdown(cpa.references) st.download_button("Download analysis", cpa.word_data, f"changepoint_analysis_{st.session_state.gage_id}.docx") def warnings(): """Print warnings on data validity etc.""" - if st.session_state.changepoint.data is not None and "peak_va" in st.session_state.changepoint.data.columns: - if st.session_state.changepoint.missing_years: + if st.session_state.changepoint.gage.ams is not None and "peak_va" in st.session_state.changepoint.gage.ams.columns: + if st.session_state.changepoint.gage.missing_dates_ams: st.warning( - f"Missing {len(st.session_state.changepoint.missing_years)} dates between {st.session_state.changepoint.data.index.min()} and {st.session_state.changepoint.data.index.max()}" + "Missing {} dates between {} and {}".format( + len(st.session_state.changepoint.gage.missing_dates_ams), + st.session_state.changepoint.gage.ams.index.min(), + st.session_state.changepoint.gage.ams.index.max(), + ) ) diff --git a/hydroshift/_pages/summary.py b/hydroshift/_pages/summary.py index 6f1d6d3..903ff84 100644 --- a/hydroshift/_pages/summary.py +++ b/hydroshift/_pages/summary.py @@ -2,7 +2,8 @@ import streamlit as st from streamlit_folium import st_folium -from hydroshift.utils.data_models import Gage, LP3Analysis +from hydroshift.utils.data_retrieval import Gage +from hydroshift.utils.ffa import LP3Analysis from hydroshift.utils.jinja import write_template from hydroshift.utils.plots import ( plot_ams, diff --git a/hydroshift/templates/changepoint_description.md b/hydroshift/templates/changepoint_description.md index 1527e89..8668eae 100644 --- a/hydroshift/templates/changepoint_description.md +++ b/hydroshift/templates/changepoint_description.md @@ -10,7 +10,7 @@ These test statistics were utilized in two distinct ways in this analysis. A st A streaming analysis was performed by treating the data as a stream of values and repeating the static analysis after each new value was added. If the test statistic exceeds a specified threshold at any point within the subseries, a changepoint is marked, and a new data series is initialized for all further test statistics. The resulting change points are shown as dashed red lines in the top panel of Figure 1. - The threshold for identifying changepoints in the streaming analysis is defined using an Average Run Length (ARL0) parameter. ARL0 reflects the frequency with which a false positive would be raised on a stationary timeseries (e.g., for an ARL0 of 1,000 a false changepoint would be identified on a stationary timeseries on average every 1,000 samples.). For this analysis, an ARL0 of {{ arl0 }} was used. - - A burn-in period of {{ burnin }} years was selected to ignore singificant change points in the first {{ burnin }} years of the record due to the influence of small sample sizes. + - A burn-in period of {{ burn_in }} years was selected to ignore singificant change points in the first {{ burn_in }} years of the record due to the influence of small sample sizes. If the flood peak series contained any gaps, the data around the gap was joined as if there was no gap between the data points. For large data gaps, this assumption could lead to inaccurate results. diff --git a/hydroshift/templates/changepoint_ffa.md b/hydroshift/templates/changepoint_ffa.md new file mode 100644 index 0000000..5d7fd26 --- /dev/null +++ b/hydroshift/templates/changepoint_ffa.md @@ -0,0 +1,2 @@ +Based on the changepoint analysis results, a modified flood frequency analysis was conducted using truncated periods of record. The truncated periods correspond with times when the hydrologic regime appears to be stationary across time. Results from this analysis are shown +in Figure 2 and Table 2. diff --git a/hydroshift/templates/changepoint_summary_1.md b/hydroshift/templates/changepoint_summary_1.md new file mode 100644 index 0000000..d556d6d --- /dev/null +++ b/hydroshift/templates/changepoint_summary_1.md @@ -0,0 +1,15 @@ +There is **{{ evidence_level }}** evidence that the annual maximum series data at USGS gage {{ gage_id }} are nonstationary in time. Four change +point detection tests were completed to assess changes in the mean, variance, and overall distribution of flood +peaks across the period of record. Significant change points were identified using a Type I error rate of 1 in +{{ arl0 }} and ignoring significant changes in the first {{ burn_in }} years of data. {{ cp_count }} statistically significant +{% if plural -%} +changepoints were +{%- else -%} +changepoint was +{%- endif %} +identified, indicating that +{% if nonstationary -%} +some form of nonstationarity (e.g., land use change, climate change, flow regulation, etc) may be influencing flow patterns at this site. +{%- else -%} +an assumption of nonstationary conditions is likely reasonable. +{%- endif %} diff --git a/hydroshift/templates/changepoint_summary_2.md b/hydroshift/templates/changepoint_summary_2.md new file mode 100644 index 0000000..ef4445d --- /dev/null +++ b/hydroshift/templates/changepoint_summary_2.md @@ -0,0 +1,16 @@ +The static changepoint test showed {{ evidence }} evidence of a changepoint in the timeseries. +{% if min_p < 1 -%} +A minimum p-value of {{ min_p }} was obtained at {{ p_count }} contiguous time period{{ 's' if plural else '' }}. +{%- else -%} +There were no time-periods where a p-value less than 0.05 was observed in all tests. +{%- endif %} +The p-value reflects the probability that the distribution of +flood peaks before that date has the **same** distribution as the flood peaks after the date. + +{% if len_cp < 1 -%} +The streaming analysis identified one statistically significant changepoint. This changepoint was identified by {{ test_count }} distinct tests: {{ test_list }}. +{%- else -%} +The streaming analysis identified {{ len_cp_str }} statistically significant changepoints. These changepoints broadly fell +into {{ grp_count }} window{{ 's' if plural_2 else '' }} where tests identified changepoints not more than 10 years apart. For a full summary of which +tests identified changes at which dates, see table 2. +{%- endif %} diff --git a/hydroshift/text/__init__.py b/hydroshift/text/__init__.py deleted file mode 100644 index 143f7ac..0000000 --- a/hydroshift/text/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Storage for large blocks of app text.""" diff --git a/hydroshift/text/changepoint.py b/hydroshift/text/changepoint.py deleted file mode 100644 index f69200b..0000000 --- a/hydroshift/text/changepoint.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Storage for large blocks of changepoint app text.""" - -test_description = """ -A changepoint analysis was performed on the series of annual flood peaks Using the change point model of Ross (2015). For each date in the timeseries, the distribution of flood peaks leading up to that date were compared with the distribution after that date using a variety of statistical tests - - - **Mood**: Measures changes in the variance of the peak series. - - **Mann-Whitney**: Measures changes in the mean of the peak series. - - **Lepage**: Combines both Mood and Mann-Whitney statistics into one. - - **Kolmogorov-Smirnov**: Measures changes in the overall distribution of flood peaks. - - **Cramer-von-Mises**: Measures changes in the overall distribution of flood peaks. - -These test statistics were utilized in two distinct ways in this analysis. A static analysis was performed by evaluating the test statistic at each date of the timeseries and using a two-sample test to determine the statistical significance of the distribution differences. The P-values from this analysis are shown in the second panel of Figure 1. -A streaming analysis was performed by treating the data as a stream of values and repeating the static analysis after each new value was added. If the test statistic exceeds a specified threshold at any point within the subseries, a changepoint is marked, and a new data series is initialized for all further test statistics. The resulting change points are shown as dashed red lines in the top panel of Figure 1. - - - The threshold for identifying changepoints in the streaming analysis is defined using an Average Run Length (ARL0) parameter. ARL0 reflects the frequency with which a false positive would be raised on a stationary timeseries (e.g., for an ARL0 of 1,000 a false changepoint would be identified on a stationary timeseries on average every 1,000 samples.). For this analysis, an ARL0 of {} was used. - - A burn-in period of {} years was selected to ignore singificant change points in the first {} years of the record due to the influence of small sample sizes. - -If the flood peak series contained any gaps, the data around the gap was joined as if there was no gap between the data points. For large data gaps, this assumption could lead to inaccurate results. - -""" -references = """ -Gordon J. Ross (2015)., "Parametric and Nonparametric Sequential Change Detection in R: The cpm Package.", Journal of Statistical Software, 66(3), 1-20., https://www.jstatsoft.org/v66/i03/. -""" diff --git a/hydroshift/utils/tests.py b/hydroshift/utils/changepoint.py similarity index 100% rename from hydroshift/utils/tests.py rename to hydroshift/utils/changepoint.py diff --git a/hydroshift/utils/common.py b/hydroshift/utils/common.py new file mode 100644 index 0000000..92e1adf --- /dev/null +++ b/hydroshift/utils/common.py @@ -0,0 +1,18 @@ +def num_2_word(number: int) -> str: + """Convert numbers less than 10 to words.""" + if number > 9: + return number + else: + d = { + 0: "no", + 1: "one", + 2: "two", + 3: "three", + 4: "four", + 5: "five", + 6: "six", + 7: "seven", + 8: "eight", + 9: "nine", + } + return d[number] diff --git a/hydroshift/utils/data_models.py b/hydroshift/utils/data_models.py deleted file mode 100644 index 1aa3614..0000000 --- a/hydroshift/utils/data_models.py +++ /dev/null @@ -1,150 +0,0 @@ -from dataclasses import dataclass, field -from typing import List - -import numpy as np -import pandas as pd -import streamlit as st -from scipy.stats import pearson3, rv_continuous - -from hydroshift.utils.data_retrieval import ( - check_missing_dates, - get_ams, - get_daily_values, - get_flow_stats, - get_monthly_values, - load_site_data, -) -from hydroshift.utils.ffa import l_moments - - -class Gage: - """A USGS Gage.""" - - def __init__(self, gage_id: str): - """Construct class.""" - self.gage_id = gage_id - self.site_data = load_site_data(gage_id) - - @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) - def latitude(self) -> float: - """Latitude of gage.""" - return self.site_data.get("dec_lat_va") - - @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) - def longitude(self) -> float: - """Longitude of gage.""" - return self.site_data.get("dec_long_va") - - @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) - def ams(self) -> pd.DataFrame: - """Load AMS for this site.""" - return get_ams(self.gage_id) - - @property - def ams_vals(self) -> np.ndarray: - """Convenient ams column selection.""" - return self.ams["peak_va"].values - - @property - def missing_dates_ams(self) -> list: - """Get missing dates for AMS.""" - return check_missing_dates(self.ams, "water_year") - - @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) - def flow_stats(self) -> pd.DataFrame: - """Load flow statistics for this site.""" - return get_flow_stats(self.gage_id) - - @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) - def get_daily_values(self, start_date: str, end_date: str) -> pd.DataFrame: - """Load daily mean discharge for this site.""" - return get_daily_values(self.gage_id, start_date, end_date) - - @property - def missing_dates_daily_values(self, start_date: str, end_date: str) -> list: - """Get missing dates for mean daily value series.""" - return check_missing_dates(self.get_daily_values(start_date, end_date), "daily") - - @st.cache_data(hash_funcs={"hydroshift.utils.data_models.Gage": lambda x: hash(x.gage_id)}) - def get_monthly_values(self, start_date: str, end_date: str) -> pd.DataFrame: - """Load monthly mean discharge for this site.""" - return get_monthly_values(self.gage_id, start_date, end_date) - - @property - def missing_dates_monthly_values(self, start_date: str, end_date: str) -> list: - """Get missing dates for mean monthly value series.""" - return check_missing_dates(self.get_monthly_values(start_date, end_date), "monthly") - - def raise_warnings(self): - """Create any high level data warnings.""" - pass - - @property - def has_regional_skew(self): - """Check if gage has regional skew available.""" - return False - - -@dataclass -class LP3Analysis: - """A log-pearson type 3 analysis.""" - - gage_id: str - peaks: list - regional_skew: float = None - est_method: str = "MLE" - label: str = "" - return_periods: List[str] = field(default_factory=lambda: [1.1, 2, 5, 10, 25, 50, 100, 500]) - - def __post_init__(self): - """Customize init.""" - self.peaks = np.sort(self.peaks) - - @property - def log_peaks(self) -> np.ndarray: - """Log 10 of peaks.""" - return np.log10(self.peaks) - - @property - def parameters(self) -> tuple[float]: - """Sample parameters for LP3 distribution.""" - if self.est_method == "MOM": - skew_log, mean_log, std_log = pearson3.fit(self.log_peaks, method="MM") - elif self.est_method == "MLE": - skew_log, mean_log, std_log = pearson3.fit(self.log_peaks, method="MLE") - elif self.est_method == "LMOM": - mean_log, std_log, l3 = l_moments(self.log_peaks) - skew_log = l3 / (std_log * 0.7797) # pseudo-stdev - if self.regional_skew is not None: - skew_log = self.regional_skew - return mean_log, std_log, skew_log - - @property - def distribution(self) -> rv_continuous: - """The fitted LP3 distribution.""" - params = self.parameters - return pearson3(params[2], params[0], params[1]) - - @property - def plotting_positions(self) -> tuple[np.ndarray]: - """Empirical flood frequency curve.""" - aep = np.arange(1, len(self.peaks) + 1)[::-1] / (len(self.peaks) + 1) - return (aep, self.peaks) - - @property - def ffa_quantiles(self) -> tuple[np.ndarray]: - """Calculate some recurrence intervals from fitted distribution.""" - ris = np.array(self.return_periods) - aeps = 1 / ris - qs = np.power(10, self.distribution.ppf(1 - aeps)).astype(int) - return (aeps, qs) - - @property - def quantile_df(self): - """Put quantiles into a dataframe.""" - _, qs = self.ffa_quantiles - return pd.DataFrame({"Recurrence Interval (years)": self.return_periods, "Discharge (cfs)": qs}) diff --git a/hydroshift/utils/data_retrieval.py b/hydroshift/utils/data_retrieval.py index bc811f4..1bea3d7 100644 --- a/hydroshift/utils/data_retrieval.py +++ b/hydroshift/utils/data_retrieval.py @@ -7,6 +7,78 @@ from scipy.stats import genpareto +class Gage: + """A USGS Gage.""" + + def __init__(self, gage_id: str): + """Construct class.""" + self.gage_id = gage_id + self.site_data = load_site_data(gage_id) + + @property + @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + def latitude(self) -> float: + """Latitude of gage.""" + return self.site_data.get("dec_lat_va") + + @property + @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + def longitude(self) -> float: + """Longitude of gage.""" + return self.site_data.get("dec_long_va") + + @property + @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + def ams(self) -> pd.DataFrame: + """Load AMS for this site.""" + return get_ams(self.gage_id) + + @property + def ams_vals(self) -> np.ndarray: + """Convenient ams column selection.""" + return self.ams["peak_va"].values + + @property + def missing_dates_ams(self) -> list: + """Get missing dates for AMS.""" + return check_missing_dates(self.ams, "water_year") + + @property + @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + def flow_stats(self) -> pd.DataFrame: + """Load flow statistics for this site.""" + return get_flow_stats(self.gage_id) + + @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + def get_daily_values(self, start_date: str, end_date: str) -> pd.DataFrame: + """Load daily mean discharge for this site.""" + return get_daily_values(self.gage_id, start_date, end_date) + + @property + def missing_dates_daily_values(self, start_date: str, end_date: str) -> list: + """Get missing dates for mean daily value series.""" + return check_missing_dates(self.get_daily_values(start_date, end_date), "daily") + + @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + def get_monthly_values(self, start_date: str, end_date: str) -> pd.DataFrame: + """Load monthly mean discharge for this site.""" + return get_monthly_values(self.gage_id, start_date, end_date) + + @property + def missing_dates_monthly_values(self, start_date: str, end_date: str) -> list: + """Get missing dates for mean monthly value series.""" + return check_missing_dates(self.get_monthly_values(start_date, end_date), "monthly") + + def raise_warnings(self): + """Create any high level data warnings.""" + pass + + @property + def has_regional_skew(self): + """Check if gage has regional skew available.""" + return False + + @st.cache_data def get_ams(gage_id): """Fetches Annual Maximum Series (AMS) peak flow data for a given gage.""" diff --git a/hydroshift/utils/ffa.py b/hydroshift/utils/ffa.py index d8714b0..1b78fc6 100644 --- a/hydroshift/utils/ffa.py +++ b/hydroshift/utils/ffa.py @@ -1,10 +1,74 @@ +from dataclasses import dataclass, field from math import comb +from typing import List import numpy as np import pandas as pd import rasterio import streamlit as st from scipy import stats +from scipy.stats import pearson3, rv_continuous + + +@dataclass +class LP3Analysis: + """A log-pearson type 3 analysis.""" + + gage_id: str + peaks: list + regional_skew: float = None + est_method: str = "MLE" + label: str = "" + return_periods: List[str] = field(default_factory=lambda: [1.1, 2, 5, 10, 25, 50, 100, 500]) + + def __post_init__(self): + """Customize init.""" + self.peaks = np.sort(self.peaks) + + @property + def log_peaks(self) -> np.ndarray: + """Log 10 of peaks.""" + return np.log10(self.peaks) + + @property + def parameters(self) -> tuple[float]: + """Sample parameters for LP3 distribution.""" + if self.est_method == "MOM": + skew_log, mean_log, std_log = pearson3.fit(self.log_peaks, method="MM") + elif self.est_method == "MLE": + skew_log, mean_log, std_log = pearson3.fit(self.log_peaks, method="MLE") + elif self.est_method == "LMOM": + mean_log, std_log, l3 = l_moments(self.log_peaks) + skew_log = l3 / (std_log * 0.7797) # pseudo-stdev + if self.regional_skew is not None: + skew_log = self.regional_skew + return mean_log, std_log, skew_log + + @property + def distribution(self) -> rv_continuous: + """The fitted LP3 distribution.""" + params = self.parameters + return pearson3(params[2], params[0], params[1]) + + @property + def plotting_positions(self) -> tuple[np.ndarray]: + """Empirical flood frequency curve.""" + aep = np.arange(1, len(self.peaks) + 1)[::-1] / (len(self.peaks) + 1) + return (aep, self.peaks) + + @property + def ffa_quantiles(self) -> tuple[np.ndarray]: + """Calculate some recurrence intervals from fitted distribution.""" + ris = np.array(self.return_periods) + aeps = 1 / ris + qs = np.power(10, self.distribution.ppf(1 - aeps)).astype(int) + return (aeps, qs) + + @property + def quantile_df(self): + """Put quantiles into a dataframe.""" + _, qs = self.ffa_quantiles + return pd.DataFrame({"Recurrence Interval (years)": self.return_periods, "Discharge (cfs)": qs}) @st.cache_data diff --git a/hydroshift/utils/plots.py b/hydroshift/utils/plots.py index b33d12b..96b58c3 100644 --- a/hydroshift/utils/plots.py +++ b/hydroshift/utils/plots.py @@ -2,10 +2,11 @@ import plotly.express as px import plotly.graph_objects as go import streamlit as st +from plotly.graph_objects import Figure from plotly.subplots import make_subplots from scipy.stats import norm -from hydroshift.utils.data_models import LP3Analysis +from hydroshift.utils.ffa import LP3Analysis def plot_ams(ams_df, gage_id, cps: dict = {}): @@ -320,7 +321,7 @@ def plot_cpm_heatmap(pval_df: pd.DataFrame): @st.cache_data -def combo_cpm(ams_df: pd.DataFrame, pval_df: pd.DataFrame, cps: dict = {}): +def combo_cpm(ams_df: pd.DataFrame, pval_df: pd.DataFrame, cps: dict = {}) -> Figure: """Plot a change point model with peak flows and statistical analysis.""" # Create subplots fig = make_subplots( diff --git a/tests/stat_tests/changepoint_test.py b/tests/stat_tests/changepoint_test.py index 6dd5305..2c43f77 100644 --- a/tests/stat_tests/changepoint_test.py +++ b/tests/stat_tests/changepoint_test.py @@ -5,7 +5,7 @@ from scipy.ndimage import gaussian_filter1d from scipy.stats import genpareto -from hydroshift.utils.tests import ( +from hydroshift.utils.changepoint import ( cpm_detect_change_point_batch, cpm_process_stream, get_batch_threshold, From b33bff469ab9e7fba36da00d63f5128658f34e5c Mon Sep 17 00:00:00 2001 From: sclaw Date: Thu, 1 May 2025 15:55:02 -0400 Subject: [PATCH 06/24] add regional skew --- hydroshift/_pages/changepoint.py | 65 +++++++++++++----- hydroshift/_pages/summary.py | 54 +++++++++++---- hydroshift/utils/data_retrieval.py | 106 ++++++++++++++++++++++++----- hydroshift/utils/ffa.py | 89 +++++++++++++----------- hydroshift/utils/plots.py | 27 ++++++-- 5 files changed, 247 insertions(+), 94 deletions(-) diff --git a/hydroshift/_pages/changepoint.py b/hydroshift/_pages/changepoint.py index bc54cd4..40438a3 100644 --- a/hydroshift/_pages/changepoint.py +++ b/hydroshift/_pages/changepoint.py @@ -68,7 +68,9 @@ def get_change_windows(self, max_dist: float = 10) -> tuple: current_group_tests = set(test_dict[dates[0]]) for i in range(1, len(dates)): - if ((dates[i] - current_group[-1]).days / 365) < max_dist: # 10 years in days + if ( + (dates[i] - current_group[-1]).days / 365 + ) < max_dist: # 10 years in days current_group.append(dates[i]) current_group_tests = current_group_tests.union(test_dict[dates[i]]) else: @@ -87,7 +89,12 @@ def get_max_pvalue(self) -> tuple[float, int]: """Get the minimum p value where all tests agree and count how often that occurred.""" all_tests = self.pval_df.fillna(1).max(axis=1).to_frame(name="pval") all_tests["run"] = ((all_tests != all_tests.shift(1)) * 1).cumsum() - for ind, r in all_tests.groupby("pval").agg({"run": pd.Series.nunique}).sort_index().iterrows(): + for ind, r in ( + all_tests.groupby("pval") + .agg({"run": pd.Series.nunique}) + .sort_index() + .iterrows() + ): if r.run > 0: min_p = ind count = r.run @@ -116,7 +123,9 @@ def ffa_png(self): @property def cp_df(self): """Get a dataframe representing changepoints identified in the streaming analysis.""" - cpa_df = pd.DataFrame.from_dict(self.cp_dict, orient="index", columns=["Tests Identifying Change"]) + cpa_df = pd.DataFrame.from_dict( + self.cp_dict, orient="index", columns=["Tests Identifying Change"] + ) cpa_df.index = cpa_df.index.date return cpa_df @@ -142,7 +151,10 @@ def summary_text(self) -> str: @property def test_description(self): """Analysis methodology.""" - payload = {"alr0": st.session_state.arlo_slider, "burn_in": st.session_state.burn_in} + payload = { + "alr0": st.session_state.arlo_slider, + "burn_in": st.session_state.burn_in, + } return render_template("changepoint_description.md", payload) @property @@ -168,7 +180,9 @@ def results_text(self) -> str: "plural": p_count > 1, "len_cp": len(self.cp_dict), "len_cp_str": num_2_word(len(self.cp_dict)), - "test_count": num_2_word(len(self.cp_dict[next(iter(self.cp_dict))].split(","))), + "test_count": num_2_word( + len(self.cp_dict[next(iter(self.cp_dict))].split(",")) + ), "grp_count": num_2_word(len(groups)), "plural_2": len(groups) > 0, } @@ -204,7 +218,9 @@ def word_data(self) -> BytesIO: document.add_heading("Modified flood frequency analysis", level=2) self.add_markdown_to_doc(document, self.ffa_text) document.add_picture(self.ffa_png, width=Inches(6.5)) - self.add_markdown_to_doc(document, "**Figure 2.** Modified flood frequency analysis.") + self.add_markdown_to_doc( + document, "**Figure 2.** Modified flood frequency analysis." + ) self.add_markdown_to_doc(document, "**Table 2.** Modified flood quantiles.") self.add_table_from_df(self.ffa_df, document, index_name="Regime Period") @@ -215,7 +231,9 @@ def word_data(self) -> BytesIO: document.save(out) return out - def add_table_from_df(self, df: pd.DataFrame, document: Document, index_name: str = None): + def add_table_from_df( + self, df: pd.DataFrame, document: Document, index_name: str = None + ): if index_name is not None: df = df.copy() cols = df.columns @@ -251,10 +269,8 @@ def validate_data(self): st.session_state.data_comment = "Unable to retrieve data." elif len(data) < st.session_state.burn_in: st.session_state.valid_data = False - st.session_state.data_comment = ( - "Not enough peaks available for analysis. {} peaks found, but burn-in length was {}".format( - len(data["peaks"]), st.session_state.burn_in - ) + st.session_state.data_comment = "Not enough peaks available for analysis. {} peaks found, but burn-in length was {}".format( + len(data["peaks"]), st.session_state.burn_in ) else: st.session_state.valid_data = True @@ -282,7 +298,9 @@ def make_sidebar(): """User control for analysis.""" with st.sidebar: st.title("Settings") - st.session_state["gage_id"] = st.text_input("Enter USGS Gage Number:", st.session_state["gage_id"]) + st.session_state["gage_id"] = st.text_input( + "Enter USGS Gage Number:", st.session_state["gage_id"] + ) st.session_state.gage = Gage(st.session_state["gage_id"]) st.select_slider( "False Positive Rate (1 in #)", @@ -322,7 +340,9 @@ def run_analysis(): """Run the change point model analysis.""" cpa = st.session_state.changepoint cpa.pval_df = get_pvalues(cpa.gage.ams) - cpa.cp_dict = get_changepoints(cpa.gage.ams, st.session_state.arlo_slider, st.session_state.burn_in) + cpa.cp_dict = get_changepoints( + cpa.gage.ams, st.session_state.arlo_slider, st.session_state.burn_in + ) @st.cache_data @@ -362,7 +382,9 @@ def ffa_analysis(data: pd.DataFrame, regimes: list): ffa_dict[label] = {"peaks": sub, "lp3": lp3} if len(ffa_dict) > 0: ffa_plot = plot_lp3(ffa_dict, st.session_state.gage_id, multi_series=True) - ffa_df = pd.DataFrame.from_dict({k: ffa_dict[k]["lp3"] for k in ffa_dict}, orient="index") + ffa_df = pd.DataFrame.from_dict( + {k: ffa_dict[k]["lp3"] for k in ffa_dict}, orient="index" + ) renames = {c: f"Q{c}" for c in ffa_df.columns} ffa_df = ffa_df.rename(columns=renames) return ffa_plot, ffa_df @@ -394,7 +416,9 @@ def make_body(): st.header("Modified flood frequency analysis") if len(st.session_state.ffa_regimes["added_rows"]) > 0: - ffa_plot, ffa_df = ffa_analysis(cpa.data, st.session_state.ffa_regimes["added_rows"]) + ffa_plot, ffa_df = ffa_analysis( + cpa.data, st.session_state.ffa_regimes["added_rows"] + ) if ffa_plot is not None and ffa_df is not None: st.markdown(cpa.ffa_text) cpa.ffa_plot = ffa_plot @@ -411,12 +435,19 @@ def make_body(): st.header("References") st.markdown(cpa.references) - st.download_button("Download analysis", cpa.word_data, f"changepoint_analysis_{st.session_state.gage_id}.docx") + st.download_button( + "Download analysis", + cpa.word_data, + f"changepoint_analysis_{st.session_state.gage_id}.docx", + ) def warnings(): """Print warnings on data validity etc.""" - if st.session_state.changepoint.gage.ams is not None and "peak_va" in st.session_state.changepoint.gage.ams.columns: + if ( + st.session_state.changepoint.gage.ams is not None + and "peak_va" in st.session_state.changepoint.gage.ams.columns + ): if st.session_state.changepoint.gage.missing_dates_ams: st.warning( "Missing {} dates between {} and {}".format( diff --git a/hydroshift/_pages/summary.py b/hydroshift/_pages/summary.py index 903ff84..a6aed28 100644 --- a/hydroshift/_pages/summary.py +++ b/hydroshift/_pages/summary.py @@ -18,7 +18,7 @@ def section_ams(gage: Gage): """Display the AMS section.""" if gage.ams is not None: - if gage.missing_dates_ams is not None: + if gage.missing_dates_ams is not None and len(gage.missing_dates_ams) > 0: st.warning(f"Missing {len(gage.missing_dates_ams)} AMS records") st.plotly_chart(plot_ams(gage.ams, gage.gage_id)) show_data = st.checkbox("Show AMS Data Table") @@ -42,19 +42,27 @@ def section_lp3(gage: Gage): opt_col_1, opt_col_2 = st.columns(2) with opt_col_1: est_method = st.selectbox( - "Estimation Method", ["L-moments", "Method of moments", "Maximum Likelihood"], index=2 + "Estimation Method", + ["L-moments", "Method of moments", "Maximum Likelihood"], + index=1, ) - est_method = {"L-moments": "LMOM", "Method of moments": "MOM", "Maximum Likelihood": "MLE"}[est_method] + est_method = { + "L-moments": "LMOM", + "Method of moments": "MOM", + "Maximum Likelihood": "MLE", + }[est_method] with opt_col_2: - st_skew = st.toggle("Use regional skew", value=False, disabled=not gage.has_regional_skew) + st_skew = st.toggle( + "Use regional skew", value=False, disabled=not gage.has_regional_skew + ) if st_skew: - skew = gage.regional_skew + use_map = True else: - skew = None + use_map = False # Analysis and display - lp3 = LP3Analysis(gage.gage_id, gage.ams_vals, skew, est_method, "") - if gage.missing_dates_ams is not None: + lp3 = LP3Analysis(gage.gage_id, gage.ams_vals, use_map, est_method, "") + if gage.missing_dates_ams is not None and len(gage.missing_dates_ams) > 0: st.warning(f"Missing {len(gage.missing_dates_ams)} LP3 records") st.plotly_chart(plot_lp3(lp3), use_container_width=True) show_data = st.checkbox("Show LP3 Data Table") @@ -67,7 +75,9 @@ def section_ams_seasonal(gage: Gage): if gage.ams is not None: if gage.missing_dates_ams: st.warning(f"Missing {len(gage.missing_dates_ams)} AMS seasonal records") - st.plotly_chart(plot_ams_seasonal(gage.ams, gage.gage_id), use_container_width=True) + st.plotly_chart( + plot_ams_seasonal(gage.ams, gage.gage_id), use_container_width=True + ) show_data = st.checkbox("Show Ranked Seasonal Data Table") if show_data: st.dataframe(gage.ams) @@ -89,7 +99,9 @@ def section_daily_mean(gage: Gage): if data is not None: if missing_dates: st.warning(f"Missing {len(missing_dates)} daily mean records") - st.plotly_chart(plot_daily_mean(data, gage.gage_id), use_container_width=True) + st.plotly_chart( + plot_daily_mean(data, gage.gage_id), use_container_width=True + ) show_data = st.checkbox("Show Daily Mean Data Table") if show_data: st.dataframe(data) @@ -98,11 +110,14 @@ def section_daily_mean(gage: Gage): def section_monthly_mean(gage: Gage): """Display the monthly mean discharge section.""" data = gage.get_monthly_values() - missing_dates = gage.missing_dates_monthly_values() + missing_dates = gage.missing_dates_monthly_values if data is not None and "mean_va" in data.columns: if missing_dates: st.warning(f"Missing {len(missing_dates)} monthly records") - st.plotly_chart(plot_monthly_mean(data, st.session_state["gage_id"]), use_container_width=True) + st.plotly_chart( + plot_monthly_mean(data, st.session_state["gage_id"]), + use_container_width=True, + ) show_data = st.checkbox("Show Monthly Mean Data Table") if show_data: @@ -115,7 +130,9 @@ def summary(): # Sidebar for input with st.sidebar: st.title("Settings") - st.session_state["gage_id"] = st.text_input("Enter USGS Gage Number:", st.session_state["gage_id"]) + st.session_state["gage_id"] = st.text_input( + "Enter USGS Gage Number:", st.session_state["gage_id"] + ) gage = Gage(st.session_state["gage_id"]) # Toggle plots @@ -132,7 +149,9 @@ def summary(): write_template("data_sources_side_bar.html") if st.session_state["gage_id"]: - with st.spinner("Loading gage data..."): # This is here to clear previous pages while data loads. + with st.spinner( + "Loading gage data..." + ): # This is here to clear previous pages while data loads. pass col2, col3 = st.columns([6, 2], gap="large") @@ -142,7 +161,12 @@ def summary(): st.subheader("Gage Location") # Create Folium Map - mini_map = folium.Map(location=[gage.latitude, gage.longitude], zoom_start=7, width=200, height=200) + mini_map = folium.Map( + location=[gage.latitude, gage.longitude], + zoom_start=7, + width=200, + height=200, + ) folium.Marker( [gage.latitude, gage.longitude], popup=f"Gage {st.session_state['gage_id']}", diff --git a/hydroshift/utils/data_retrieval.py b/hydroshift/utils/data_retrieval.py index 1bea3d7..2dafff6 100644 --- a/hydroshift/utils/data_retrieval.py +++ b/hydroshift/utils/data_retrieval.py @@ -2,6 +2,8 @@ import numpy as np import pandas as pd +import rasterio +import requests import streamlit as st from dataretrieval import NoSitesError, nwis from scipy.stats import genpareto @@ -16,19 +18,55 @@ def __init__(self, gage_id: str): self.site_data = load_site_data(gage_id) @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) def latitude(self) -> float: """Latitude of gage.""" return self.site_data.get("dec_lat_va") @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) def longitude(self) -> float: """Longitude of gage.""" return self.site_data.get("dec_long_va") @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) + def elevation(self) -> float: + """Elevation of gage.""" + return self.site_data.get("alt_va") + + @property + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) + def mean_basin_elevation(self) -> float: + """Average elevation of gage watershed.""" + row = [ + r for r in self.streamstats["characteristics"] if r["variableTypeID"] == 6 + ] # Get ELEV param + return row[0]["value"] + + @property + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) + def streamstats(self) -> pd.DataFrame: + """Load AMS for this site.""" + r = requests.get( + f"https://streamstats.usgs.gov/gagestatsservices/stations/{self.gage_id}" + ) + return r.json() + + @property + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) def ams(self) -> pd.DataFrame: """Load AMS for this site.""" return get_ams(self.gage_id) @@ -44,39 +82,60 @@ def missing_dates_ams(self) -> list: return check_missing_dates(self.ams, "water_year") @property - @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) def flow_stats(self) -> pd.DataFrame: """Load flow statistics for this site.""" return get_flow_stats(self.gage_id) - @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) def get_daily_values(self, start_date: str, end_date: str) -> pd.DataFrame: """Load daily mean discharge for this site.""" return get_daily_values(self.gage_id, start_date, end_date) - @property def missing_dates_daily_values(self, start_date: str, end_date: str) -> list: """Get missing dates for mean daily value series.""" return check_missing_dates(self.get_daily_values(start_date, end_date), "daily") - @st.cache_data(hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)}) - def get_monthly_values(self, start_date: str, end_date: str) -> pd.DataFrame: + @st.cache_data( + hash_funcs={"hydroshift.utils.data_retrieval.Gage": lambda x: hash(x.gage_id)} + ) + def get_monthly_values(self) -> pd.DataFrame: """Load monthly mean discharge for this site.""" - return get_monthly_values(self.gage_id, start_date, end_date) + return get_monthly_values(self.gage_id) @property - def missing_dates_monthly_values(self, start_date: str, end_date: str) -> list: + def missing_dates_monthly_values(self) -> list: """Get missing dates for mean monthly value series.""" - return check_missing_dates(self.get_monthly_values(start_date, end_date), "monthly") + return check_missing_dates(self.get_monthly_values(), "monthly") def raise_warnings(self): """Create any high level data warnings.""" pass @property - def has_regional_skew(self): + def has_regional_skew(self) -> bool: """Check if gage has regional skew available.""" - return False + return self.regional_skew is not None + + @property + def regional_skew(self) -> float: + """The skew value from the PeakFQ skew map, if one exists.""" + raster = get_skew_raster() + try: + val = [i for i in raster.sample([(self.longitude, self.latitude)])][0][0] + if val in raster.nodatavals: + return None + except (KeyError, IndexError): + return None + if val == 9999: # California Eq. from USGS SIR 2010-5260 NL-ELEV eq + val = (0 - 0.62) + 1.3 * ( + 1 - np.exp(0 - ((self.mean_basin_elevation) / 6500) ** 2) + ) + return val @st.cache_data @@ -127,6 +186,7 @@ def load_site_data(gage_number: str) -> dict: "dec_long_va": float(resp["dec_long_va"].iloc[0]), "drain_area_va": resp["drain_area_va"].iloc[0], "huc_cd": resp["huc_cd"].iloc[0], + "alt_va": resp["alt_va"].iloc[0], "alt_datum_cd": resp["alt_datum_cd"].iloc[0], } @@ -177,7 +237,9 @@ def check_missing_dates(df, freq): elif freq == "monthly": df["date"] = pd.to_datetime(df["date"]) - full_range = pd.date_range(start=df["date"].min(), end=df["date"].max(), freq="MS") + full_range = pd.date_range( + start=df["date"].min(), end=df["date"].max(), freq="MS" + ) elif freq == "water_year": if not isinstance(df.index, pd.DatetimeIndex): @@ -185,7 +247,9 @@ def check_missing_dates(df, freq): df["water_year"] = df.index.year.where(df.index.month < 10, df.index.year + 1) - full_water_years = set(range(df["water_year"].min(), df["water_year"].max() + 1)) + full_water_years = set( + range(df["water_year"].min(), df["water_year"].max() + 1) + ) existing_water_years = set(df["water_year"]) missing_years = sorted(full_water_years - existing_water_years) @@ -217,5 +281,15 @@ def fake_ams() -> pd.DataFrame: rvs = np.concatenate(rvs, axis=0) dates = pd.date_range(start="1900-01-01", periods=len(rvs), freq="YE") water_year = dates.year - df = pd.DataFrame({"datetime": dates, "peak_va": rvs, "water_year": water_year}).set_index("datetime") + df = pd.DataFrame( + {"datetime": dates, "peak_va": rvs, "water_year": water_year} + ).set_index("datetime") return df + + +@st.cache_resource +def get_skew_raster(): + """Load the skew raster into memory.""" + return rasterio.open( + __file__.replace("utils/data_retrieval.py", "data/skewmap_4326.tif") + ) diff --git a/hydroshift/utils/ffa.py b/hydroshift/utils/ffa.py index 1b78fc6..e81e371 100644 --- a/hydroshift/utils/ffa.py +++ b/hydroshift/utils/ffa.py @@ -4,11 +4,10 @@ import numpy as np import pandas as pd -import rasterio -import streamlit as st -from scipy import stats from scipy.stats import pearson3, rv_continuous +from hydroshift.utils.data_retrieval import Gage + @dataclass class LP3Analysis: @@ -16,10 +15,14 @@ class LP3Analysis: gage_id: str peaks: list - regional_skew: float = None + use_map_skew: bool = False est_method: str = "MLE" label: str = "" - return_periods: List[str] = field(default_factory=lambda: [1.1, 2, 5, 10, 25, 50, 100, 500]) + return_periods: List[str] = field( + default_factory=lambda: [1.1, 2, 5, 10, 25, 50, 100, 500] + ) + + # TODO: Add california equation. Likely best to subclass this. def __post_init__(self): """Customize init.""" @@ -40,10 +43,15 @@ def parameters(self) -> tuple[float]: elif self.est_method == "LMOM": mean_log, std_log, l3 = l_moments(self.log_peaks) skew_log = l3 / (std_log * 0.7797) # pseudo-stdev - if self.regional_skew is not None: - skew_log = self.regional_skew + if self.use_map_skew: + skew_log = self.weighted_skew return mean_log, std_log, skew_log + @property + def station_skew(self) -> tuple[float]: + """Skew of peaks.""" + return pearson3.fit(self.log_peaks, method="MM")[0] + @property def distribution(self) -> rv_continuous: """The fitted LP3 distribution.""" @@ -68,13 +76,41 @@ def ffa_quantiles(self) -> tuple[np.ndarray]: def quantile_df(self): """Put quantiles into a dataframe.""" _, qs = self.ffa_quantiles - return pd.DataFrame({"Recurrence Interval (years)": self.return_periods, "Discharge (cfs)": qs}) + return pd.DataFrame( + {"Recurrence Interval (years)": self.return_periods, "Discharge (cfs)": qs} + ) + @property + def map_skew(self): + """The skew value from the PeakFQ skew map, if one exists.""" + gage = Gage(self.gage_id) + return gage.regional_skew -@st.cache_data -def get_skew_raster(): - """Load the skew raster into memory.""" - return rasterio.open(__file__.replace("ffa.py", "skewmap_4326.tif")) + @property + def mse_station_skew(self) -> float: + """Weighted station skew using USGS B17B method.""" + abs_g = abs(self.station_skew) + if abs_g <= 0.9: + a = -0.33 + (0.08 * abs_g) + else: + a = -0.52 + (0.3 * abs_g) + if abs_g <= 1.5: + b = 0.94 - (0.26 * abs_g) + else: + a = 0.55 + return 10 ** (a - (b * np.log10(len(self.peaks) / 10))) + + @property + def weighted_skew(self) -> float: + """Weighted station skew using USGS B17B method.""" + g_s = self.station_skew # Station Skew + g_g = self.map_skew # Generalized skew + mse_s = self.mse_station_skew # MSE of station skew + mse_g = 0.302 # From peakfq user manual page 7. TODO: Update for Cali equation + + # From Handbook of hydrology pg 18.44 + g_weighted = ((g_s / mse_s) + (g_g / mse_g)) / ((1 / mse_s) + (1 / mse_g)) + return g_weighted def l_moments(series): @@ -97,32 +133,3 @@ def l_moments(series): l2 = (2 * b_values[1]) - b_values[0] l3 = (6 * b_values[2]) - (6 * b_values[1]) + (1 * b_values[0]) return l1, l2, l3 - - -@st.cache_data -def log_pearson_iii( - peak_flows: pd.Series, - standard_return_periods: list = [1.1, 2, 5, 10, 25, 50, 100, 500], - method: str = "MLE", - coords: list = None, -): - log_flows = np.log10(peak_flows.values) - if method == "MM": - skew_log, mean_log, std_log = stats.pearson3.fit(log_flows, method="MM") - elif method == "MLE": - skew_log, mean_log, std_log = stats.pearson3.fit(log_flows, method="MLE") - elif method == "LMOM": - mean_log, std_log, skew_log = l_moments(log_flows) - - if coords: - src = get_skew_raster() - tmp_skew = src.sample(coords[0:2]) - if tmp_skew == 9999: # CA Equation - tmp_skew = (0 - 0.62) + 1.3 * (1 - np.exp(0 - ((coords[2]) / 6500) ^ 2)) - if not np.isnan(tmp_skew): - skew_log = tmp_skew - - return { - rp: int(10 ** stats.pearson3(skew=skew_log, loc=mean_log, scale=std_log).ppf(1 - 1 / rp)) - for rp in standard_return_periods - } diff --git a/hydroshift/utils/plots.py b/hydroshift/utils/plots.py index 96b58c3..2287b10 100644 --- a/hydroshift/utils/plots.py +++ b/hydroshift/utils/plots.py @@ -187,8 +187,10 @@ def plot_lp3(data: LP3Analysis | list[LP3Analysis]): ) # Formatting - return_periods = [int(i) if i.is_integer() else round(i, 1) for i in i.return_periods] - if i.regional_skew is not None: + return_periods = [ + int(i) if i.is_integer() else round(i, 1) for i in i.return_periods + ] + if i.use_map_skew: skew_txt = "" else: skew_txt = " (No Regional Skew)" @@ -220,7 +222,12 @@ def plot_ams_seasonal(df, gage_id): color="season", title=f"Gage ID: {gage_id} | Seasonal AMS Ranked from Low to High", labels={"rank": "Rank", "peak_va": "Flow (cfs)"}, - color_discrete_map={"Winter": "blue", "Spring": "green", "Summer": "orange", "Fall": "brown"}, + color_discrete_map={ + "Winter": "blue", + "Spring": "green", + "Summer": "orange", + "Fall": "brown", + }, ) fig.update_layout( @@ -238,7 +245,13 @@ def plot_daily_mean(dv_df, gage_id): fig = go.Figure() fig.add_trace( - go.Scatter(x=dv_df.index, y=dv_df["00060_Mean"], mode="lines", line=dict(color="blue"), name="Daily Mean Flow") + go.Scatter( + x=dv_df.index, + y=dv_df["00060_Mean"], + mode="lines", + line=dict(color="blue"), + name="Daily Mean Flow", + ) ) fig.update_layout( @@ -334,7 +347,11 @@ def combo_cpm(ams_df: pd.DataFrame, pval_df: pd.DataFrame, cps: dict = {}) -> Fi # Scatter plot for peak flow data fig.add_trace( go.Scatter( - x=ams_df.index, y=ams_df["peak_va"], mode="markers", marker=dict(size=6, color="blue"), name="Peak Flow" + x=ams_df.index, + y=ams_df["peak_va"], + mode="markers", + marker=dict(size=6, color="blue"), + name="Peak Flow", ), row=1, col=1, From 3cc5de270e94e343357c23456fc90ed737daebda Mon Sep 17 00:00:00 2001 From: sclaw Date: Fri, 2 May 2025 11:52:20 -0400 Subject: [PATCH 07/24] incorporate ui improvements. gh-7, gh-5, gh-1 --- hydroshift/_pages/summary.py | 14 ++++-- hydroshift/consts.py | 9 ++++ hydroshift/utils/common.py | 35 +++++++++++++ hydroshift/utils/data_retrieval.py | 51 ++++++++++++++++++- hydroshift/utils/plots.py | 81 ++++++++++++++++++++++-------- 5 files changed, 162 insertions(+), 28 deletions(-) diff --git a/hydroshift/_pages/summary.py b/hydroshift/_pages/summary.py index a6aed28..970559e 100644 --- a/hydroshift/_pages/summary.py +++ b/hydroshift/_pages/summary.py @@ -1,3 +1,5 @@ +from datetime import date + import folium import streamlit as st from streamlit_folium import st_folium @@ -90,10 +92,14 @@ def section_daily_mean(gage: Gage): with input_col: st.write("") # blank line for more space st.write("Daily Mean Input Dates") - start_date = st.text_input("Start Date (YYYY-MM-DD)", "2024-01-01") - end_date = st.text_input("End Date (YYYY-MM-DD)", "2024-12-31") - - data = gage.get_daily_values(start_date, end_date) + start_date = st.date_input("Start Date", value=date(2024, 1, 1)) + end_date = st.date_input("End Date", value=date(2024, 12, 31)) + + data, missing_dates = gage.get_daily_values( + st.session_state["gage_id"], + start_date.strftime("%Y-%m-%d"), + end_date.strftime("%Y-%m-%d"), + ) missing_dates = gage.missing_dates_daily_values(start_date, end_date) with plot_col: if data is not None: diff --git a/hydroshift/consts.py b/hydroshift/consts.py index 32a092e..8eaa36e 100644 --- a/hydroshift/consts.py +++ b/hydroshift/consts.py @@ -45,3 +45,12 @@ CP_T1_CAPTION = "**Table 1.** Results of the changepoint analysis, listing dates when a significant change was identified for each test statistic." CP_F2_CAPTION = "**Figure 2.** Modified flood frequency analysis." CP_T2_CAPTION = "**Table 2.** Modified flood quantiles." + +### MISC ### +REGULATION_MAP = { + "3": "Discharge affected by Dam Failure", + "5": "Discharge affected to unknown degree by Regulation or Diversion", + "6": "Discharge affected by Regulation or Diversion", + "9": "Discharge due to Snowmelt, Hurricane, Ice-Jam or Debris Dam breakup", + "C": "All or part of the record affected by Urbanization, Mining, Agricultural changes, Channelization, or other", +} diff --git a/hydroshift/utils/common.py b/hydroshift/utils/common.py index 92e1adf..ca78ebd 100644 --- a/hydroshift/utils/common.py +++ b/hydroshift/utils/common.py @@ -1,3 +1,11 @@ +from itertools import groupby +from typing import List + +import pandas as pd + +from hydroshift.consts import REGULATION_MAP + + def num_2_word(number: int) -> str: """Convert numbers less than 10 to words.""" if number > 9: @@ -16,3 +24,30 @@ def num_2_word(number: int) -> str: 9: "nine", } return d[number] + + +def group_consecutive_years(years: List[int]) -> List[str]: + """Group consecutive years together and returns a list of formatted year ranges.""" + sorted_years = sorted(years) + grouped_years = [] + + for _, group in groupby(enumerate(sorted_years), lambda ix: ix[0] - ix[1]): + g = [x[1] for x in group] + grouped_years.append(f"{g[0]}" if len(g) == 1 else f"{g[0]}-{g[-1]}") + + return grouped_years + + +def classify_regulation(code_string): + """Return True if any code in the string is considered regulated.""" + if pd.isna(code_string): + return False + for code in str(code_string).split(","): + code = code.strip() + try: + code = str(int(float(code))) # normalize numeric string like '6.0' to '6' + except ValueError: + pass + if code in REGULATION_MAP: + return True + return False diff --git a/hydroshift/utils/data_retrieval.py b/hydroshift/utils/data_retrieval.py index 2dafff6..d029899 100644 --- a/hydroshift/utils/data_retrieval.py +++ b/hydroshift/utils/data_retrieval.py @@ -1,4 +1,5 @@ import logging +from typing import List import numpy as np import pandas as pd @@ -8,6 +9,9 @@ from dataretrieval import NoSitesError, nwis from scipy.stats import genpareto +from hydroshift.consts import REGULATION_MAP +from hydroshift.utils.common import group_consecutive_years + class Gage: """A USGS Gage.""" @@ -112,9 +116,52 @@ def missing_dates_monthly_values(self) -> list: """Get missing dates for mean monthly value series.""" return check_missing_dates(self.get_monthly_values(), "monthly") + def get_regulation_summary(self, major_codes=["3", "9"]) -> List[str]: + """Run regulation summary for gage.""" + df = self.ams + df["water_year"] = df.index.year.where(df.index.month < 10, df.index.year + 1) + + regulation_years = {} + + for index, row in df.iterrows(): + if pd.notna(row.get("peak_cd")): + codes = str(row["peak_cd"]).split(",") + for code in codes: + code_str = code.strip() + try: + code_key = str(int(float(code_str))) # Normalize numeric codes + except ValueError: + code_key = code_str + + if code_key in REGULATION_MAP: + regulation_years.setdefault(code_key, set()).add( + row["water_year"] + ) + + results = {"major": [], "minor": []} + for code, years in regulation_years.items(): + grouped_year_ranges = group_consecutive_years(sorted(years)) + formatted_ranges = ", ".join(grouped_year_ranges) + if code in major_codes: + results["major"].append( + f"{REGULATION_MAP[code]} for water years {formatted_ranges}" + ) + else: + results["minor"].append( + f"{REGULATION_MAP[code]} for water years {formatted_ranges}" + ) + + return results + def raise_warnings(self): """Create any high level data warnings.""" - pass + regulation_results = self.get_regulation_summary() + if regulation_results["minor"]: + for result in regulation_results["minor"]: + st.warning(result) + if regulation_results["major"]: + for result in regulation_results["major"]: + st.error(result) @property def has_regional_skew(self) -> bool: @@ -162,7 +209,7 @@ def get_ams(gage_id): def get_flow_stats(gage_id): """Fetches flow statistics for a given gage.""" try: - df = nwis.get_stats(sites=gage_id, ssl_check=True)[0] + df = nwis.get_stats(sites=gage_id, parameterCd="00060", ssl_check=True)[0] except IndexError: logging.warning(f"Flow stats could not be found for gage_id: {gage_id}") return None diff --git a/hydroshift/utils/plots.py b/hydroshift/utils/plots.py index 2287b10..2d84cfd 100644 --- a/hydroshift/utils/plots.py +++ b/hydroshift/utils/plots.py @@ -6,22 +6,40 @@ from plotly.subplots import make_subplots from scipy.stats import norm +from hydroshift.utils.common import classify_regulation from hydroshift.utils.ffa import LP3Analysis def plot_ams(ams_df, gage_id, cps: dict = {}): - """Plots AMS (Annual Peak Flow) using Plotly with only markers (no line).""" + """Plot AMS (Annual Peak Flow) with markers colored by regulation status.""" fig = go.Figure() + # Classify each point as regulated or not + ams_df["regulated"] = ams_df["peak_cd"].apply(classify_regulation) + + # Plot non-regulated points fig.add_trace( go.Scatter( - x=ams_df.index, - y=ams_df["peak_va"], + x=ams_df[~ams_df["regulated"]].index, + y=ams_df[~ams_df["regulated"]]["peak_va"], mode="markers", marker=dict(size=6, color="blue"), - name="Peak Flow", + name="Non-Regulated", + ) + ) + + # Plot regulated points + fig.add_trace( + go.Scatter( + x=ams_df[ams_df["regulated"]].index, + y=ams_df[ams_df["regulated"]]["peak_va"], + mode="markers", + marker=dict(size=6, color="red"), + name="Regulated", ) ) + + # Plot changepoints if provided if cps: for ind, cp in enumerate(cps): x = ams_df.index[cp] @@ -30,22 +48,22 @@ def plot_ams(ams_df, gage_id, cps: dict = {}): x=[x, x], y=[ams_df["peak_va"].min(), ams_df["peak_va"].max()], mode="lines", - line=dict(color="red", width=1, dash="dash"), + line=dict(color="black", width=1, dash="dash"), hovertext=[cps[cp], cps[cp]], hoverinfo="text", showlegend=False, ) ) - # Label line + # Legend label for changepoint fig.add_trace( go.Scatter( x=[0, 0], y=[0, 0], mode="lines", - line=dict(color="red", width=1, dash="dash"), # Dashed style - hoverinfo="skip", # Don't show hover on this trace - showlegend=True, # Hide the legend entry for this trace - name="Statistically\nSignificant\nChangepoint", + line=dict(color="black", width=1, dash="dash"), + hoverinfo="skip", + showlegend=True, + name="Statistically Significant Changepoint", ) ) @@ -67,16 +85,25 @@ def plot_ams(ams_df, gage_id, cps: dict = {}): def plot_flow_stats(stats_df, gage_id): - """Plots Flow Statistics using Plotly with correctly labeled legend entries.""" - # Ensure the data is sorted properly + """Plot Flow Statistics using Plotly with month-abbreviation x-axis labels.""" + # Ensure data is sorted + # Create a datetime column + stats_df["date"] = pd.to_datetime( + { + "year": 2000, # dummy leap year to support Feb 29 + "month": stats_df["month_nu"], + "day": stats_df["day_nu"], + }, + errors="coerce", + ) stats_df = stats_df.sort_values(by=["month_nu", "day_nu"]) # Approximate day of year stats_df["day_of_year"] = stats_df["month_nu"] * 30 + stats_df["day_nu"] fig = go.Figure() - # Add percentile shaded regions with correct labels + # Percentile bands fig.add_trace( go.Scatter( - x=stats_df["day_of_year"], + x=stats_df["date"], y=stats_df["p95_va"], mode="lines", line=dict(color="lightblue"), @@ -85,17 +112,18 @@ def plot_flow_stats(stats_df, gage_id): ) fig.add_trace( go.Scatter( - x=stats_df["day_of_year"], + x=stats_df["date"], y=stats_df["p05_va"], mode="lines", line=dict(color="lightblue"), fill="tonexty", showlegend=False, + name="5th-95th Percentile", ) ) fig.add_trace( go.Scatter( - x=stats_df["day_of_year"], + x=stats_df["date"], y=stats_df["p90_va"], mode="lines", line=dict(color="blue"), @@ -104,17 +132,18 @@ def plot_flow_stats(stats_df, gage_id): ) fig.add_trace( go.Scatter( - x=stats_df["day_of_year"], + x=stats_df["date"], y=stats_df["p10_va"], mode="lines", line=dict(color="blue"), fill="tonexty", showlegend=False, + name="10th-90th Percentile", ) ) fig.add_trace( go.Scatter( - x=stats_df["day_of_year"], + x=stats_df["date"], y=stats_df["p75_va"], mode="lines", line=dict(color="darkblue"), @@ -123,29 +152,37 @@ def plot_flow_stats(stats_df, gage_id): ) fig.add_trace( go.Scatter( - x=stats_df["day_of_year"], + x=stats_df["date"], y=stats_df["p25_va"], mode="lines", line=dict(color="darkblue"), fill="tonexty", showlegend=False, + name="25th-75th Percentile", ) ) - # Add mean flow + + # Mean flow line fig.add_trace( go.Scatter( - x=stats_df["day_of_year"], + x=stats_df["date"], y=stats_df["mean_va"], mode="lines+markers", line=dict(color="black"), name="Mean Flow", ) ) + + # Format layout with month abbreviations fig.update_layout( title=f"{gage_id} | Daily Flow Statistics", - xaxis_title="Day of Year", + xaxis_title="Month", yaxis_title="Flow (cfs)", legend_title="Flow Statistics", + xaxis=dict( + tickformat="%b", # abbreviated month name + dtick="M1", # monthly ticks + ), ) return fig From b8037aab4c0674efea065ffe72bab390d9724773 Mon Sep 17 00:00:00 2001 From: sclaw Date: Fri, 2 May 2025 12:07:30 -0400 Subject: [PATCH 08/24] update changepoint ui --- hydroshift/_pages/changepoint.py | 72 +++++++++++++++++--------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/hydroshift/_pages/changepoint.py b/hydroshift/_pages/changepoint.py index 40438a3..bd4a671 100644 --- a/hydroshift/_pages/changepoint.py +++ b/hydroshift/_pages/changepoint.py @@ -298,42 +298,46 @@ def make_sidebar(): """User control for analysis.""" with st.sidebar: st.title("Settings") - st.session_state["gage_id"] = st.text_input( - "Enter USGS Gage Number:", st.session_state["gage_id"] - ) - st.session_state.gage = Gage(st.session_state["gage_id"]) - st.select_slider( - "False Positive Rate (1 in #)", - options=VALID_ARL0S, - value=1000, - key="arlo_slider", - label_visibility="visible", - ) + with st.form("changepoint_params"): + st.session_state["gage_id"] = st.text_input( + "Enter USGS Gage Number:", st.session_state["gage_id"] + ) + st.session_state.gage = Gage(st.session_state["gage_id"]) + st.select_slider( + "False Positive Rate (1 in #)", + options=VALID_ARL0S, + value=1000, + key="arlo_slider", + label_visibility="visible", + ) - st.number_input( - "Burn-in Period", - 0, - 100, - 20, - key="burn_in", - label_visibility="visible", - ) - st.text("Flood Frequency Analysis") - init_data = pd.DataFrame(columns=["Regime Start", "Regime End"]) - init_data["Regime Start"] = pd.to_datetime(init_data["Regime Start"]) - init_data["Regime End"] = pd.to_datetime(init_data["Regime End"]) - - start_config = st.column_config.DateColumn("Regime Start", format="D/M/YYYY") - end_config = st.column_config.DateColumn("Regime End", format="D/M/YYYY") - st.data_editor( - init_data, - num_rows="dynamic", - key="ffa_regimes", - column_config={"Regime Start": start_config, "Regime End": end_config}, - ) + st.number_input( + "Burn-in Period", + 0, + 100, + 20, + key="burn_in", + label_visibility="visible", + ) + st.text("Flood Frequency Analysis") + init_data = pd.DataFrame(columns=["Regime Start", "Regime End"]) + init_data["Regime Start"] = pd.to_datetime(init_data["Regime Start"]) + init_data["Regime End"] = pd.to_datetime(init_data["Regime End"]) + + start_config = st.column_config.DateColumn( + "Regime Start", format="D/M/YYYY" + ) + end_config = st.column_config.DateColumn("Regime End", format="D/M/YYYY") + st.data_editor( + init_data, + num_rows="dynamic", + key="ffa_regimes", + column_config={"Regime Start": start_config, "Regime End": end_config}, + ) + st.form_submit_button(label="Run Analysis") - st.divider() - write_template("footer.html") + st.divider() + write_template("data_sources_side_bar.html") def run_analysis(): From 3d8a2ec945af3f3cd5a032ab3df305b777ccfc8f Mon Sep 17 00:00:00 2001 From: sclaw Date: Fri, 2 May 2025 12:08:03 -0400 Subject: [PATCH 09/24] debug section_daily_mean --- hydroshift/_pages/summary.py | 1 - 1 file changed, 1 deletion(-) diff --git a/hydroshift/_pages/summary.py b/hydroshift/_pages/summary.py index 970559e..59caf23 100644 --- a/hydroshift/_pages/summary.py +++ b/hydroshift/_pages/summary.py @@ -96,7 +96,6 @@ def section_daily_mean(gage: Gage): end_date = st.date_input("End Date", value=date(2024, 12, 31)) data, missing_dates = gage.get_daily_values( - st.session_state["gage_id"], start_date.strftime("%Y-%m-%d"), end_date.strftime("%Y-%m-%d"), ) From 28711cc20f8fd7daa51a4209f4dfb700b887ec2f Mon Sep 17 00:00:00 2001 From: sclaw Date: Fri, 2 May 2025 13:28:50 -0400 Subject: [PATCH 10/24] debug changepoint ffa --- hydroshift/_pages/changepoint.py | 54 +++++++++++++++++++++----------- hydroshift/utils/ffa.py | 5 ++- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/hydroshift/_pages/changepoint.py b/hydroshift/_pages/changepoint.py index bd4a671..8f23cf6 100644 --- a/hydroshift/_pages/changepoint.py +++ b/hydroshift/_pages/changepoint.py @@ -1,6 +1,7 @@ """A tool to identify changepoints in hydrologic timeseries.""" import traceback +import uuid from collections import defaultdict from dataclasses import dataclass, field from io import BytesIO @@ -22,6 +23,7 @@ from hydroshift.utils.changepoint import cp_pvalue_batch, cpm_process_stream from hydroshift.utils.common import num_2_word from hydroshift.utils.data_retrieval import Gage +from hydroshift.utils.ffa import LP3Analysis from hydroshift.utils.jinja import render_template, write_template from hydroshift.utils.plots import combo_cpm, plot_lp3 @@ -294,15 +296,22 @@ def define_variables(): st.session_state.changepoint.validate_data() +def refresh_data_editor(): + """Set a new uuid for the data entry widget.""" + st.session_state.data_editor_key = str(uuid.uuid4()) + + def make_sidebar(): """User control for analysis.""" with st.sidebar: st.title("Settings") + st.session_state["gage_id"] = st.text_input( + "Enter USGS Gage Number:", + st.session_state["gage_id"], + on_change=refresh_data_editor, + ) + st.session_state.gage = Gage(st.session_state["gage_id"]) with st.form("changepoint_params"): - st.session_state["gage_id"] = st.text_input( - "Enter USGS Gage Number:", st.session_state["gage_id"] - ) - st.session_state.gage = Gage(st.session_state["gage_id"]) st.select_slider( "False Positive Rate (1 in #)", options=VALID_ARL0S, @@ -324,6 +333,9 @@ def make_sidebar(): init_data["Regime Start"] = pd.to_datetime(init_data["Regime Start"]) init_data["Regime End"] = pd.to_datetime(init_data["Regime End"]) + # Make data editor. Unique key allows for refreshing + if "data_editor_key" not in st.session_state: + refresh_data_editor() start_config = st.column_config.DateColumn( "Regime Start", format="D/M/YYYY" ) @@ -331,7 +343,7 @@ def make_sidebar(): st.data_editor( init_data, num_rows="dynamic", - key="ffa_regimes", + key=st.session_state.data_editor_key, column_config={"Regime Start": start_config, "Regime End": end_config}, ) st.form_submit_button(label="Run Analysis") @@ -376,21 +388,26 @@ def get_changepoints(data: pd.DataFrame, arl0: int, burn_in: int) -> dict: @st.cache_data def ffa_analysis(data: pd.DataFrame, regimes: list): """Run multiple flood frequency analyses for different regimes.""" - ffa_dict = {} + ffas = [] for r in regimes: if "Regime Start" in r and "Regime End" in r: sub = data.loc[r["Regime Start"] : r["Regime End"]].copy() - peaks = sub["peak_va"] - lp3 = log_pearson_iii(peaks) + peaks = sub["peak_va"].values label = f'{r["Regime Start"]} - {r["Regime End"]}' - ffa_dict[label] = {"peaks": sub, "lp3": lp3} - if len(ffa_dict) > 0: - ffa_plot = plot_lp3(ffa_dict, st.session_state.gage_id, multi_series=True) - ffa_df = pd.DataFrame.from_dict( - {k: ffa_dict[k]["lp3"] for k in ffa_dict}, orient="index" - ) - renames = {c: f"Q{c}" for c in ffa_df.columns} - ffa_df = ffa_df.rename(columns=renames) + lp3 = LP3Analysis( + st.session_state.gage_id, + peaks, + use_map_skew=False, + est_method="MOM", + label=label, + ) + ffas.append(lp3) + if len(ffas) > 0: + ffa_plot = plot_lp3(ffas) + ffa_df = ffas[0].quantile_df[["Recurrence Interval (years)"]] + ffa_df = ffa_df.set_index("Recurrence Interval (years)") + for i in ffas: + ffa_df[i.label] = i.quantile_df["Discharge (cfs)"].values return ffa_plot, ffa_df else: return None, None @@ -419,9 +436,10 @@ def make_body(): st.markdown(CP_T1_CAPTION) st.header("Modified flood frequency analysis") - if len(st.session_state.ffa_regimes["added_rows"]) > 0: + if len(st.session_state[st.session_state.data_editor_key]["added_rows"]) > 0: ffa_plot, ffa_df = ffa_analysis( - cpa.data, st.session_state.ffa_regimes["added_rows"] + cpa.gage.ams, + st.session_state[st.session_state.data_editor_key]["added_rows"], ) if ffa_plot is not None and ffa_df is not None: st.markdown(cpa.ffa_text) diff --git a/hydroshift/utils/ffa.py b/hydroshift/utils/ffa.py index e81e371..381b568 100644 --- a/hydroshift/utils/ffa.py +++ b/hydroshift/utils/ffa.py @@ -76,9 +76,8 @@ def ffa_quantiles(self) -> tuple[np.ndarray]: def quantile_df(self): """Put quantiles into a dataframe.""" _, qs = self.ffa_quantiles - return pd.DataFrame( - {"Recurrence Interval (years)": self.return_periods, "Discharge (cfs)": qs} - ) + ris = [str(i) for i in self.return_periods] + return pd.DataFrame({"Recurrence Interval (years)": ris, "Discharge (cfs)": qs}) @property def map_skew(self): From 231a2d7dd09b3672c6ddb739ac3c6fa4bfacd855 Mon Sep 17 00:00:00 2001 From: sclaw Date: Fri, 2 May 2025 13:29:49 -0400 Subject: [PATCH 11/24] update deps --- pyproject.toml | 2 ++ uv.lock | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 60c1f4d..38df551 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,7 @@ requires-python = ">=3.12" dependencies = [ "dataretrieval==1.0.11", "folium==0.19.4", + "jinja2>=3.1.6", "kaleido==0.2.0", "leafmap>=0.43.1", "matplotlib>=3.10.1", @@ -15,6 +16,7 @@ dependencies = [ "psutil>=7.0.0", "python-docx>=1.1.2", "radian>=0.6.13", + "rasterio>=1.4.3", "scipy==1.15.2", "streamlit==1.42.2", "streamlit-folium==0.24.0", diff --git a/uv.lock b/uv.lock index d78bcaf..db553f3 100644 --- a/uv.lock +++ b/uv.lock @@ -2,6 +2,15 @@ version = 1 revision = 1 requires-python = ">=3.12" +[[package]] +name = "affine" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/98/d2f0bb06385069e799fc7d2870d9e078cfa0fa396dc8a2b81227d0da08b9/affine-2.4.0.tar.gz", hash = "sha256:a24d818d6a836c131976d22f8c27b8d3ca32d0af64c1d8d29deb7bafa4da1eea", size = 17132 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/f7/85273299ab57117850cc0a936c64151171fac4da49bc6fba0dad984a7c5f/affine-2.4.0-py3-none-any.whl", hash = "sha256:8a3df80e2b2378aef598a83c1392efd47967afec4242021a0b06b4c7cbc61a92", size = 15662 }, +] + [[package]] name = "altair" version = "5.5.0" @@ -197,6 +206,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, ] +[[package]] +name = "click-plugins" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/1d/45434f64ed749540af821fd7e42b8e4d23ac04b1eda7c26613288d6cd8a8/click-plugins-1.1.1.tar.gz", hash = "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b", size = 8164 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/da/824b92d9942f4e472702488857914bdd50f73021efea15b4cad9aca8ecef/click_plugins-1.1.1-py2.py3-none-any.whl", hash = "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8", size = 7497 }, +] + +[[package]] +name = "cligj" +version = "0.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/0d/837dbd5d8430fd0f01ed72c4cfb2f548180f4c68c635df84ce87956cff32/cligj-0.7.2.tar.gz", hash = "sha256:a4bc13d623356b373c2c27c53dbd9c68cae5d526270bfa71f6c6fa69669c6b27", size = 9803 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/86/43fa9f15c5b9fb6e82620428827cd3c284aa933431405d1bcf5231ae3d3e/cligj-0.7.2-py3-none-any.whl", hash = "sha256:c1ca117dbce1fe20a5809dc96f01e1c2840f6dcc939b3ddbb1111bf330ba82df", size = 7069 }, +] + [[package]] name = "colorama" version = "0.4.6" @@ -437,6 +470,7 @@ source = { virtual = "." } dependencies = [ { name = "dataretrieval" }, { name = "folium" }, + { name = "jinja2" }, { name = "kaleido" }, { name = "leafmap" }, { name = "matplotlib" }, @@ -445,6 +479,7 @@ dependencies = [ { name = "psutil" }, { name = "python-docx" }, { name = "radian" }, + { name = "rasterio" }, { name = "scipy" }, { name = "streamlit" }, { name = "streamlit-folium" }, @@ -454,6 +489,7 @@ dependencies = [ requires-dist = [ { name = "dataretrieval", specifier = "==1.0.11" }, { name = "folium", specifier = "==0.19.4" }, + { name = "jinja2", specifier = ">=3.1.6" }, { name = "kaleido", specifier = "==0.2.0" }, { name = "leafmap", specifier = ">=0.43.1" }, { name = "matplotlib", specifier = ">=3.10.1" }, @@ -462,6 +498,7 @@ requires-dist = [ { name = "psutil", specifier = ">=7.0.0" }, { name = "python-docx", specifier = ">=1.1.2" }, { name = "radian", specifier = ">=0.6.13" }, + { name = "rasterio", specifier = ">=1.4.3" }, { name = "scipy", specifier = "==1.15.2" }, { name = "streamlit", specifier = "==1.42.2" }, { name = "streamlit-folium", specifier = "==0.24.0" }, @@ -1335,6 +1372,32 @@ dependencies = [ ] sdist = { url = "https://files.pythonhosted.org/packages/e1/3b/c5ff0d431ea2bf87646600ba75a3786836d85edd9e8da0f468a8d07ab8e4/radian-0.6.13.tar.gz", hash = "sha256:197da7c44c7f21ec6926ec2bb3223c968e833099725cf1a76d2aa80c0b0235b7", size = 53891 } +[[package]] +name = "rasterio" +version = "1.4.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "affine" }, + { name = "attrs" }, + { name = "certifi" }, + { name = "click" }, + { name = "click-plugins" }, + { name = "cligj" }, + { name = "numpy" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/19/ab4326e419b543da623ce4191f68e3f36a4d9adc64f3df5c78f044d8d9ca/rasterio-1.4.3.tar.gz", hash = "sha256:201f05dbc7c4739dacb2c78a1cf4e09c0b7265b0a4d16ccbd1753ce4f2af350a", size = 442990 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/f2/b7417292ceace70d815760f7e41fe5b0244ebff78ede11b1ffa9ca01c370/rasterio-1.4.3-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:e703e4b2c74c678786d5d110a3f30e26f3acfd65f09ccf35f69683a532f7a772", size = 21514543 }, + { url = "https://files.pythonhosted.org/packages/b2/ea/e21010457847b26bb4aea3983e9b44afbcefef07defc5e9a3285a8fe2f0c/rasterio-1.4.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:38a126f8dbf405cd3450b5bd10c6cc493a2e1be4cf83442d26f5e4f412372d36", size = 18735924 }, + { url = "https://files.pythonhosted.org/packages/67/72/331727423b28fffdfd8bf18bdc55c18d374c0fefd2dde390cd833f8f4477/rasterio-1.4.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e90c2c300294265c16becc9822337ded0f01fb8664500b4d77890d633d8cd0e", size = 22251721 }, + { url = "https://files.pythonhosted.org/packages/be/cc/453816b489af94b9a243eda889865973d518989ba6923b2381f6d6722b43/rasterio-1.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:a962ad4c29feaf38b1d7a94389313127de3646a5b9b734fbf9a04e16051a27ff", size = 25430154 }, + { url = "https://files.pythonhosted.org/packages/2e/e0/718c06b825d1f62077913e5bff1e70b71ac673718b135d55a0256d88d4ba/rasterio-1.4.3-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:5d4fcb635379b3d7b2f5e944c153849e3d27e93f35ad73ad4d3f0b8a580f0c8e", size = 21532284 }, + { url = "https://files.pythonhosted.org/packages/bb/a8/3b6b11923300d6835453d1157fabb518338067a67366c5c52e9df9a2314f/rasterio-1.4.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:98a9c89eade8c779e8ac1e525269faaa18c6b9818fc3c72cfc4627df71c66d0d", size = 18729960 }, + { url = "https://files.pythonhosted.org/packages/05/19/94d6c66184c7d0f9374330c714f62c147dbb53eda9efdcc8fc6e2ac454c5/rasterio-1.4.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9bab1a0bb22b8bed1db34b5258db93d790ed4e61ef21ac055a7c6933c8d5e84", size = 22237518 }, + { url = "https://files.pythonhosted.org/packages/df/88/9db5f49ebfdd9c12365e4cac76c34ccb1a642b1c8cbab4124b3c681495de/rasterio-1.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:1839960e2f3057a6daa323ccf67b330f8f2f0dbd4a50cc7031e88e649301c5c0", size = 25424949 }, +] + [[package]] name = "rchitect" version = "0.4.7" From af11cd98f0daa0e0849306a2541599f679de068f Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 15:49:29 +0000 Subject: [PATCH 12/24] add CI first draft --- .github/workflows/docker-build.yaml | 79 +++++++++++++++++++++++++++++ .github/workflows/get-version.yaml | 44 ++++++++++++++++ .github/workflows/main-push.yaml | 46 +++++++++++++++++ .github/workflows/pr-chaeck.yaml | 31 +++++++++++ hydroshift/__init__.py | 1 + 5 files changed, 201 insertions(+) create mode 100644 .github/workflows/docker-build.yaml create mode 100644 .github/workflows/get-version.yaml create mode 100644 .github/workflows/main-push.yaml create mode 100644 .github/workflows/pr-chaeck.yaml diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml new file mode 100644 index 0000000..aad3121 --- /dev/null +++ b/.github/workflows/docker-build.yaml @@ -0,0 +1,79 @@ +name: Docker Build + +on: + workflow_call: + inputs: + push_to_registry: + type: boolean + default: false + required: false + version: + type: string + required: true + branch: + type: string + required: true + platforms: + type: string + default: 'linux/amd64' + required: false + +permissions: + contents: read + packages: write + +jobs: + build-docker: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_NUMBER }}:role/${{ secrets.AWS_ROLE }} + role-session-name: updateimage + aws-region: ${{ secrets.AWS_REGION }} + + - name: Login to Amazon ECR + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + with: + registries: ${{ secrets.AWS_ACCOUNT_NUMBER }} + + - name: Set Docker tags based on branch + id: set_tags + env: + ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} + GH_REPO: ${{ github.repository }} + run: | + if [[ "${{ inputs.branch }}" == "main" ]]; then + echo "TAGS=$ECR_REGISTRY/$GH_REPO:latest,$ECR_REGISTRY/$GH_REPO:${{ inputs.version }}" >> $GITHUB_OUTPUT + else + echo "TAGS=$ECR_REGISTRY/$GH_REPO:pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT + fi + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GitHub Container Registry + if: inputs.push_to_registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + platforms: ${{ inputs.platforms }} + push: ${{ inputs.push_to_registry }} + tags: ${{ steps.set_tags.outputs.TAGS }} + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/.github/workflows/get-version.yaml b/.github/workflows/get-version.yaml new file mode 100644 index 0000000..952d9ae --- /dev/null +++ b/.github/workflows/get-version.yaml @@ -0,0 +1,44 @@ +name: Get Version + +on: + workflow_call: + outputs: + version: + description: "The version string extracted from hydroshift.__version__" + value: ${{ jobs.get-version.outputs.version }} + is_new_version: + description: "Whether this version is new (not previously tagged)" + value: ${{ jobs.get-version.outputs.is_new_version }} + +jobs: + get-version: + runs-on: ubuntu-latest + outputs: + version: ${{ steps.get_version.outputs.VERSION }} + is_new_version: ${{ steps.check_tag.outputs.IS_NEW_VERSION }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Extract version from hydroshift + id: get_version + run: | + VERSION=$(python -c "import hydroshift; print(hydroshift.__version__)") + echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" + + - name: Check if version exists as tag + id: check_tag + run: | + if git tag | grep -q "v${{ steps.get_version.outputs.VERSION }}"; then + echo "Version ${{ steps.get_version.outputs.VERSION }} already exists as a tag." + echo "IS_NEW_VERSION=false" >> "$GITHUB_OUTPUT" + else + echo "Version ${{ steps.get_version.outputs.VERSION }} does not exist as a tag." + echo "IS_NEW_VERSION=true" >> "$GITHUB_OUTPUT" + fi diff --git a/.github/workflows/main-push.yaml b/.github/workflows/main-push.yaml new file mode 100644 index 0000000..ed01b5d --- /dev/null +++ b/.github/workflows/main-push.yaml @@ -0,0 +1,46 @@ +name: Main Branch Push + +on: + push: + branches: [ "main" ] + paths: + - 'hydroshift/**' + - 'tests/**' + - '.devcontainer/Dockerfile' + - '.dockerignore' + - '.github/workflows/**' + - 'pyproject.toml' + workflow_dispatch: + +permissions: + contents: write + packages: write + +jobs: + get-version: + name: Extract Package Version + uses: ./.github/workflows/get-version.yaml + + check-version-exists: + name: Verify Version is New + needs: get-version + runs-on: ubuntu-latest + steps: + - name: Fail if version already exists + if: needs.get-version.outputs.is_new_version != 'true' + run: | + echo "::error::ERROR: Version ${{ needs.get-version.outputs.version }} already exists as a tag." + echo "::error::Please update the version in hydroshift/__init__.py before releasing to main." + exit 1 + - name: Version check passed + run: echo "Version ${{ needs.get-version.outputs.version }} is new. Proceeding with release." + + docker-build-push: + name: Build and Push Docker Image + needs: [get-version, check-version-exists] + uses: ./.github/workflows/docker-build.yaml + with: + push_to_registry: true + version: ${{ needs.get-version.outputs.version }} + branch: 'main' + platforms: 'linux/amd64' diff --git a/.github/workflows/pr-chaeck.yaml b/.github/workflows/pr-chaeck.yaml new file mode 100644 index 0000000..5de58e5 --- /dev/null +++ b/.github/workflows/pr-chaeck.yaml @@ -0,0 +1,31 @@ +name: PR Checks + +on: + pull_request: + branches: [ "main" ] + paths: + - 'hydroshift/**' + - 'tests/**' + - '/.devcontainer/Dockerfile' + - '.dockerignore' + - '.github/workflows/**' + - 'pyproject.toml' + +permissions: + contents: read + packages: write + +jobs: + get-version: + name: Extract Package Version + uses: ./.github/workflows/get-version.yaml + + docker-build-test: + name: Test Docker Build + needs: get-version + uses: ./.github/workflows/docker-build.yaml + with: + push_to_registry: false + version: ${{ needs.get-version.outputs.version }} + branch: ${{ github.base_ref }} + platforms: 'linux/amd64' diff --git a/hydroshift/__init__.py b/hydroshift/__init__.py index e69de29..3dc1f76 100644 --- a/hydroshift/__init__.py +++ b/hydroshift/__init__.py @@ -0,0 +1 @@ +__version__ = "0.1.0" From 704b101c6190326b36353bb38a38216be37c98a6 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 15:55:03 +0000 Subject: [PATCH 13/24] update CI --- .github/workflows/docker-build.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index aad3121..9dadfd6 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -60,14 +60,6 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Log in to GitHub Container Registry - if: inputs.push_to_registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build and push Docker image uses: docker/build-push-action@v5 with: From fbc91567a6115abf9d387b019ce3153baf8f9090 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 16:40:30 +0000 Subject: [PATCH 14/24] update ecr repo name --- .github/workflows/docker-build.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 9dadfd6..a748a65 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -46,12 +46,11 @@ jobs: id: set_tags env: ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }} - GH_REPO: ${{ github.repository }} run: | if [[ "${{ inputs.branch }}" == "main" ]]; then - echo "TAGS=$ECR_REGISTRY/$GH_REPO:latest,$ECR_REGISTRY/$GH_REPO:${{ inputs.version }}" >> $GITHUB_OUTPUT + echo "TAGS=$ECR_REGISTRY/hydroshift:latest,$ECR_REGISTRY/hydroshift:${{ inputs.version }}" >> $GITHUB_OUTPUT else - echo "TAGS=$ECR_REGISTRY/$GH_REPO:pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT + echo "TAGS=$ECR_REGISTRY/hydroshift:pr-${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT fi - name: Set up QEMU From c076709698249229f83a297ced8ed1eb02a8b5d6 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 17:03:47 +0000 Subject: [PATCH 15/24] update aws credential action version --- .github/workflows/docker-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index a748a65..9c9c01d 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -30,7 +30,7 @@ jobs: uses: actions/checkout@v4 - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v2 + uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_NUMBER }}:role/${{ secrets.AWS_ROLE }} role-session-name: updateimage From dab7ccd593617cb0ba2419657d4b34afd387b0e9 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 17:07:17 +0000 Subject: [PATCH 16/24] test hardcode region --- .github/workflows/docker-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 9c9c01d..112babb 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -34,7 +34,7 @@ jobs: with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_NUMBER }}:role/${{ secrets.AWS_ROLE }} role-session-name: updateimage - aws-region: ${{ secrets.AWS_REGION }} + aws-region: us-east-1 - name: Login to Amazon ECR id: login-ecr From a70a192c6aa6cd07885f31a92c71152d26717657 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 17:13:58 +0000 Subject: [PATCH 17/24] typo --- .github/workflows/{pr-chaeck.yaml => pr-check.yaml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{pr-chaeck.yaml => pr-check.yaml} (100%) diff --git a/.github/workflows/pr-chaeck.yaml b/.github/workflows/pr-check.yaml similarity index 100% rename from .github/workflows/pr-chaeck.yaml rename to .github/workflows/pr-check.yaml From ec179fdd253a6ffbb12b5f70d95d81136723caa0 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 17:14:49 +0000 Subject: [PATCH 18/24] add id-token permission to CI --- .github/workflows/docker-build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 112babb..13d2df9 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -21,6 +21,7 @@ on: permissions: contents: read packages: write + id-token: write jobs: build-docker: From 030af006621ee3a6250ece99a5815bf5df6096ba Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 17:21:34 +0000 Subject: [PATCH 19/24] add id-token permission to CI --- .github/workflows/main-push.yaml | 1 + .github/workflows/pr-check.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/main-push.yaml b/.github/workflows/main-push.yaml index ed01b5d..48f6820 100644 --- a/.github/workflows/main-push.yaml +++ b/.github/workflows/main-push.yaml @@ -15,6 +15,7 @@ on: permissions: contents: write packages: write + id-token: write jobs: get-version: diff --git a/.github/workflows/pr-check.yaml b/.github/workflows/pr-check.yaml index 5de58e5..569670c 100644 --- a/.github/workflows/pr-check.yaml +++ b/.github/workflows/pr-check.yaml @@ -14,6 +14,7 @@ on: permissions: contents: read packages: write + id-token: write jobs: get-version: From 7cb6b1d30f39473b7e5f8b9d0fe56414525963fb Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 18:38:58 +0000 Subject: [PATCH 20/24] trigger ci --- .github/workflows/docker-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 13d2df9..9b9fc12 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -35,7 +35,7 @@ jobs: with: role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_NUMBER }}:role/${{ secrets.AWS_ROLE }} role-session-name: updateimage - aws-region: us-east-1 + aws-region: ${{ secrets.AWS_REGION }} - name: Login to Amazon ECR id: login-ecr From 07a6db1e086007788668d78c90fa6cebfdafa0a6 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 18:41:29 +0000 Subject: [PATCH 21/24] add action read access --- .github/workflows/docker-build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 9b9fc12..e4a201b 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -22,6 +22,7 @@ permissions: contents: read packages: write id-token: write + actions: read jobs: build-docker: From 3dbe9c51260bb1fc004166d64e8338617578d47a Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 18:48:04 +0000 Subject: [PATCH 22/24] update secrets for CI --- .github/workflows/docker-build.yaml | 8 +++++++- .github/workflows/pr-check.yaml | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index e4a201b..745b79a 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -17,12 +17,18 @@ on: type: string default: 'linux/amd64' required: false + secrets: + AWS_ACCOUNT_NUMBER: + required: true + AWS_ROLE: + required: true + AWS_REGION: + required: true permissions: contents: read packages: write id-token: write - actions: read jobs: build-docker: diff --git a/.github/workflows/pr-check.yaml b/.github/workflows/pr-check.yaml index 569670c..e742487 100644 --- a/.github/workflows/pr-check.yaml +++ b/.github/workflows/pr-check.yaml @@ -30,3 +30,4 @@ jobs: version: ${{ needs.get-version.outputs.version }} branch: ${{ github.base_ref }} platforms: 'linux/amd64' + secrets: inherit From 7ae0a59a2daa733209198d5fb67432256c6810a5 Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 18:50:14 +0000 Subject: [PATCH 23/24] update context for dockerfile CI --- .github/workflows/docker-build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 745b79a..6c134aa 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -70,7 +70,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@v5 with: - context: . + context: ./.devcontainer platforms: ${{ inputs.platforms }} push: ${{ inputs.push_to_registry }} tags: ${{ steps.set_tags.outputs.TAGS }} From c6714fb1b8823c36b5532d2d72e837a9c967e99a Mon Sep 17 00:00:00 2001 From: sclaw Date: Tue, 20 May 2025 18:53:11 +0000 Subject: [PATCH 24/24] move dockerfile for context --- .github/workflows/docker-build.yaml | 2 +- .devcontainer/Dockerfile => Dockerfile | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename .devcontainer/Dockerfile => Dockerfile (100%) diff --git a/.github/workflows/docker-build.yaml b/.github/workflows/docker-build.yaml index 6c134aa..745b79a 100644 --- a/.github/workflows/docker-build.yaml +++ b/.github/workflows/docker-build.yaml @@ -70,7 +70,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@v5 with: - context: ./.devcontainer + context: . platforms: ${{ inputs.platforms }} push: ${{ inputs.push_to_registry }} tags: ${{ steps.set_tags.outputs.TAGS }} diff --git a/.devcontainer/Dockerfile b/Dockerfile similarity index 100% rename from .devcontainer/Dockerfile rename to Dockerfile