Skip to content

add and test warmup#422

Merged
barneydobson merged 12 commits intomainfrom
warmup
May 20, 2025
Merged

add and test warmup#422
barneydobson merged 12 commits intomainfrom
warmup

Conversation

@barneydobson
Copy link
Copy Markdown
Collaborator

@barneydobson barneydobson commented May 14, 2025

Description

SWMM models, especially ones that aren't entirely impervious, need time to warm up and stablilise - now a parameter than can be controlled.

Fixes # (issue)

Type of change

  • Documentation (non-breaking change that adds or improves the documentation)
  • New feature (non-breaking change which adds functionality)
  • Optimization (non-breaking, back-end change that speeds up the code)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (whatever its nature)

Key checklist

  • All tests pass (eg. python -m pytest)
  • The documentation builds and looks OK (eg. python -m sphinx -b html docs docs/build)
  • Pre-commit hooks run successfully (eg. pre-commit run --all-files)

Further checks

  • Code is commented, particularly in hard-to-understand areas
  • Tests added or an issue has been opened to tackle that in the future. (Indicate issue here: # (issue))

@barneydobson barneydobson requested a review from Copilot May 14, 2025 15:45
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces a warmup feature to the metric evaluation process by adding a new warmup parameter and its associated filtering logic, along with tests to verify its behavior.

  • Added a new test (test_apply_warmup) to validate the warmup functionality.
  • Introduced a "warmup" field in the parameters configuration with a defined range.
  • Implemented an apply_warmup function in metric_utilities.py and updated iterate_metrics to apply the warmup period when metric_evaluation is provided.

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tests/test_metric_utilities.py Added test case for verifying the warmup filtering logic
src/swmmanywhere/parameters.py Added a new warmup parameter; documentation and unit detail updated
src/swmmanywhere/metric_utilities.py Implemented the apply_warmup function and its integration in iterate_metrics

Comment thread src/swmmanywhere/parameters.py Outdated
Comment thread src/swmmanywhere/metric_utilities.py
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 15, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 88.13%. Comparing base (e39f8cb) to head (59f6d3b).
Report is 49 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #422      +/-   ##
==========================================
+ Coverage   88.10%   88.13%   +0.02%     
==========================================
  Files          23       23              
  Lines        2287     2292       +5     
  Branches      288      289       +1     
==========================================
+ Hits         2015     2020       +5     
  Misses        193      193              
  Partials       79       79              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@barneydobson barneydobson requested a review from cheginit May 15, 2025 09:37
Copy link
Copy Markdown
Collaborator

@cheginit cheginit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using a fractional warm-up period is technically fine, but modelers usually go with absolute times. We could just accept things like 1h, 1d, or 365 days, parse them with pd.to_timedelta and offset the start date. Feels more intuitive: results[results["date"] >= results["date"].min() + pd.to_timedelta(warmup)].

Comment thread src/swmmanywhere/metric_utilities.py
Comment thread src/swmmanywhere/parameters.py Outdated
@barneydobson
Copy link
Copy Markdown
Collaborator Author

Using a fractional warm-up period is technically fine, but modelers usually go with absolute times. We could just accept things like 1h, 1d, or 365 days, parse them with pd.to_timedelta and offset the start date. Feels more intuitive: results[results["date"] >= results["date"].min() + pd.to_timedelta(warmup)].

I see the point, even though I would always be using a fraction personally. I think we can stick with fraction for now - as validating the fraction is just baked into pydantic whereas validating the timedelta would be a bit more onerous (if we want to validate it when it is set - of course it can be validated easily in the apply_warmup function - but it's probably more useful to be validated before simulation), and allowing both will be fiddly.

@cheginit
Copy link
Copy Markdown
Collaborator

I'm ok with both. FYI, pydantic has a powerful validator functionality:

from pydantic import BaseModel, Field, model_validator
from typing import Self
import pandas as pd

class HydraulicDesign(BaseModel):
    warmup: str = Field(..., description="Warmup duration parseable by pd.to_timedelta")

    @model_validator(mode="after")
    def _check_warmup_format(self) -> Self:
        """Check if warmup can be parsed with pandas."""
        try:
            pd.to_timedelta(self.warmup)
        except Exception as e:
            raise ValueError("Failed to parse warmup with pd.to_timedelta.") from e
        return self

@cheginit
Copy link
Copy Markdown
Collaborator

Is warmup going to be used for computing metrics? Considering the issue that you raised about variable timesteps, having a test that applies to the actual usage of warmup is important.

@barneydobson
Copy link
Copy Markdown
Collaborator Author

Is warmup going to be used for computing metrics? Considering the issue that you raised about variable timesteps, having a test that applies to the actual usage of warmup is important.

Fair point!

@barneydobson
Copy link
Copy Markdown
Collaborator Author

barneydobson commented May 16, 2025

I'm ok with both. FYI, pydantic has a powerful validator functionality:

from pydantic import BaseModel, Field, model_validator
from typing import Self
import pandas as pd

class HydraulicDesign(BaseModel):
    warmup: str = Field(..., description="Warmup duration parseable by pd.to_timedelta")

    @model_validator(mode="after")
    def _check_warmup_format(self) -> Self:
        """Check if warmup can be parsed with pandas."""
        try:
            pd.to_timedelta(self.warmup)
        except Exception as e:
            raise ValueError("Failed to parse warmup with pd.to_timedelta.") from e
        return self

Ah that's neat - will look at in future (though in this case I meant validate that the warmup occurs within the simulation period - which is not off the top of my head calculated/specified until after the network is generated, and will change with #55 - which may conceivably be incorporated into #407 ).

@barneydobson barneydobson requested a review from cheginit May 16, 2025 15:20
@cheginit
Copy link
Copy Markdown
Collaborator

LGTM, thanks!

@barneydobson barneydobson merged commit 408122c into main May 20, 2025
5 checks passed
@barneydobson barneydobson deleted the warmup branch May 20, 2025 08:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants