diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 84ffca5d8..5821d4f5c 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -27,4 +27,4 @@ body: id: context attributes: label: Additional context - description: Add any additional context about the feature request. \ No newline at end of file + description: Add any additional context about the feature request. diff --git a/.github/workflows/release-action.yaml b/.github/workflows/release-action.yaml index 8bfa74f15..c2cd834b2 100644 --- a/.github/workflows/release-action.yaml +++ b/.github/workflows/release-action.yaml @@ -36,7 +36,7 @@ jobs: runs-on: ubuntu-latest environment: name: pypi - url: https://pypi.org/p/pybop + url: https://pypi.org/p/pybop permissions: id-token: write # IMPORTANT: mandatory for trusted publishing @@ -107,4 +107,4 @@ jobs: - name: Publish distribution 📦 to TestPyPI uses: pypa/gh-action-pypi-publish@release/v1 with: - repository-url: https://test.pypi.org/legacy/ \ No newline at end of file + repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/test_on_push.yaml b/.github/workflows/test_on_push.yaml index 02c71bcdd..959e4c826 100644 --- a/.github/workflows/test_on_push.yaml +++ b/.github/workflows/test_on_push.yaml @@ -14,6 +14,21 @@ concurrency: cancel-in-progress: true jobs: + style: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: 3.11 + + - name: Check formatting with pre-commit + run: | + python -m pip install pre-commit + pre-commit run ruff + + build: runs-on: ubuntu-latest strategy: @@ -61,4 +76,4 @@ jobs: - name: Upload coverage report uses: codecov/codecov-action@v3 env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 000000000..9791b659e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,37 @@ +ci: + autoupdate_commit_msg: "chore: update pre-commit hooks" + autofix_commit_msg: "style: pre-commit fixes" + +repos: + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.0.292" + hooks: + - id: ruff + args: [--fix, --ignore=E741, --exclude=__init__.py] + + - repo: https://github.com/nbQA-dev/nbQA + rev: 1.7.0 + hooks: + - id: nbqa-ruff + additional_dependencies: [ruff==0.0.284] + args: ["--fix","--ignore=E501,E402"] + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.4.0 + hooks: + - id: check-added-large-files + - id: check-case-conflict + - id: check-merge-conflict + - id: check-yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + - id: trailing-whitespace + + - repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.10.0 + hooks: + - id: python-check-blanket-type-ignore + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 30d2fe59f..f65361cd2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,6 +8,22 @@ Before you commit any code, please perform the following checks: - [All tests pass](#testing): `$ nox -s unit_test` +### Installing and using pre-commit + +`PyBOP` uses a set of `pre-commit` hooks and the `pre-commit` bot to format and prettify the codebase. The hooks can be installed locally using - + +```bash +pip install pre-commit +pre-commit install +``` + +This would run the checks every time a commit is created locally. The checks will only run on the files modified by that commit, but the checks can be triggered for all the files using - + +```bash +pre-commit run --all-files +``` + +If you would like to skip the failing checks and push the code for further discussion, use the `--no-verify` option with `git commit`. ## Workflow @@ -279,4 +295,4 @@ GitHub does some magic with particular filenames. In particular: ## Acknowledgements This CONTRIBUTING.md file, along with large sections of the code infrastructure, -was copied from the excellent [Pints repo](https://github.com/pints-team/pints), and [PyBaMM repo](https://github.com/pybamm-team/PyBaMM) \ No newline at end of file +was copied from the excellent [Pints repo](https://github.com/pints-team/pints), and [PyBaMM repo](https://github.com/pybamm-team/PyBaMM) diff --git a/README.md b/README.md index 9b4f4a267..cf39db405 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ def getdata(x0): x0 = np.array([0.55, 0.63]) solution = getdata(x0) ``` -Next, the observed variables are defined, with the model construction and parameter definitions following. Finally, the parameterisation class is constructed and parameter fitting is completed. +Next, the observed variables are defined, with the model construction and parameter definitions following. Finally, the parameterisation class is constructed and parameter fitting is completed. ```python observations = [ pybop.Observed("Time [s]", solution["Time [s]"].data), @@ -197,7 +197,7 @@ learning from the success of the [PyBaMM](https://pybamm.org/) community. Our va - Inclusivity and fairness (those who want to contribute may do so, and their input is appropriately recognised) -- Inter-operability (aiming for modularity to enable maximum impact and inclusivity) +- Interoperability (aiming for modularity to enable maximum impact and inclusivity) - User-friendliness (putting user requirements first, thinking about user-assistance & workflows) @@ -226,4 +226,4 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d -This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specifications. Contributions of any kind are welcome! See `contributing.md` for ways to get started. \ No newline at end of file +This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specifications. Contributions of any kind are welcome! See `contributing.md` for ways to get started. diff --git a/examples/notebooks/rmse-estimisation.ipynb b/examples/notebooks/rmse-estimisation.ipynb index c4104d7be..ff7b47771 100644 --- a/examples/notebooks/rmse-estimisation.ipynb +++ b/examples/notebooks/rmse-estimisation.ipynb @@ -220,7 +220,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Next, we define the targetted forward model parameters for estimation. Furthermore, PyBOP provides functionality to define a prior for the parameters. The initial parameters values used in the estimiation will be randomly drawn from the prior distribution." + "Next, we define the targeted forward model parameters for estimation. Furthermore, PyBOP provides functionality to define a prior for the parameters. The initial parameters values used in the estimiation will be randomly drawn from the prior distribution." ] }, { diff --git a/tests/unit/test_parameterisations.py b/tests/unit/test_parameterisations.py index b542b0c96..047e41847 100644 --- a/tests/unit/test_parameterisations.py +++ b/tests/unit/test_parameterisations.py @@ -118,4 +118,34 @@ def getdata(self, model, x0): sim = model.predict(experiment=experiment) return sim + @pytest.mark.unit + def test_simulate_without_build_model(self): + # Define model + model = pybop.lithium_ion.SPM() + with pytest.raises( + ValueError, match="Model must be built before calling simulate" + ): + model.simulate(None, None) + + @pytest.mark.unit + def test_priors(self): + # Tests priors + Gaussian = pybop.Gaussian(0.5, 1) + Uniform = pybop.Uniform(0, 1) + Exponential = pybop.Exponential(1) + + np.testing.assert_allclose(Gaussian.pdf(0.5), 0.3989422804014327, atol=1e-4) + np.testing.assert_allclose(Uniform.pdf(0.5), 1, atol=1e-4) + np.testing.assert_allclose(Exponential.pdf(1), 0.36787944117144233, atol=1e-4) + + @pytest.mark.unit + def test_parameter_set(self): + # Tests parameter set creation + with pytest.raises(ValueError): + pybop.ParameterSet("pybamms", "Chen2020") + + parameter_test = pybop.ParameterSet("pybamm", "Chen2020") + np.testing.assert_allclose( + parameter_test["Negative electrode active material volume fraction"], 0.75 + )