diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index d6d1116..1fd9234 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -12,10 +12,10 @@ jobs: runs-on: ubuntu-latest if: ${{ github.event.workflow_run.conclusion == 'success' }} steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: 3.7 + python-version: 3.11 - run: pip install mkdocs mkdocs-material mkdocstrings[python] mkdocs-jupyter livereload - run: pip install . - run: mkdocs gh-deploy --force diff --git a/.github/workflows/os-tests.yml b/.github/workflows/os-tests.yml index 61ed54d..3acbda5 100644 --- a/.github/workflows/os-tests.yml +++ b/.github/workflows/os-tests.yml @@ -15,18 +15,17 @@ jobs: os: [macos-latest, windows-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + + - name: Install poetry + run: pipx install poetry - name: Set up Python ${{ env.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ env.python-version }} - cache: 'pip' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install pytest pytest-cov pytest-xdist + cache: 'poetry' + cache-dependency-path: "pyproject.toml" - name: Install windows geo dependencies if: matrix.os == 'windows-latest' @@ -42,10 +41,15 @@ jobs: pipwin install rtree pip install geopandas + - name: 'Install osx geo dependencies' + if: matrix.os == 'macos-latest' + run: | + brew install gdal + - name: Install package run: | - pip install . + poetry install - name: Run pytest run: | - pytest -n auto --cov --no-cov-on-fail --cov-report=term-missing:skip-covered --cov-report xml:coverage.xml + poetry run pytest -n auto --cov --no-cov-on-fail --cov-report=term-missing:skip-covered --cov-report xml:coverage.xml diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml index fe65402..5d07ded 100644 --- a/.github/workflows/run-pytest.yml +++ b/.github/workflows/run-pytest.yml @@ -11,19 +11,20 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.8", "3.9", "3.10", "3.11"] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + - name: Install poetry + run: pipx install poetry - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - cache: 'pip' + cache: 'poetry' + cache-dependency-path: "pyproject.toml" - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install pytest pytest-cov pytest-xdist - pip install . + poetry install - name: Run pytest run: | - pytest -n auto --cov --no-cov-on-fail --cov-report=term-missing:skip-covered --cov-report xml:coverage.xml + poetry run pytest -n auto --cov --no-cov-on-fail --cov-report=term-missing:skip-covered --cov-report xml:coverage.xml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 058266a..6dacbb2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,27 +1,27 @@ default_language_version: - python: python3.8 + python: python3.11 repos: - repo: https://github.com/ambv/black - rev: 23.1.0 + rev: 24.8.0 hooks: - id: black - args: ["elapid", "--line-length=120", "--target-version=py37"] + args: ["elapid", "--line-length=120"] - repo: https://github.com/pycqa/flake8 - rev: 6.0.0 + rev: 7.1.0 hooks: - id: flake8 args: ["--select=C,E,F,W,B,B950", "--max-line-length=120", "--ignore=E203,E501,W503,F401,F403"] - repo: https://github.com/timothycrosley/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort args: ["-l 120", "--profile", "black", "."] - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.6.0 hooks: - id: check-yaml exclude: recipe/meta.yaml diff --git a/MANIFEST.in b/MANIFEST.in index 0439384..724bd87 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,6 +1,6 @@ include LICENSE include README.md -include requirements.txt +include pyproject.toml recursive-exclude * __pycache__ recursive-exclude * *.py[co] diff --git a/Makefile b/Makefile index bf377a9..7a67d7c 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,6 @@ help: @echo "--- [ $(NAME) developer tools ] --- " @echo "" @echo "make init - initialize conda dev environment" - @echo "make utils - install convenient packages" @echo "make test - run package tests" @echo "make test-data - generates new data for tests/data/" @echo "make conda-clean - removes conda tempfiles" @@ -20,14 +19,9 @@ help: # utils init: - conda env list | grep -q ${NAME} || conda create --name=${NAME} python=3.8 mamba -y -c conda-forge - ${CONDA} mamba install gdal -c conda-forge -c nodefaults - ${CONDA} pip install pre-commit pytest pytest-xdist pytest-cov - ${CONDA} pre-commit install - ${CONDA} pip install -e . - -utils: - ${CONDA} pip install ipython jupyter matplotlib mkdocs-material mkdocstrings[python] mkdocs-jupyter + conda env list | grep -q ${NAME} || conda create --name=${NAME} python=3.11 mamba -y -c conda-forge -c nodefaults + ${CONDA} mamba install gdal poetry -c conda-forge -c nodefaults -y + ${CONDA} poetry install test: ${CONDA} pytest -n auto --cov --no-cov-on-fail --cov-report=term-missing:skip-covered diff --git a/elapid/__init__.py b/elapid/__init__.py index c7232a2..cf4968f 100644 --- a/elapid/__init__.py +++ b/elapid/__init__.py @@ -1,6 +1,5 @@ """User entrypoint to elapid""" -from elapid.__version__ import __doc__ as __version__ from elapid.features import ( CategoricalTransformer, HingeTransformer, @@ -27,3 +26,4 @@ from elapid.stats import normalize_sample_probabilities from elapid.train_test_split import BufferedLeaveOneOut, GeographicKFold, checkerboard_split from elapid.utils import download_sample_data, load_object, load_sample_data, save_object +from elapid.version import __version__ diff --git a/elapid/__version__.py b/elapid/__version__.py deleted file mode 100644 index 6c39a52..0000000 --- a/elapid/__version__.py +++ /dev/null @@ -1 +0,0 @@ -"1.0.1" diff --git a/elapid/config.py b/elapid/config.py index 1d4c348..87bc549 100644 --- a/elapid/config.py +++ b/elapid/config.py @@ -1,4 +1,5 @@ """SDM model configuration parameters.""" + from typing import Tuple, Union diff --git a/elapid/features.py b/elapid/features.py index ccfd13d..16299d3 100644 --- a/elapid/features.py +++ b/elapid/features.py @@ -349,13 +349,13 @@ def fit(self, x: ArrayLike) -> "CategoricalTransformer": self.estimators_ = [] x = np.array(x) if x.ndim == 1: - estimator = OneHotEncoder(dtype=np.uint8, sparse=False) + estimator = OneHotEncoder(dtype=np.uint8, sparse_output=False) self.estimators_.append(estimator.fit(x.reshape(-1, 1))) else: nrows, ncols = x.shape for col in range(ncols): xsub = x[:, col].reshape(-1, 1) - estimator = OneHotEncoder(dtype=np.uint8, sparse=False) + estimator = OneHotEncoder(dtype=np.uint8, sparse_output=False) self.estimators_.append(estimator.fit(xsub)) return self diff --git a/elapid/models.py b/elapid/models.py index 5f8009a..eda8488 100644 --- a/elapid/models.py +++ b/elapid/models.py @@ -1,4 +1,5 @@ """Classes for training species distribution models.""" + from typing import List, Tuple, Union import matplotlib.pyplot as plt @@ -20,7 +21,7 @@ compute_weights, ) from elapid.types import ArrayLike, validate_feature_types -from elapid.utils import NCPUS, make_band_labels, square_factor +from elapid.utils import NCPUS, make_band_labels # handle windows systems without functioning gfortran compilers FORCE_SKLEARN = False @@ -181,7 +182,7 @@ def partial_dependence_scores( ) mean[idx] = pd["individual"][0].mean(axis=0) stdv[idx] = pd["individual"][0].std(axis=0) - bins[idx] = pd["values"][0] + bins[idx] = pd["grid_values"][0] return bins, mean, stdv diff --git a/elapid/types.py b/elapid/types.py index 8f05f78..0ebb26c 100644 --- a/elapid/types.py +++ b/elapid/types.py @@ -1,4 +1,5 @@ """Custom maxent and typing data types.""" + from typing import Any, Union import geopandas as gpd diff --git a/elapid/utils.py b/elapid/utils.py index c4c9b4b..9dfef4b 100644 --- a/elapid/utils.py +++ b/elapid/utils.py @@ -5,7 +5,7 @@ import os import pickle import sys -from typing import Any, Callable, Dict, Iterable, List, Tuple, Union +from typing import Any, Callable, Dict, Iterable, List, Tuple from urllib import request import geopandas as gpd diff --git a/elapid/version.py b/elapid/version.py new file mode 100644 index 0000000..c1d20e7 --- /dev/null +++ b/elapid/version.py @@ -0,0 +1,3 @@ +import importlib.metadata + +__version__ = importlib.metadata.version(__package__) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1d0c01c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,42 @@ +[tool.poetry] +name = "elapid" +version = "1.0.2" +description = "Species distribution modeling tools" +authors = ["Christopher Anderson "] +license = "MIT" +readme = "README.md" +keywords = ["biogeography", "ecology", "maxent", "SDM", "species distribution modeling"] +include = [ + { path = "elapid/data/*", format = "sdist" } +] + +[tool.poetry.dependencies] +python = ">=3.8" +numpy = ">=1.18,<2.0" +pandas = ">=1.0.3" +pyproj = ">3.0" +geopandas = ">=0.7" +rasterio = ">=1.2.1" +tqdm = ">=4.60" +rtree = ">=0.9" +scikit-learn = ">=1.2" +matplotlib = ">=3.7" + +[tool.poetry.group.dev.dependencies] +descartes = ">=1.1" +pytest = ">=8.3" +pytest-xdist = ">=3.6" +pytest-cov = ">=5.0" +pre-commit = ">=3.0" +ipython = ">=8.0" +jupyter = ">=1.0" +mkdocs-material = ">=9.5" +mkdocstrings = {extras = ["python"], version = ">=0.25"} +mkdocs-jupyter = ">=0.24" + +[tool.poetry.extras] +glmnet = ["glmnet"] + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e798bdd..0000000 --- a/requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -descartes>=1.1.0 -geopandas>=0.7.0 -numpy>=1.18 -pandas>=1.0.3 -pyproj>=3.0 -rasterio>=1.2.1 -rtree>=0.9 -scikit-learn>=0.22.2 -shapely>=1.7.0 -tqdm>=4.60.0 diff --git a/setup.py b/setup.py deleted file mode 100644 index a157c02..0000000 --- a/setup.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -import platform - -from setuptools import setup - -this_dir, this_path = os.path.split(os.path.abspath(__file__)) -version = open(os.path.join(this_dir, "elapid", "__version__.py")).read().strip('"\n') -long_description = open(os.path.join(this_dir, "README.md"), "r", encoding="utf-8").read() -requirements = open(os.path.join(this_dir, "requirements.txt"), "r", encoding="utf-8").read().strip().split() - -setup_args = { - "name": "elapid", - "version": version, - "url": "https://elapid.org", - "license": "MIT", - "author": "Christopher Anderson", - "author_email": "cbanders@stanford.edu", - "description": "Species distribution modeling support tools", - "long_description": long_description, - "long_description_content_type": "text/markdown", - "keywords": [ - "biogeography", - "ecology", - "conservation", - "SDM", - "species distribution modeling", - "maxent", - ], - "packages": ["elapid"], - "include_package_data": True, - "data_files": [("elapid", ["elapid/data/bradypus.csv.gz"])], - "install_requires": requirements, - "extras_require": { - "glmnet": "glmnet", - }, - "python_requires": ">=3.7.0", - "platforms": "any", - "classifiers": [ - "Programming Language :: Python :: 3", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - ], -} - -setup(**setup_args)