Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", 3.13]

steps:
- uses: actions/checkout@v4
Expand All @@ -53,7 +53,7 @@ jobs:
fail-fast: false
max-parallel: 4
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", 3.13]

steps:
- uses: actions/checkout@v4
Expand All @@ -63,15 +63,16 @@ jobs:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
pip install -r requirements-dev.txt
pip install --upgrade pip
pip install -e ".[dev,examples]"
- name: Test with pytest
run: |
pytest tests --cov=pysensors --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
files: ./coverage.xml
- name: Execute feature notebook with papermill
run: |
pip install papermill
Expand All @@ -80,6 +81,6 @@ jobs:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements-dev.txt') }}
key: ${{ runner.os }}-pip-${{ hashFiles('**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pip-
4 changes: 3 additions & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ repos:
rev: 7.1.1
hooks:
- id: flake8
args: ["--config=setup.cfg"]
args:
- --max-line-length=88
- --extend-ignore=E203,F401
17 changes: 8 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Installation

Dependencies
^^^^^^^^^^^^
The high-level dependencies for PySensors are Linux or macOS and Python 3.9-3.12. ``pip`` is also recommended as is makes managing PySensors' other dependencies much easier. You can install it by following the instructions `here <https://packaging.python.org/tutorials/installing-packages/#ensure-you-can-run-pip-from-the-command-line>`__.
The requirements for PySensors are Linux or macOS and Python 3.10-3.13. ``pip`` is recommended as it makes managing PySensors' other dependencies much easier. You can install it by following the instructions `here <https://packaging.python.org/tutorials/installing-packages/#ensure-you-can-run-pip-from-the-command-line>`__.

PySensors has not been tested on Windows.

Expand Down Expand Up @@ -174,13 +174,12 @@ Then, to install the package, run
cd pysensors
pip install .

If you do not have pip you can instead use
If you do not have root access, you should add the ``--user`` option to the install command above.
If you want an editable install (recommended for development), run

.. code-block:: bash

python setup.py install

If you do not have root access, you should add the ``--user`` option to the ``install`` commands above.
pip install -e .


Features
Expand Down Expand Up @@ -213,11 +212,11 @@ Documentation
-------------
PySensors has a `documentation site <https://python-sensors.readthedocs.io/en/latest/index.html>`__ hosted by readthedocs.
Examples are available `online <https://python-sensors.readthedocs.io/en/latest/examples/index.html>`__, as static
`Jupyter notebooks <https://github.com/dynamicslab/pysensors/tree/master/examples>`__ and as `interactive notebooks <https://gesis.mybinder.org/binder/v2/gh/dynamicslab/pysensors/654e8144e44bcdc4e481b59a36c496033ef90bf6>`__. To run the example notebooks locally you should install the dependencies in ``requirements-examples.txt``:
`Jupyter notebooks <https://github.com/dynamicslab/pysensors/tree/master/examples>`__ and as `interactive notebooks <https://gesis.mybinder.org/binder/v2/gh/dynamicslab/pysensors/654e8144e44bcdc4e481b59a36c496033ef90bf6>`__. To run the example notebooks locally, you should install the examples dependencies:

.. code-block:: bash

pip install -r requirements-examples.txt
pip install -e ".[examples]"

Community guidelines
--------------------
Expand All @@ -233,11 +232,11 @@ your work!

Contributing code
^^^^^^^^^^^^^^^^^
We welcome contributions to PySensors. To contribute a new feature please submit a pull request. To get started we recommend installing the packages in ``requirements-dev.txt`` via
We welcome contributions to PySensors. To contribute a new feature please submit a pull request. To get started, we recommend installing the optional dev packages

.. code-block:: bash

pip install -r requirements-dev.txt
pip install -e ".[dev]"

This will allow you to run unit tests and automatically format your code. To be accepted your code should conform to PEP8 and pass all unit tests. Code can be tested by invoking

Expand Down
83 changes: 79 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,67 @@
[build-system]
requires = ["setuptools>=42", "wheel", "setuptools_scm[toml]>=3.4", "setuptools_scm_git_archive"]
build-backend = "setuptools.build_meta:__legacy__"
requires = [
"setuptools>=64",
"wheel",
"setuptools_scm[toml]>=8",
"setuptools_scm_git_archive",
]
build-backend = "setuptools.build_meta"

[tool.setuptools_scm]
write_to = "pysensors/version.py"
[project]
name = "python-sensors"
description = "Sparse Sensor Placement"
authors = [
{name="Brian de Silva", email="bdesilva@uw.edu"},
{name="Krithika Manohar", email="kmanohar@uw.edu"},
{name="Emily Clark", email="emily.e.clark93@gmail.com"},
]
license = {text = "MIT"}
requires-python = ">=3.10"
dynamic = ["version"]
classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Development Status :: 4 - Beta",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Topic :: Scientific/Engineering :: Mathematics",
]
readme = "README.rst"
dependencies = [
"scikit-learn",
"numpy>=2.0",
"matplotlib>=3.10",
"pandas",
"scipy"
]

[project.urls]
Homepage = "https://github.com/dynamicslab/pysensors"
Repository = "https://github.com/dynamicslab/pysensors"

[project.optional-dependencies]
dev = [
"pytest >=6.2.4, <8.0.0",
"pytest-cov",
"pytest-lazy-fixture",
"flake8-builtins-unleashed",
"codecov",
"sphinx >= 2",
"sphinxcontrib-apidoc",
"sphinx_rtd_theme",
"pre-commit",
"nbsphinx",
]
examples = [
"jupyter",
"matplotlib",
"netCDF4",
"notebook",
"seaborn",
]

[tool.black]
line-length = 88
Expand All @@ -21,4 +79,21 @@ exclude = '''
filterwarnings = [
"ignore::RuntimeWarning",
"ignore::UserWarning"
]

[tool.setuptools]
packages = { find = { exclude = ["tests", "examples"] } }

[tool.setuptools_scm]
write_to = "pysensors/version.py"

[tool.flake8]
exclude = [
".git",
".venv",
"dist",
"build",
"docs",
"examples",
"__pycache__",
]
15 changes: 0 additions & 15 deletions requirements-dev.txt

This file was deleted.

6 changes: 0 additions & 6 deletions requirements-examples.txt

This file was deleted.

5 changes: 0 additions & 5 deletions requirements.txt

This file was deleted.

20 changes: 0 additions & 20 deletions setup.cfg

This file was deleted.

51 changes: 0 additions & 51 deletions setup.py

This file was deleted.

32 changes: 20 additions & 12 deletions tests/utils/test_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -3580,11 +3580,15 @@ def test_draw_with_numpy_array_and_equation(self):
constraint = UserDefinedConstraints(
all_sensors=all_sensors, equation="x**2 + y**2 <= 4", data=sample_array
)
with patch(
"pysensors.utils._constraints.get_coordinates_from_indices"
) as mock_get_coords, patch("builtins.eval") as mock_eval, patch.object(
BaseConstraint, "get_functionalConstraind_sensors_indices"
) as mock_get_func:
with (
patch(
"pysensors.utils._constraints.get_coordinates_from_indices"
) as mock_get_coords,
patch("builtins.eval") as mock_eval,
patch.object(
BaseConstraint, "get_functionalConstraind_sensors_indices"
) as mock_get_func,
):
x_values = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
y_values = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
mock_get_coords.side_effect = [
Expand Down Expand Up @@ -3634,13 +3638,17 @@ def test_function(x, y):
all_sensors=all_sensors, file="test_constraint.py", data=sample_array
)
assert constraint.functions == test_function
with patch.object(
BaseConstraint, "functional_constraints"
) as mock_func_constr, patch.object(
BaseConstraint, "get_functionalConstraind_sensors_indices"
) as mock_get_func, patch(
"pysensors.utils._constraints.get_coordinates_from_indices"
) as mock_get_coords:
with (
patch.object(
BaseConstraint, "functional_constraints"
) as mock_func_constr,
patch.object(
BaseConstraint, "get_functionalConstraind_sensors_indices"
) as mock_get_func,
patch(
"pysensors.utils._constraints.get_coordinates_from_indices"
) as mock_get_coords,
):
mock_func_constr.return_value = np.array([1.5, -0.5, 0.8, -1.2, 2.3])
mock_get_func.return_value = (np.array([0, 2, 4]), np.array([0, 1, 2]))
mock_get_coords.return_value = (
Expand Down