From 42f2e8115078fd879825d3982fd9fd29ff236f9e Mon Sep 17 00:00:00 2001 From: Amy Defnet <74691675+amy-defnet@users.noreply.github.com> Date: Thu, 8 Jan 2026 14:30:00 -0500 Subject: [PATCH 1/2] remove sites with no conus i/j mapping (#13) --- pyproject.toml | 2 +- src/cssi_evaluation/model_evaluation.py | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2d46f15..ca4a381 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "cssi_evaluation" -version = "0.1.3" +version = "0.1.4" description = "Model evaluation functions for the CSSI project" readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE"} diff --git a/src/cssi_evaluation/model_evaluation.py b/src/cssi_evaluation/model_evaluation.py index 6daed4c..60c4fe2 100644 --- a/src/cssi_evaluation/model_evaluation.py +++ b/src/cssi_evaluation/model_evaluation.py @@ -224,6 +224,9 @@ def get_observations( grid_bounds=ij_bounds, ) + # Filter out observations that don't have {grid}_i and {grid}_j values + metadata_df = metadata_df.dropna(subset=[f"{grid}_i", f"{grid}_j"]) + # Shift i/j coordinates so that they index starting from the regional # bounding box origin instead of the overall CONUS grid origin if ij_bounds is not None: From 34f8ca8fe3329833b192bf29aeeffff2f275a194 Mon Sep 17 00:00:00 2001 From: Amy Defnet <74691675+amy-defnet@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:11:23 -0500 Subject: [PATCH 2/2] add github workflow for ci tests (#15) * add github workflow for ci tests * add hf-hydrodata public credentials * debug running tests --- .github/workflows/run-unit-tests.yaml | 56 +++++++++++++++++++ pyproject.toml | 2 +- src/cssi_evaluation/utils.py | 5 +- .../cssi_evaluation/test_model_evaluation.py | 6 +- utilities/set_test_credentials.py | 22 ++++++++ 5 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/run-unit-tests.yaml create mode 100644 utilities/set_test_credentials.py diff --git a/.github/workflows/run-unit-tests.yaml b/.github/workflows/run-unit-tests.yaml new file mode 100644 index 0000000..ce4ff39 --- /dev/null +++ b/.github/workflows/run-unit-tests.yaml @@ -0,0 +1,56 @@ +--- +name: Run Unit Tests + +on: + pull_request: + branches: [ main ] + types: [opened, synchronize, reopened, ready_for_review] + + push: + branches: [ main ] + +# Cancel older runs for the same PR to save minutes +concurrency: + group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + tests: + name: Unit tests + runs-on: ubuntu-latest + timeout-minutes: 20 + if: ${{ github.event.pull_request.draft == false || github.event_name == 'push' }} + + strategy: + fail-fast: false + matrix: + python-version: ['3.12'] + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + + - name: Install package and dependencies + run: | + python -m pip install --upgrade pip + pip install . --group test + + - name: Register hf-hydrodata credentials as a public user + env: + TEST_EMAIL_PUBLIC: ${{ secrets.TEST_EMAIL_PUBLIC }} + TEST_PIN_PUBLIC: ${{ secrets.TEST_PIN_PUBLIC }} + run: | + python utilities/set_test_credentials.py + + - name: Run unit tests + run: | + pytest --verbose diff --git a/pyproject.toml b/pyproject.toml index ca4a381..8384018 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "cssi_evaluation" -version = "0.1.4" +version = "0.1.5" description = "Model evaluation functions for the CSSI project" readme = {file = "README.md", content-type = "text/markdown"} license = {file = "LICENSE"} diff --git a/src/cssi_evaluation/utils.py b/src/cssi_evaluation/utils.py index a20bfc4..5637b04 100644 --- a/src/cssi_evaluation/utils.py +++ b/src/cssi_evaluation/utils.py @@ -185,6 +185,9 @@ def initialize_metrics_df(obs_metadata_df, metrics_list): ["site_id", "site_name", "latitude", "longitude", "domain_i", "domain_j"] ].copy() for m in metrics_list: - metrics_df[f"{m}"] = np.nan + if m == "condon": + metrics_df[f"{m}"] = "" + else: + metrics_df[f"{m}"] = np.nan return metrics_df diff --git a/tests/cssi_evaluation/test_model_evaluation.py b/tests/cssi_evaluation/test_model_evaluation.py index b6e42d8..f9f61db 100644 --- a/tests/cssi_evaluation/test_model_evaluation.py +++ b/tests/cssi_evaluation/test_model_evaluation.py @@ -27,7 +27,7 @@ def test_get_observations(): obs_metadata_df, obs_data_df = model_evaluation.get_observations( mask, ij_bounds, grid, start_date, end_date, variable, temporal_resolution ) - assert obs_metadata_df.shape == (14, 32) + assert obs_metadata_df.shape[0] == 14 assert obs_data_df.shape == (48, 15) assert "01447500" in obs_data_df.columns @@ -49,7 +49,7 @@ def test_get_observations_nan_filter_sites_removed(): mask, ij_bounds, grid, start_date, end_date, variable, temporal_resolution ) - assert obs_metadata_df.shape == (7, 32) + assert obs_metadata_df.shape[0] == 7 assert obs_data_df.shape == (5, 8) assert "01209500" not in obs_data_df.columns @@ -78,7 +78,7 @@ def test_get_observations_nan_filter_sites_included(): remove_sites_no_data=False, ) - assert obs_metadata_df.shape == (8, 32) + assert obs_metadata_df.shape[0] == 8 assert obs_data_df.shape == (5, 9) assert "01209500" in obs_data_df.columns diff --git a/utilities/set_test_credentials.py b/utilities/set_test_credentials.py new file mode 100644 index 0000000..df38e29 --- /dev/null +++ b/utilities/set_test_credentials.py @@ -0,0 +1,22 @@ +"""Set user credentials for hf_hydrodata package.""" + +# pylint: disable=C0413 + +import sys +import os + +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../src"))) +import hf_hydrodata as hf + + +def main(): + """Use environment variable secrets to set hf_hydrodata credentials + for GitHub Actions testing.""" + test_email = str(os.environ["TEST_EMAIL_PUBLIC"]) + test_pin = str(os.environ["TEST_PIN_PUBLIC"]) + + hf.register_api_pin(test_email, test_pin) + + +if __name__ == "__main__": + main()