Skip to content

Commit ec93a05

Browse files
committed
Merge branch 'pydantic_calibration_cal_refractor'
2 parents ca82350 + 14f5549 commit ec93a05

33 files changed

Lines changed: 2257 additions & 2630 deletions

.github/workflows/build-check.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Build and Validate
2+
3+
on:
4+
push:
5+
paths:
6+
- "pyproject.toml"
7+
pull_request:
8+
paths:
9+
- "pyproject.toml"
10+
11+
jobs:
12+
build-and-validate:
13+
runs-on: ubuntu-latest
14+
15+
strategy:
16+
matrix:
17+
python-version: ["3.10", "3.11", "3.12", "3.13"]
18+
19+
steps:
20+
- name: Checkout repository
21+
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0 # needed for setuptools-scm
24+
25+
- name: Set up Python ${{ matrix.python-version }}
26+
uses: actions/setup-python@v5
27+
with:
28+
python-version: ${{ matrix.python-version }}
29+
30+
- name: Upgrade pip and install build tools
31+
run: |
32+
python -m pip install --upgrade pip
33+
pip install build setuptools-scm wheel twine
34+
35+
- name: Build distributions
36+
run: python -m build --sdist --wheel
37+
38+
- name: List dist/
39+
run: ls -l dist/
40+
41+
- name: Validate distributions with twine
42+
run: twine check dist/*
43+
44+
- name: Test install wheel
45+
run: |
46+
python -m venv venv_test
47+
source venv_test/bin/activate
48+
pip install dist/*.whl
49+
python -c "import pySWATPlus; print(pySWATPlus.__version__)"
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,39 @@
1-
name: docs
2-
3-
on:
4-
push:
5-
branches:
6-
- main # Trigger when pushing to the main branch
7-
paths:
8-
- '**/*.py' # Any Python file anywhere in the repo
9-
- 'docs/**' # Any file inside the docs folder
10-
11-
jobs:
12-
deploy-docs:
13-
runs-on: ubuntu-latest
14-
15-
permissions:
16-
contents: write # Allow pushing to the repository
17-
18-
steps:
19-
- name: Checkout repository
20-
uses: actions/checkout@v4
21-
22-
- name: Set up Python
23-
uses: actions/setup-python@v4
24-
with:
25-
python-version: '3.x'
26-
27-
- name: Install MkDocs and dependencies
28-
run: |
29-
pip install -r docs/requirements-docs.txt
30-
31-
- name: Build MkDocs documentation
32-
run: |
33-
mkdocs build --site-dir public
34-
35-
- name: Deploy to GitHub Pages
36-
uses: peaceiris/actions-gh-pages@v3
37-
with:
38-
github_token: ${{ secrets.GITHUB_TOKEN }}
1+
name: docs
2+
3+
on:
4+
push:
5+
branches:
6+
- main # Trigger when pushing to the main branch
7+
paths:
8+
- '**/*.py' # Any Python file anywhere in the repo
9+
- 'docs/**' # Any file inside the docs folder
10+
11+
jobs:
12+
deploy-docs:
13+
runs-on: ubuntu-latest
14+
15+
permissions:
16+
contents: write # Allow pushing to the repository
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v4
24+
with:
25+
python-version: '3.x'
26+
27+
- name: Install MkDocs and dependencies
28+
run: |
29+
pip install -r docs/requirements-docs.txt
30+
31+
- name: Build MkDocs documentation
32+
run: |
33+
mkdocs build --site-dir public
34+
35+
- name: Deploy to GitHub Pages
36+
uses: peaceiris/actions-gh-pages@v3
37+
with:
38+
github_token: ${{ secrets.GITHUB_TOKEN }}
3939
publish_dir: ./public
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,53 @@
1-
name: Publish to PyPI and GitHub Release
2-
3-
on:
4-
push:
5-
tags:
6-
- "v*" # Only trigger when pushing a version tag like v1.2.3
7-
8-
jobs:
9-
build-and-publish:
10-
runs-on: ubuntu-latest
11-
12-
permissions:
13-
contents: write # Required to create a release
14-
15-
steps:
16-
- name: Checkout repository
17-
uses: actions/checkout@v4
18-
with:
19-
fetch-depth: 0 # Ensure full Git history for setuptools-scm
20-
21-
- name: Set up Python
22-
uses: actions/setup-python@v4
23-
with:
24-
python-version: '3.x'
25-
26-
- name: Install dependencies
27-
run: |
28-
python -m pip install --upgrade pip
29-
pip install build twine setuptools-scm
30-
31-
- name: Verify version from tag
32-
id: get_version
33-
run: |
34-
TAG_VERSION=${GITHUB_REF#refs/tags/v} # Extract version from 'vX.Y.Z'
35-
echo "VERSION=$TAG_VERSION" >> $GITHUB_ENV
36-
echo "Publishing version: $TAG_VERSION"
37-
38-
- name: Build package (pyproject.toml)
39-
run: python -m build
40-
41-
- name: Publish to PyPI
42-
env:
43-
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
44-
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
45-
run: |
46-
twine upload dist/*
47-
48-
- name: Create GitHub Release
49-
env:
50-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51-
run: |
52-
gh release create ${{ github.ref_name }} dist/* --title "Release ${{ github.ref_name }}" --notes "Automated release for version ${{ github.ref_name }}"
53-
54-
55-
deploy-docs:
56-
runs-on: ubuntu-latest
57-
58-
permissions:
59-
contents: write # Allow pushing to the repository
60-
61-
needs: build-and-publish # Ensure this runs after the build-and-publish job
62-
steps:
63-
- name: Checkout repository
64-
uses: actions/checkout@v4
65-
66-
- name: Set up Python
67-
uses: actions/setup-python@v4
68-
with:
69-
python-version: '3.x'
70-
71-
- name: Install MkDocs and dependencies
72-
run: |
73-
pip install mkdocs mkdocs-material mkdocstrings mkdocstrings-python mkdocs-jupyter pymdown-extensions
74-
75-
- name: Build MkDocs documentation
76-
run: |
77-
mkdocs build --site-dir public
78-
79-
- name: Deploy to GitHub Pages
80-
uses: peaceiris/actions-gh-pages@v3
81-
with:
82-
github_token: ${{ secrets.GITHUB_TOKEN }}
83-
publish_dir: ./public
1+
name: dist
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*" # Only trigger when pushing a version tag like v1.2.3
7+
8+
jobs:
9+
build-and-publish:
10+
runs-on: ubuntu-latest
11+
12+
permissions:
13+
contents: write # Required to create a release
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0 # Ensure full Git history for setuptools-scm
20+
fetch-tags: true
21+
22+
- name: Set up Python
23+
uses: actions/setup-python@v4
24+
with:
25+
python-version: '3.x'
26+
27+
- name: Install dependencies
28+
run: |
29+
python -m pip install --upgrade pip
30+
pip install build twine setuptools-scm
31+
32+
- name: Verify version from tag
33+
id: get_version
34+
run: |
35+
TAG_VERSION=${GITHUB_REF#refs/tags/v} # Extract version from 'vX.Y.Z'
36+
echo "VERSION=$TAG_VERSION" >> $GITHUB_ENV
37+
echo "Publishing version: $TAG_VERSION"
38+
39+
- name: Build package (pyproject.toml)
40+
run: python -m build
41+
42+
- name: Publish to PyPI
43+
env:
44+
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
45+
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
46+
run: |
47+
twine upload dist/*
48+
49+
- name: Create GitHub Release
50+
env:
51+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
52+
run: |
53+
gh release create ${{ github.ref_name }} dist/* --title "Release ${{ github.ref_name }}" --notes "Automated release for version ${{ github.ref_name }}"

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ All contributions, whether large or small, are valuable.
1414

1515
## Guidelines
1616

17-
Please review the [Contributing Guide](https://swat-model.github.io/pySWATPlus/CONTRIBUTING) for detailed instructions on how to get started.
17+
Please review the [Contributing Guidelines](https://swat-model.github.io/pySWATPlus/CONTRIBUTING) for detailed instructions on how to get started.
1818

1919
## Code of Conduct
2020
As a contributor, you are expected to adhere to our [Code of Conduct](https://github.com/swat-model/pySWATPlus/blob/main/CODE_OF_CONDUCT.md) to ensure a welcoming and inclusive community.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
![GitHub commit activity](https://img.shields.io/github/commit-activity/t/swat-model/pySWATPlus)
1515

1616

17-
[![docs](https://github.com/swat-model/pySWATPlus/actions/workflows/deploy-docs.yml/badge.svg)](https://github.com/swat-model/pySWATPlus/actions/workflows/deploy-docs.yml)
17+
[![docs](https://github.com/swat-model/pySWATPlus/actions/workflows/documenting.yml/badge.svg)](https://github.com/swat-model/pySWATPlus/actions/workflows/documenting.yml)
1818
[![flake8](https://github.com/swat-model/pySWATPlus/actions/workflows/linting.yml/badge.svg)](https://github.com/swat-model/pySWATPlus/actions/workflows/linting.yml)
1919
[![mypy](https://github.com/swat-model/pySWATPlus/actions/workflows/typing.yml/badge.svg)](https://github.com/swat-model/pySWATPlus/actions/workflows/typing.yml)
2020
[![pytest](https://github.com/swat-model/pySWATPlus/actions/workflows/testing.yml/badge.svg)](https://github.com/swat-model/pySWATPlus/actions/workflows/testing.yml)

docs/api/performance_metrics.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
::: pySWATPlus.PerformanceMetrics
2+

docs/api/types.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
::: pySWATPlus.types.ParamChange
1+
::: pySWATPlus.types.ParametersType
22

3-
::: pySWATPlus.types.ParamSpec
4-
5-
::: pySWATPlus.types.FileParams
6-
7-
::: pySWATPlus.types.ParamsType
3+
::: pySWATPlus.types.ParametersBoundedType

docs/changelog.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,22 @@
33

44
## Version 1.1.0 (August 26, 2025)
55

6-
- Introduced `SensitivityAnalyzer` class for sensitivity analysis of SWAT+ model parameters.
6+
- Added a new class `pySWATPlus.SensitivityAnalyzer` to support sensitivity simulations with two main methods:
77

8-
- Added high-level method `simulation_by_sobol_sample` in `SensitivityAnalyzer` to automate the sensitivity simulation workflow using Sobol samples.
8+
- `simulated_timeseries_df`: Generates a time series `DataFrame` directly from a simulation output file.
9+
- `simulation_by_sobol_sample`: Provides a high-level interface for running sensitivity simulations with parallel computing and extracting results from multiple output files.
10+
11+
- Changes in `pySWATPlus.TxtinoutReader` class:
12+
13+
- `copy_required_files`: New method to copy required files into a separate directory before running simulations. This protects the main `TxtInOut` folder and enables safer, more controlled workflows.
14+
- `run_swat_in_other_dir`: Enhanced with new optional parameters, allowing users to configure all necessary inputs in a single call for improved usability.
15+
16+
- The `has_units` input parameter, which specifies whether the third line of `SWAT+` input or output files contains column units, is now **mandatory** across the `pySWATPlus` package (previously optional) to ensure consistent file handling.
17+
18+
- Added [Contributing Guidelines](https://swat-model.github.io/pySWATPlus/CONTRIBUTING) with clear instructions for setting up the development environment, reporting issues, and submitting contributions.
19+
20+
- Added [Code of Conduct](https://github.com/swat-model/pySWATPlus/blob/main/CODE_OF_CONDUCT.md) to define standards for a welcoming, respectful, and inclusive community.
921

10-
- Updated `run_swat_in_other_dir` method in `TxtinoutReader` to support additional input variables, enabling SWAT+ simulation through a single interface.
11-
1222

1323
## Version 1.0.3 (July 30, 2025)
1424

docs/userguide/read_output.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ It covers accessing results from both standard simulations and Sobol-based sensi
1010
A standard `SWAT+` simulation generates TXT files with time series columns: `day`, `mon`, and `yr` for day, month, and year, respectively. To create a time series `DataFrame` that includes a new `date` column with `datetime.date` objects. Additionally, the method can optionally save the resulting DataFrame to a JSON file. This is controlled by the parameters `save_df` and `json_file`: setting `save_df=True` enables the saving process, and `json_file` specifies the path where the DataFrame will be written.
1111

1212
```python
13-
output = pySWATPlus.SensitivityAnalyzer().simulated_timeseries_df(
13+
output = pySWATPlus.SensitivityAnalyzer.simulated_timeseries_df(
1414
data_file=r"C:\Users\Username\simulation_folder_2\channel_sd_mon.txt",
1515
has_units=True,
1616
start_date='2014-06-01',

docs/userguide/sensitivity_analysis.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ if __name__ == '__main__':
216216
}
217217
}
218218
# Sensitive simulation
219-
output = pySWATPlus.SensitivityAnalyzer().simulation_by_sobol_sample(
219+
output = pySWATPlus.SensitivityAnalyzer.simulation_by_sobol_sample(
220220
var_names=var_names,
221221
var_bounds=var_bounds,
222222
sample_number=1,

0 commit comments

Comments
 (0)