[build-system]
build-backend = "hatchling.build"
requires = [ "hatchling" ]

[project]
name = "harpy-analysis"
version = "0.4.4"
description = "single-cell spatial omics analysis that makes you happy."
readme = "README.md"
requires-python = ">=3.12,<3.15"
license = { file = "LICENSE" }
authors = [
    { name = "Saeys Lab, VIB spatial catalyst" }
]

keywords = [
    "spatial-omics",
    "spatial-transcriptomics",
    "spatial-proteomics",
    "bioinformatics",
    "single-cell",
    "image-analysis",
    "spatialdata",
    "anndata",
    "scanpy",
    "scverse",
]

classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Science/Research",
    "Intended Audience :: Developers",
    "License :: Other/Proprietary License",
    "Operating System :: OS Independent",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3 :: Only",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
    "Programming Language :: Python :: 3.14",
    "Topic :: Scientific/Engineering :: Bio-Informatics",
    "Topic :: Scientific/Engineering :: Image Processing",
]

dependencies = [
    "spatialdata>=0.7.3",
    "distributed",
    "scanpy>=1.9.1",
    "scikit-learn>=1.3.1",
    "voronoi-diagram-for-polygons>=0.1.6",
    "zarr>=3.2.1",
    "tifffile>=2026.5.2",
    "rasterio>=1.3.2",
    "seaborn>=0.12.2",
    "leidenalg>=0.9.1",
    "ome_zarr>=0.14.0",
    "omegaconf",
    "pyrootutils",
    "universal_pathlib",
    "crick",
    "lazy-loader>=0.4",
    "spatialdata_io",
    "spatialdata-plot",
    "flowsom",
    # for debug logging
    "session-info2",
]

[project.optional-dependencies]
# additional models
cellpose = [
    "cellpose>=3.1.1.3,<5",
]
cellpose3 = [
    "cellpose>=3.1.1.3,<4",
]
cellpose4 = [
    "cellpose>=4,<5",
]
instanseg = [
    "instanseg-torch>=0.1.1",
]
# installation basicpy broken https://github.com/peng-lab/BaSiCPy/issues/162 fix:
#basic = [
#    "jax>=0.4.6,<=0.4.23; python_version <= '3.11'",
#    "jaxlib>=0.4.6,<=0.4.23; python_version <= '3.11'",
#    "basicpy==1.0.0; python_version <= '3.11'",
#    "numpy<2; python_version <= '3.11'",
#    # For more information, see https://basicpy.readthedocs.io/en/latest/installation.html
#]

opencv = [
    "opencv-python-headless",
]
# additional UI or CLI interfaces
napari = [
    "napari[all]>=0.4.18",
    "napari-spatialdata>=0.2.6",
    "napari-harpy>=0.0.11",
]
vitessce = [
    "harpy-vitessce ; python_version >= '3.12'"
]
cli = [
    "hydra-core>=1.2.0",
    "hydra-colorlog>=1.2.0",
    "submitit>=1.4.5",
    "hydra-submitit-launcher>=1.2.0"
]
notebook = [
    "ipywidgets",
    "tqdm",
    "bokeh",
    "textalloc",
    "joypy",
    "supervenn>=0.5.0",
    "nbconvert",
    "ipython",
]
# best default for end-users
extra = [
    # do not support basic tiling correction, and squidpy installation in default PyPI install
    "harpy-analysis[cellpose,instanseg,opencv,vitessce,cli,notebook]",
]
# dev dependencies
test = [
    "opencv-python-headless",
    "pytest",
    "pytest-cov",
    "tox",
]
docs = [
    "sphinx>=4.5",
    "sphinx-book-theme>=1.0.0",
    "sphinx_rtd_theme",
    "myst-nb",
    "sphinxcontrib-bibtex>=1.0.0",
    "sphinx-autodoc-typehints",
    "sphinx-design",
    "sphinx-copybutton",
]
benchmark =[
    "asv",
]
dev = [
    "pre-commit",
    "twine>=4.0.2",
    "harpy-analysis[extra,test,docs,benchmark]",
]

[project.urls]
Homepage = "https://github.com/saeyslab/harpy"
Documentation = "https://harpy.readthedocs.io/en/latest/"
Repository = "https://github.com/saeyslab/harpy"
Issues = "https://github.com/saeyslab/harpy/issues"
Changelog = "https://github.com/saeyslab/harpy/releases"
Paper = "https://doi.org/10.1093/bioinformatics/btag122"
SaeysLab = "https://saeyslab.sites.vib.be/en"
VIBSpatialCatalyst = "https://vib.be/en/technologies/technology-portfolio/spatial-catalyst"


[tool.uv]
# Override Cellpose 3.x's stale numpy<2.1 requirement. This keeps Python 3.13
# installs on pre-built numpy wheels while still allowing numpy to be bumped.
# Keep transitive numba new enough to import with the overridden numpy version.
override-dependencies = [
    "numpy>=2.4.6",
    "numba>=0.64.0",
]
required-environments = [
    "sys_platform == 'darwin' and platform_machine == 'arm64'",
    "sys_platform == 'linux' and platform_machine == 'x86_64'",
]
conflicts = [
    [
        { extra = "cellpose3" },
        { extra = "cellpose4" },
    ],
]

[tool.coverage.run]
source = ["harpy"]
omit = [
    "src/harpy/_tests/*",
    "experiments/*",
    "src/harpy/externals/*",
    "src/harpy/io/*",
    "src/harpy/pipeline.py",
    "docs/*",
]

[tool.ruff]
src = ["src"]
line-length = 120
select = [
    "F",  # Errors detected by Pyflakes
    "E",  # Error detected by Pycodestyle
    "W",  # Warning detected by Pycodestyle
    "I",  # isort
    "D",  # pydocstyle
    "B",  # flake8-bugbear
    "TID",  # flake8-tidy-imports
    "C4",  # flake8-comprehensions
    "BLE",  # flake8-blind-except
    "UP",  # pyupgrade
    "RUF100",  # Report unused noqa directives
]
ignore = [
    # line too long -> we accept long comment lines; formatter gets rid of long code lines
    "E501",
    # Do not assign a lambda expression, use a def -> lambda expression assignments are convenient
    "E731",
    # allow I, O, l as variable names -> I is the identity matrix
    "E741",
    # Missing docstring in public package
    "D104",
    # Missing docstring in public module
    "D100",
    # Missing docstring in __init__
    "D107",
    # Errors from function calls in argument defaults. These are fine when the result is immutable.
    "B008",
    # __magic__ methods are are often self-explanatory, allow missing docstrings
    "D105",
    # first line should end with a period [Bug: doesn't work with single-line docstrings]
    "D400",
    # First line should be in imperative mood; try rephrasing
    "D401",
    ## Disable one in each pair of mutually incompatible rules
    # We don’t want a blank line before a class docstring
    "D203",
    # We want docstrings to start immediately after the opening triple quote
    "D213",
]
extend-include = ["*.ipynb"]

[tool.hatch.build.targets.wheel]
packages = ["src/harpy"]

[tool.hatch.envs.default]
installer = "uv"
features = [ "dev" ]

[tool.hatch.envs.docs]
features = [ "dev" ]
scripts.build = "sphinx-build -M html docs docs/_build {args}"
scripts.open = "python -m webbrowser -t docs/_build/html/index.html"
scripts.clean = "git clean -fdX -- {args:docs}"

[tool.hatch.envs.hatch-test]
features = [ "dev" ]

[tool.ruff.pydocstyle]
convention = "numpy"

[tool.ruff.per-file-ignores]
"docs/*" = ["I"]
"**/_tests/*" = ["D"]
"*/__init__.py" = ["F401"]
"**/test_data/*" = ["ALL"]

[tool.pytest.ini_options]
testpaths = ['src/harpy/_tests']
xfail_strict = true
addopts = [
  "--import-mode=importlib", # allow using test files with same name
]
