-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
217 lines (201 loc) · 7.99 KB
/
Copy pathpyproject.toml
File metadata and controls
217 lines (201 loc) · 7.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
[project]
name = "minisim"
dynamic = ["version"]
description = "Physically-driven synthetic 1-photon miniscope data: a forward-model generator and teaching tool, the inverse of the minian analysis pipeline."
authors = [
{name = "Daniel Aharoni", email = "[email protected]"},
]
dependencies = [
"numpy>=1.20.2",
"numpydantic>=1.8",
# opencv (headless: no GUI libs) backs the brain-motion warp via cv2.warpAffine,
# ~4x faster than scipy.ndimage.shift for the rigid sub-pixel shift, and is the
# single shift implementation so a recording is reproducible across environments.
# It also bundles its own ffmpeg, so it can own video output (dropping the mediapy
# + system-ffmpeg requirement) -- a tracked follow-up.
"opencv-python-headless>=4.6",
"pydantic>=2",
"scipy>=1.4.1",
"xarray>=0.17.0",
# recording.py uses the zarr v2 group API (`create_dataset`), removed in
# zarr 3. Pinned to v2 to match minian; porting the cache I/O to the zarr 3
# store/array API is a tracked follow-up.
"zarr>=2.18,<3",
]
requires-python = ">=3.10"
readme = "README.md"
license = "GPL-3.0-or-later"
license-files = ["LICENSE"]
keywords = [
"calcium-imaging",
"miniscope",
"neuroscience",
"simulation",
"synthetic-data",
"benchmarking",
]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"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",
]
[project.scripts]
# Copy the bundled teaching notebooks out to a writable directory.
minisim-notebooks = "minisim.notebooks:main"
[project.urls]
Homepage = "https://github.com/miniscope/minisim"
Documentation = "https://minisim.readthedocs.io/"
Repository = "https://github.com/miniscope/minisim"
Issues = "https://github.com/miniscope/minisim/issues"
Changelog = "https://github.com/miniscope/minisim/blob/main/CHANGELOG.md"
[project.optional-dependencies]
# The teaching notebooks render with matplotlib + ipywidgets under jupyter.
# Kept out of the core so a plain `pip install minisim` (engine only) stays lean.
notebook = [
"ipympl>=0.10.0",
"ipywidgets",
"jupyter",
"matplotlib",
"mediapy",
"tqdm",
]
test = [
"minisim[notebook]",
"pytest>=8.4.1",
"pytest-cov>=7.1.0",
"ruff>=0.15.14",
]
# The Sphinx documentation site (Read the Docs). Authored in Markdown via MyST;
# the typed Spec/steps render from the live pydantic models via autodoc-pydantic.
docs = [
"sphinx>=8.1",
"pydata-sphinx-theme>=0.16",
"myst-nb>=1.1",
"autodoc-pydantic>=2.2",
"sphinx-copybutton>=0.5",
"sphinx-design>=0.6",
]
[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"
[tool.pdm]
distribution = true
[tool.pdm.version]
# Derive the package version from `v*` git tags via pdm-backend's SCM source.
# Builds between tags get a PEP 440 dev version like `0.1.0.dev41+g<sha>`;
# tagged builds get the clean tag version. No version field to keep in sync.
source = "scm"
tag_filter = "v*"
tag_regex = 'v(?P<version>([1-9][0-9]*!)?(0|[1-9][0-9]*)(\.(0|[1-9][0-9]*))*((a|b|c|rc)(0|[1-9][0-9]*))?(\.post(0|[1-9][0-9]*))?(\.dev(0|[1-9][0-9]*))?$)$'
[tool.pdm.build]
# Keep build artifacts out of the wheel/sdist when the package dir is walked.
# pdm-backend does NOT honor .gitignore, so generated outputs that are gitignored
# but present in a developer's working tree (e.g. a notebook's rendered movies)
# would otherwise be swept into a locally-built wheel. minisim generates every
# movie from code, so videos are outputs and never package inputs: exclude them
# (and notebook checkpoints) outright so a build can never carry large binaries.
excludes = [
"**/__pycache__",
"**/*.pyc",
"**/*.avi",
"**/*.mp4",
"**/*.mkv",
"**/*.mov",
"**/.ipynb_checkpoints",
]
[tool.pdm.scripts]
lock.composite = [
'pdm lock --with :all --python=">=3.10,<3.12"',
'pdm lock --with :all --python=">=3.12,<3.14" --append',
'pdm lock --with :all --python=">=3.14" --append'
]
test = "pytest"
# Dependency cooldown: exclude packages published in the last 7 days when
# resolving the lockfile, dodging most supply-chain attacks (usually caught
# within ~a week). Reading exclude-newer from this table requires PDM >= 2.26.9;
# older PDMs SILENTLY IGNORE it. CI pins the floor.
[tool.pdm.resolution]
exclude-newer = "7d"
[tool.commitizen]
name = "cz_conventional_commits"
# `version_provider = "scm"` makes commitizen read the current version from the
# latest git tag, so `cz bump` does not write to source files: it just creates
# the next tag and updates the changelog.
version_provider = "scm"
tag_format = "v$version"
changelog_incremental = true
[tool.ruff]
target-version = "py310"
# Teaching notebooks follow notebook conventions (mid-cell imports, explicit
# int() casts for clarity), so they are linted by hand, not by this gate.
extend-exclude = ["*.ipynb"]
[tool.ruff.lint]
# UP (pyupgrade) plus the high-value, low-noise families: pyflakes (F: unused
# imports/vars, undefined names), import sorting (I), bugbear (B), a slice of
# pycodestyle (E4/E7/E9: import/statement/runtime errors, not line length), and
# ruff's own checks (RUF).
select = ["E4", "E7", "E9", "F", "I", "B", "UP", "RUF"]
ignore = [
# Scientific notation (µ, σ, →, ×, ≈, ⊛) is intentional throughout the
# docstrings, comments, and Field descriptions; it is not an ambiguous typo.
"RUF001", "RUF002", "RUF003",
# Compact `a; b` one-liners are an intentional style choice in a few spots.
"E702",
# `int(round(x))` is deliberate: round() on a numpy scalar returns a numpy
# type, and the int() pins it to a Python int. Not an unnecessary cast.
"RUF046",
]
fixable = ["ALL"]
[tool.ruff.lint.per-file-ignores]
# numpydantic's `Shape["* unit, * frame"]` DSL is a string ruff parses as a
# Python forward annotation, where the leading `*` is a syntax error. It is valid
# numpydantic, so F722 is a false positive here -- the same root cause that keeps
# recording.py out of the pyright gate (see [tool.pyright].exclude).
"minisim/recording.py" = ["F722"]
[tool.pyright]
include = ["minisim"]
exclude = [
"**/__pycache__",
# Tests exercise dynamic xarray/numpy indexing heavily; type-gating them is
# high-noise, low-value, so they are out of scope.
"minisim/test",
# The training-notebook presentation helpers are matplotlib / ipywidgets /
# mediapy plotting code, not part of minisim's forward-model contract and
# gated behind the [notebook] extra. Pyright on it is the same high-noise,
# low-value story as the tests: loose matplotlib stubs (header_visible,
# add_axes rect, plt.Circle), numpy .shape / Optional narrowing the checker
# cannot follow through stored lists, and heterogeneous-dict inference. The
# load-bearing physics lives in the gated library modules these call into.
"minisim/notebooks",
# numpydantic's Shape["..."] DSL is not statically parseable, so pyright
# mis-infers GroundTruth's array fields and the error cascades through the
# whole module. Excluded *pending* a numpydantic static-typing story (a stub
# or TYPE_CHECKING-friendly form) -- see the upstream discussion -- not a
# permanent punt. The rest of the package is gated.
"minisim/recording.py",
]
venvPath = "."
venv = ".venv"
pythonVersion = "3.10"
typeCheckingMode = "basic"
# pydantic step specs legitimately redeclare the `kind`/`domain` ClassVars the
# StepSpec base declares (the discriminated-union idiom); pyright's
# incompatible-override check is a false positive for that pattern.
reportIncompatibleVariableOverride = false
[tool.pytest.ini_options]
addopts = [
'-v',
'--color=yes',
'--cov=minisim',
]
testpaths = [
"minisim/test"
]