kintsugi-st 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,43 @@
1
+ # Local research assets (not published to GitHub)
2
+ data/
3
+ exp/
4
+ external/
5
+ figures/
6
+ ms/
7
+ scripts/
8
+
9
+ # LaTeX build artifacts
10
+ *.aux
11
+ *.bbl
12
+ *.bcf
13
+ *.blg
14
+ *.fdb_latexmk
15
+ *.fls
16
+ *.log
17
+ *.out
18
+ *.run.xml
19
+ *.synctex.gz
20
+ *.toc
21
+ texput.log
22
+
23
+ # Python
24
+ __pycache__/
25
+ *.egg-info/
26
+ *.pyc
27
+ *.pyo
28
+ *.pyd
29
+ dist/
30
+ build/
31
+ .venv/
32
+ .coverage
33
+ .coverage.*
34
+ .mypy_cache/
35
+ .pytest_cache/
36
+ .ruff_cache/
37
+ .tox/
38
+ .nox/
39
+ htmlcov/
40
+ .playwright-mcp/
41
+
42
+ # OS
43
+ .DS_Store
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kintsugi authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,394 @@
1
+ Metadata-Version: 2.4
2
+ Name: kintsugi-st
3
+ Version: 0.1.0
4
+ Summary: Adaptive spatial tessellation for sub-cellular resolution transcriptomics
5
+ Project-URL: Homepage, https://github.com/cafferychen777/kintsugi
6
+ Project-URL: Repository, https://github.com/cafferychen777/kintsugi
7
+ Project-URL: Issues, https://github.com/cafferychen777/kintsugi/issues
8
+ Project-URL: Documentation, https://github.com/cafferychen777/kintsugi#readme
9
+ Author: Kintsugi authors
10
+ Maintainer: Kintsugi authors
11
+ License: MIT License
12
+
13
+ Copyright (c) 2026 Kintsugi authors
14
+
15
+ Permission is hereby granted, free of charge, to any person obtaining a copy
16
+ of this software and associated documentation files (the "Software"), to deal
17
+ in the Software without restriction, including without limitation the rights
18
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19
+ copies of the Software, and to permit persons to whom the Software is
20
+ furnished to do so, subject to the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be included in all
23
+ copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
+ SOFTWARE.
32
+ License-File: LICENSE
33
+ Keywords: segmentation,spatial transcriptomics,tessellation,visium hd
34
+ Classifier: Development Status :: 4 - Beta
35
+ Classifier: Intended Audience :: Science/Research
36
+ Classifier: License :: OSI Approved :: MIT License
37
+ Classifier: Operating System :: OS Independent
38
+ Classifier: Programming Language :: Python :: 3
39
+ Classifier: Programming Language :: Python :: 3 :: Only
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
44
+ Requires-Python: >=3.10
45
+ Requires-Dist: h5py>=3.10
46
+ Requires-Dist: numpy>=1.24
47
+ Requires-Dist: pandas>=2.0
48
+ Requires-Dist: pyarrow>=14.0
49
+ Requires-Dist: scipy>=1.11
50
+ Provides-Extra: anndata
51
+ Requires-Dist: anndata>=0.10; extra == 'anndata'
52
+ Provides-Extra: dev
53
+ Requires-Dist: anndata>=0.10; extra == 'dev'
54
+ Requires-Dist: build>=1.2; extra == 'dev'
55
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
56
+ Requires-Dist: pytest>=8.0; extra == 'dev'
57
+ Requires-Dist: ruff>=0.6; extra == 'dev'
58
+ Requires-Dist: twine>=5.0; extra == 'dev'
59
+ Description-Content-Type: text/markdown
60
+
61
+ # Kintsugi
62
+
63
+ > Named after the Japanese art of repairing broken ceramics with gold — honouring
64
+ > boundaries rather than erasing them.
65
+
66
+ Kintsugi builds adaptive spatial regions from Visium HD and other regular-grid
67
+ spatial transcriptomics data. It starts from a 2D bin lattice and returns
68
+ larger spatial regions whose boundaries follow local changes in molecule
69
+ density. The package sits between raw binned counts and downstream biological
70
+ analysis: it produces region labels, region-level Pearson residuals, region
71
+ sizes, depths, centroids, and a spatial adjacency graph.
72
+
73
+ Kintsugi does not do clustering, marker testing, plotting, or
74
+ manuscript-specific analysis. Those choices stay downstream.
75
+
76
+ ## Installation
77
+
78
+ ### From PyPI (available upon publication)
79
+
80
+ ```bash
81
+ pip install kintsugi-st
82
+ ```
83
+
84
+ ### From GitHub
85
+
86
+ ```bash
87
+ pip install git+https://github.com/cafferychen777/kintsugi.git
88
+ ```
89
+
90
+ ### With AnnData support
91
+
92
+ ```bash
93
+ pip install "kintsugi-st[anndata]"
94
+ ```
95
+
96
+ ### Conda / Mamba (from source)
97
+
98
+ ```bash
99
+ git clone https://github.com/cafferychen777/kintsugi.git
100
+ cd kintsugi
101
+ mamba env create -f environment.yml
102
+ mamba activate kintsugi
103
+ ```
104
+
105
+ ### Docker
106
+
107
+ ```bash
108
+ docker build -t kintsugi .
109
+ docker run --rm kintsugi # run demo
110
+ docker run --rm -it kintsugi python # interactive
111
+ docker run --rm -v $(pwd)/data:/data kintsugi \
112
+ python -c "import kintsugi; ..." # mount data
113
+ ```
114
+
115
+ ### Singularity / Apptainer (HPC)
116
+
117
+ ```bash
118
+ singularity build kintsugi.sif Singularity.def
119
+ singularity exec kintsugi.sif python -c "import kintsugi"
120
+
121
+ # or, on systems that provide Apptainer:
122
+ apptainer build kintsugi.sif Singularity.def
123
+ apptainer exec kintsugi.sif python -c "import kintsugi"
124
+ ```
125
+
126
+ ### System requirements
127
+
128
+ - **OS**: Linux, macOS, Windows (any platform with Python support).
129
+ - **Python**: 3.10, 3.11, or 3.12.
130
+ - **Dependencies**: NumPy (>=1.24), SciPy (>=1.11), h5py (>=3.10),
131
+ pandas (>=2.0), PyArrow (>=14.0). Kintsugi itself is pure Python and
132
+ ships no compiled extension modules.
133
+ - **Install time**: < 30 seconds on a standard machine with pip.
134
+ - **Hardware**: No GPU required. 16 GB RAM is sufficient for most Visium HD
135
+ samples; 64 GB recommended for very large grids (> 500k bins).
136
+
137
+ ## Quick start (30 seconds)
138
+
139
+ ```python
140
+ import kintsugi
141
+
142
+ grid = kintsugi.load_visium_hd_from_dir("sample_dir")
143
+ result = grid.tessellate()
144
+
145
+ print(kintsugi.tessellation_report(result, grid))
146
+ ```
147
+
148
+ That's it. Three lines: load, tessellate, report.
149
+
150
+ ## One-command demo
151
+
152
+ Run the bundled demo on a synthetic dataset (no data download needed):
153
+
154
+ ```bash
155
+ kintsugi-demo # CLI entry point (after pip install)
156
+ python -m kintsugi.demo # module invocation
157
+ ```
158
+
159
+ Expected output:
160
+
161
+ ```
162
+ Kintsugi v0.1.0
163
+ =======================================================
164
+
165
+ 1. Generating toy dataset...
166
+ Grid: 60×60, 100 genes, 2,472 tissue bins
167
+ Time: 0.02s
168
+
169
+ 2. Running tessellation...
170
+ Regions: 75
171
+ Time: 0.12s
172
+
173
+ 3. Diagnostic report:
174
+ ── Kintsugi Tessellation Report ──────────────────────
175
+ Regions : 75
176
+ Median UMI / region : 167.0
177
+ Density CV : 0.3488
178
+ Stationarity pass : 84.0%
179
+ Composition holdout : -30.3192 nats/bin
180
+ Density holdout : -2.4633 nats/bin
181
+ Composition ΔLL : +3.3670 nats/bin
182
+ Density ΔLL : +0.4569 nats/bin
183
+ Composition dominates: False
184
+ ─────────────────────────────────────────────────────
185
+
186
+ 4. Determinism check:
187
+ Label hash (sha256[:16]): 3653373eec97b137
188
+
189
+ Total runtime: 0.16s
190
+ Done.
191
+ ```
192
+
193
+ The label hash `3653373eec97b137` verifies deterministic output across
194
+ platforms.
195
+
196
+ ## 10x Space Ranger to Kintsugi tutorial
197
+
198
+ If your data comes from 10x Genomics Space Ranger, the directory typically
199
+ looks like:
200
+
201
+ ```
202
+ sample/
203
+ ├── filtered_feature_bc_matrix.h5
204
+ └── spatial/
205
+ └── tissue_positions.parquet (or .csv)
206
+ ```
207
+
208
+ ### Step 1: Load
209
+
210
+ ```python
211
+ import kintsugi
212
+
213
+ grid = kintsugi.load_visium_hd_from_dir("sample/")
214
+ print(f"Grid: {grid.rows}×{grid.cols}, {grid.n_genes} genes, {grid.mask.sum()} tissue bins")
215
+ ```
216
+
217
+ If your files are in non-standard locations:
218
+
219
+ ```python
220
+ grid = kintsugi.load_visium_hd(
221
+ "path/to/filtered_feature_bc_matrix.h5",
222
+ "path/to/tissue_positions.parquet",
223
+ )
224
+ ```
225
+
226
+ ### Step 2: Tessellate
227
+
228
+ ```python
229
+ result = grid.tessellate()
230
+ ```
231
+
232
+ With custom parameters:
233
+
234
+ ```python
235
+ result = grid.tessellate(
236
+ lag=2, # variogram lag in bins (2 bins = 4 µm at 2 µm resolution)
237
+ kappa=2.0, # stationarity tolerance
238
+ min_seed_distance=4, # minimum seed separation in bins
239
+ smooth_sigma=4.0, # Gaussian smoothing for seed detection
240
+ )
241
+ ```
242
+
243
+ ### Step 3: Inspect the result
244
+
245
+ ```python
246
+ result.labels # (rows, cols) int32 — region labels, -1 outside tissue
247
+ result.residuals # (K, G) float64 — Pearson residuals
248
+ result.areas # (K,) float64 — bins per region
249
+ result.depths # (K,) float64 — total UMI per region
250
+ result.centroids # (K, 2) float64 — (row, col) centroids
251
+ result.adjacency # (K, K) sparse — spatial adjacency graph
252
+ result.trace # (rows, cols) float64 — boundary-tensor trace
253
+ result.n_regions # int — number of regions
254
+ ```
255
+
256
+ ### Step 4: Diagnostic report
257
+
258
+ ```python
259
+ report = kintsugi.tessellation_report(result, grid)
260
+ print(report)
261
+ ```
262
+
263
+ The report automatically computes:
264
+
265
+ | Metric | What it measures |
266
+ | --- | --- |
267
+ | Region count | Number of tessellated regions |
268
+ | Median UMI/region | Depth distribution |
269
+ | Density CV | Coefficient of variation of per-bin UMI density |
270
+ | Stationarity pass rate | Fraction passing Poisson stationarity test |
271
+ | Composition holdout LL | Held-out log-likelihood for multinomial composition |
272
+ | Density holdout LL | Held-out log-likelihood for Poisson density |
273
+ | Composition/Density ΔLL | Improvement over single-global-model null |
274
+ | Composition dominates | Warning if boundaries are driven by composition, not density |
275
+
276
+ ### Step 5: Export to AnnData (scverse integration)
277
+
278
+ ```python
279
+ adata = kintsugi.to_anndata(result, grid=grid, use_raw_counts=True)
280
+
281
+ # adata.X = Pearson residuals
282
+ # adata.obs = area, depth
283
+ # adata.obsm = spatial centroids
284
+ # adata.obsp = adjacency graph
285
+ # adata.layers = raw aggregated counts
286
+
287
+ adata.write("tessellation.h5ad")
288
+ ```
289
+
290
+ The AnnData object is directly usable with Scanpy, Squidpy, and other scverse
291
+ tools for clustering, visualisation, and spatial analysis.
292
+
293
+ ## Parameters
294
+
295
+ All parameters have fixed defaults and are documented. There is no hidden
296
+ tuning.
297
+
298
+ | Parameter | Default | How to think about it |
299
+ | --- | --- | --- |
300
+ | `lag` | `2` | Grid offset for directional semivariance. On a 2 µm Visium HD grid, `lag=2` is a 4 µm offset. Larger values look at broader spatial variation. |
301
+ | `kappa` | `2.0` | Stationarity tolerance during region refinement (in SE units). Larger values allow broader regions. |
302
+ | `min_seed_distance` | `4` | Minimum distance between seed points in grid bins. Controls the spatial scale: larger = fewer, larger regions. |
303
+ | `smooth_sigma` | `4.0` | Gaussian sigma for smoothing the trace field before seed detection. Larger values favor smoother boundaries. |
304
+
305
+ For very small toy examples, use smaller `min_seed_distance` and
306
+ `smooth_sigma` values (the defaults target real Visium HD grids).
307
+
308
+ ## Performance
309
+
310
+ Measured on an Apple M1 Max (single thread, pure Python).
311
+
312
+ | Dataset | Grid | Genes | Tissue bins | Regions | Time | Peak memory |
313
+ | --- | --- | --- | --- | --- | --- | --- |
314
+ | Toy (synthetic) | 60 × 60 | 100 | 2,472 | 75 | 0.3 s | 4 MB |
315
+ | Medium (synthetic) | 200 × 200 | 500 | 40,000 | ~1,900 | 0.4 s | 54 MB |
316
+ | Large (synthetic) | 500 × 500 | 1,000 | 250,000 | ~12,000 | 2.7 s | 385 MB |
317
+
318
+ Memory scales primarily with `n_regions × n_genes` (the dense residual
319
+ matrix). Upstream gene filtering is the main memory lever for large datasets.
320
+
321
+ ## Input contract
322
+
323
+ Kintsugi operates on a normalized grid:
324
+
325
+ - `counts`: SciPy sparse matrix with shape `(rows * cols, genes)`.
326
+ - `rows`, `cols`: dimensions of the 2D grid.
327
+ - `mask`: optional boolean array with shape `(rows, cols)`; `True` marks
328
+ in-tissue bins.
329
+ - Matrix rows are in row-major order: row `r * cols + c` corresponds to grid
330
+ bin `(r, c)`.
331
+ - Count values must be finite and non-negative.
332
+
333
+ `GridData` is the package container for this contract.
334
+
335
+ ## Non-Visium inputs
336
+
337
+ For any regular-grid data where you have occupied-bin counts and coordinates:
338
+
339
+ ```python
340
+ grid = kintsugi.build_regular_grid(
341
+ counts, # sparse (n_occupied, genes)
342
+ row_coords, # 1D array of row indices
343
+ col_coords, # 1D array of column indices
344
+ rows=R, cols=C, # grid extent
345
+ )
346
+ result = grid.tessellate()
347
+ ```
348
+
349
+ ## API overview
350
+
351
+ Most users need only:
352
+
353
+ - `kintsugi.load_visium_hd_from_dir(...)` — load from Space Ranger output
354
+ - `kintsugi.tessellate(...)` — run the full pipeline
355
+ - `kintsugi.tessellation_report(...)` — diagnostic report
356
+ - `kintsugi.to_anndata(...)` — export to AnnData
357
+
358
+ Lower-level functions for advanced users:
359
+
360
+ - `directional_semivariance` — variogram estimation
361
+ - `boundary_tensor` — tensor eigendecomposition
362
+ - `adaptive_tessellation` — watershed + stationarity refinement
363
+ - `aggregate_counts` — region-level Pearson residuals
364
+ - `build_spatial_graph` — adjacency from labels
365
+
366
+ ## Reproducibility
367
+
368
+ - **Deterministic**: no random seeds, no stochastic algorithms. The same
369
+ input always produces the same output (verified by SHA-256 hash in tests).
370
+ - **No hidden tuning**: all parameters are explicit and documented.
371
+ - **Tested package surface**: unit tests cover core algorithms, I/O, report,
372
+ AnnData export, the demo dataset, and edge-case validation.
373
+ - **Coverage reporting**: use the pytest-cov command below to reproduce the
374
+ module-level coverage table.
375
+ - **CI on Python 3.10, 3.11, 3.12** via GitHub Actions.
376
+ - **Docker and Singularity** images for containerised reproduction.
377
+
378
+ ## Testing
379
+
380
+ ```bash
381
+ python -m pip install -e ".[dev]"
382
+ python -m ruff check kintsugi tests examples
383
+ python -m pytest --cov=kintsugi --cov-report=term-missing
384
+ ```
385
+
386
+ ## License
387
+
388
+ Kintsugi is released under the [MIT License](LICENSE).
389
+
390
+ ## Citation
391
+
392
+ If you use Kintsugi in your research, please cite:
393
+
394
+ > [Citation will be added upon publication]