slide2vec 3.2.1__tar.gz → 4.0.2__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.
Files changed (123) hide show
  1. {slide2vec-3.2.1/slide2vec.egg-info → slide2vec-4.0.2}/PKG-INFO +94 -32
  2. {slide2vec-3.2.1 → slide2vec-4.0.2}/README.md +29 -6
  3. slide2vec-4.0.2/pyproject.toml +174 -0
  4. slide2vec-4.0.2/setup.cfg +4 -0
  5. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/__init__.py +3 -2
  6. slide2vec-4.0.2/slide2vec/api.py +561 -0
  7. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/artifacts.py +127 -49
  8. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/cli.py +4 -20
  9. slide2vec-4.0.2/slide2vec/configs/__init__.py +4 -0
  10. {slide2vec-3.2.1/slide2vec/configs/preprocessing → slide2vec-4.0.2/slide2vec/configs}/default.yaml +35 -12
  11. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/data/__init__.py +0 -1
  12. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/data/dataset.py +4 -6
  13. slide2vec-4.0.2/slide2vec/data/tile_reader.py +430 -0
  14. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/distributed/__init__.py +1 -55
  15. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/distributed/direct_embed_worker.py +45 -22
  16. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/distributed/pipeline_worker.py +12 -6
  17. slide2vec-4.0.2/slide2vec/encoders/__init__.py +36 -0
  18. slide2vec-4.0.2/slide2vec/encoders/base.py +134 -0
  19. slide2vec-4.0.2/slide2vec/encoders/models/__init__.py +34 -0
  20. slide2vec-4.0.2/slide2vec/encoders/models/conch.py +93 -0
  21. slide2vec-4.0.2/slide2vec/encoders/models/gigapath.py +90 -0
  22. slide2vec-4.0.2/slide2vec/encoders/models/hibou.py +90 -0
  23. slide2vec-4.0.2/slide2vec/encoders/models/hoptimus.py +133 -0
  24. slide2vec-4.0.2/slide2vec/encoders/models/midnight.py +59 -0
  25. slide2vec-4.0.2/slide2vec/encoders/models/musk.py +69 -0
  26. slide2vec-4.0.2/slide2vec/encoders/models/phikon.py +82 -0
  27. slide2vec-4.0.2/slide2vec/encoders/models/prism.py +50 -0
  28. slide2vec-4.0.2/slide2vec/encoders/models/prost40m.py +21 -0
  29. slide2vec-4.0.2/slide2vec/encoders/models/titan.py +58 -0
  30. slide2vec-4.0.2/slide2vec/encoders/models/uni.py +56 -0
  31. slide2vec-4.0.2/slide2vec/encoders/models/virchow.py +82 -0
  32. slide2vec-4.0.2/slide2vec/encoders/registry.py +216 -0
  33. slide2vec-4.0.2/slide2vec/encoders/validation.py +76 -0
  34. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/inference.py +1271 -545
  35. slide2vec-4.0.2/slide2vec/model_settings.py +47 -0
  36. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/progress.py +7 -8
  37. slide2vec-4.0.2/slide2vec/registry.py +70 -0
  38. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/resources.py +4 -1
  39. slide2vec-4.0.2/slide2vec/runtime_types.py +14 -0
  40. slide2vec-4.0.2/slide2vec/utils/__init__.py +10 -0
  41. slide2vec-4.0.2/slide2vec/utils/config.py +164 -0
  42. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/utils/coordinates.py +7 -7
  43. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/utils/log_utils.py +4 -5
  44. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/utils/tiling_io.py +81 -51
  45. slide2vec-4.0.2/slide2vec/utils/utils.py +107 -0
  46. {slide2vec-3.2.1 → slide2vec-4.0.2/slide2vec.egg-info}/PKG-INFO +94 -32
  47. slide2vec-4.0.2/slide2vec.egg-info/SOURCES.txt +64 -0
  48. slide2vec-4.0.2/slide2vec.egg-info/requires.txt +87 -0
  49. slide2vec-4.0.2/tests/test_batch_collator_timing.py +161 -0
  50. slide2vec-4.0.2/tests/test_encoder_registry.py +171 -0
  51. {slide2vec-3.2.1 → slide2vec-4.0.2}/tests/test_hs2p_package_cutover.py +87 -54
  52. {slide2vec-3.2.1 → slide2vec-4.0.2}/tests/test_output_consistency.py +9 -17
  53. slide2vec-4.0.2/tests/test_packaging_metadata.py +23 -0
  54. {slide2vec-3.2.1 → slide2vec-4.0.2}/tests/test_progress.py +61 -24
  55. {slide2vec-3.2.1 → slide2vec-4.0.2}/tests/test_regression_core.py +289 -136
  56. {slide2vec-3.2.1 → slide2vec-4.0.2}/tests/test_regression_inference.py +1013 -613
  57. {slide2vec-3.2.1 → slide2vec-4.0.2}/tests/test_regression_models.py +83 -441
  58. slide2vec-3.2.1/MANIFEST.in +0 -3
  59. slide2vec-3.2.1/pyproject.toml +0 -42
  60. slide2vec-3.2.1/setup.cfg +0 -69
  61. slide2vec-3.2.1/setup.py +0 -15
  62. slide2vec-3.2.1/slide2vec/api.py +0 -551
  63. slide2vec-3.2.1/slide2vec/configs/__init__.py +0 -5
  64. slide2vec-3.2.1/slide2vec/configs/models/conch.yaml +0 -16
  65. slide2vec-3.2.1/slide2vec/configs/models/conchv15.yaml +0 -16
  66. slide2vec-3.2.1/slide2vec/configs/models/default.yaml +0 -37
  67. slide2vec-3.2.1/slide2vec/configs/models/h-optimus-0.yaml +0 -16
  68. slide2vec-3.2.1/slide2vec/configs/models/h-optimus-1.yaml +0 -16
  69. slide2vec-3.2.1/slide2vec/configs/models/h0-mini.yaml +0 -16
  70. slide2vec-3.2.1/slide2vec/configs/models/hibou.yaml +0 -17
  71. slide2vec-3.2.1/slide2vec/configs/models/kaiko-midnight.yaml +0 -16
  72. slide2vec-3.2.1/slide2vec/configs/models/kaiko.yaml +0 -17
  73. slide2vec-3.2.1/slide2vec/configs/models/musk.yaml +0 -16
  74. slide2vec-3.2.1/slide2vec/configs/models/panda-vit-s.yaml +0 -17
  75. slide2vec-3.2.1/slide2vec/configs/models/pathojepa.yaml +0 -36
  76. slide2vec-3.2.1/slide2vec/configs/models/phikonv2.yaml +0 -16
  77. slide2vec-3.2.1/slide2vec/configs/models/prism.yaml +0 -18
  78. slide2vec-3.2.1/slide2vec/configs/models/prov-gigapath-slide.yaml +0 -17
  79. slide2vec-3.2.1/slide2vec/configs/models/prov-gigapath-tile.yaml +0 -16
  80. slide2vec-3.2.1/slide2vec/configs/models/titan.yaml +0 -17
  81. slide2vec-3.2.1/slide2vec/configs/models/uni.yaml +0 -16
  82. slide2vec-3.2.1/slide2vec/configs/models/uni2.yaml +0 -16
  83. slide2vec-3.2.1/slide2vec/configs/models/virchow.yaml +0 -16
  84. slide2vec-3.2.1/slide2vec/configs/models/virchow2.yaml +0 -16
  85. slide2vec-3.2.1/slide2vec/data/augmentations.py +0 -57
  86. slide2vec-3.2.1/slide2vec/data/cucim_tile_reader.py +0 -286
  87. slide2vec-3.2.1/slide2vec/data/wsd_tile_reader.py +0 -175
  88. slide2vec-3.2.1/slide2vec/model_settings.py +0 -196
  89. slide2vec-3.2.1/slide2vec/models/__init__.py +0 -1
  90. slide2vec-3.2.1/slide2vec/models/layers/__init__.py +0 -6
  91. slide2vec-3.2.1/slide2vec/models/layers/attention.py +0 -81
  92. slide2vec-3.2.1/slide2vec/models/layers/block.py +0 -301
  93. slide2vec-3.2.1/slide2vec/models/layers/dino_head.py +0 -62
  94. slide2vec-3.2.1/slide2vec/models/layers/drop_path.py +0 -26
  95. slide2vec-3.2.1/slide2vec/models/layers/layer_scale.py +0 -20
  96. slide2vec-3.2.1/slide2vec/models/layers/mlp.py +0 -30
  97. slide2vec-3.2.1/slide2vec/models/layers/patch_embed.py +0 -91
  98. slide2vec-3.2.1/slide2vec/models/layers/swiglu_ffn.py +0 -68
  99. slide2vec-3.2.1/slide2vec/models/models.py +0 -974
  100. slide2vec-3.2.1/slide2vec/models/vision_transformer_dino.py +0 -481
  101. slide2vec-3.2.1/slide2vec/models/vision_transformer_dinov2.py +0 -447
  102. slide2vec-3.2.1/slide2vec/models/vision_transformer_pathojepa.py +0 -171
  103. slide2vec-3.2.1/slide2vec/utils/__init__.py +0 -37
  104. slide2vec-3.2.1/slide2vec/utils/config.py +0 -119
  105. slide2vec-3.2.1/slide2vec/utils/paths.py +0 -10
  106. slide2vec-3.2.1/slide2vec/utils/utils.py +0 -132
  107. slide2vec-3.2.1/slide2vec.egg-info/SOURCES.txt +0 -89
  108. slide2vec-3.2.1/slide2vec.egg-info/requires.txt +0 -33
  109. slide2vec-3.2.1/tests/test_batch_collator_timing.py +0 -104
  110. slide2vec-3.2.1/tests/test_benchmark_embedding_throughput.py +0 -767
  111. slide2vec-3.2.1/tests/test_benchmark_end_to_end_paths.py +0 -424
  112. slide2vec-3.2.1/tests/test_benchmark_tile_read_strategies.py +0 -151
  113. slide2vec-3.2.1/tests/test_dependency_split.py +0 -133
  114. slide2vec-3.2.1/tests/test_release.py +0 -67
  115. {slide2vec-3.2.1 → slide2vec-4.0.2}/LICENSE +0 -0
  116. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/__main__.py +0 -0
  117. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/data/tile_store.py +0 -0
  118. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec/main.py +0 -0
  119. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec.egg-info/dependency_links.txt +0 -0
  120. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec.egg-info/entry_points.txt +0 -0
  121. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec.egg-info/not-zip-safe +0 -0
  122. {slide2vec-3.2.1 → slide2vec-4.0.2}/slide2vec.egg-info/top_level.txt +0 -0
  123. {slide2vec-3.2.1 → slide2vec-4.0.2}/tests/test_tile_store.py +0 -0
@@ -1,16 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: slide2vec
3
- Version: 3.2.1
3
+ Version: 4.0.2
4
4
  Summary: Embedding of whole slide images with Foundation Models
5
- Home-page: https://github.com/clemsgrs/slide2vec
6
- Author: Clément Grisi
7
- Author-email: clement.grisi@radboudumc.nl
5
+ Author-email: Clément Grisi <clement.grisi@radboudumc.nl>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/clemsgrs/slide2vec
8
8
  Project-URL: Bug Tracker, https://github.com/clemsgrs/slide2vec/issues
9
- Platform: unix
10
- Platform: linux
11
- Platform: osx
12
- Platform: cygwin
13
- Platform: win32
14
9
  Classifier: Programming Language :: Python :: 3
15
10
  Classifier: Programming Language :: Python :: 3 :: Only
16
11
  Classifier: Programming Language :: Python :: 3.10
@@ -20,42 +15,86 @@ Classifier: Programming Language :: Python :: 3.13
20
15
  Requires-Python: >=3.10
21
16
  Description-Content-Type: text/markdown
22
17
  License-File: LICENSE
23
- Requires-Dist: hs2p<3,>=2.5.1
18
+ Requires-Dist: hs2p[asap,cucim,openslide,vips]>=3.1.4
24
19
  Requires-Dist: omegaconf
25
- Requires-Dist: h5py
26
20
  Requires-Dist: matplotlib
27
21
  Requires-Dist: numpy<2
28
22
  Requires-Dist: pandas
29
23
  Requires-Dist: pillow
30
- Requires-Dist: PyTurboJPEG
31
24
  Requires-Dist: rich
32
- Requires-Dist: tqdm
33
25
  Requires-Dist: torch
34
26
  Requires-Dist: torchvision
35
27
  Requires-Dist: transformers
36
28
  Requires-Dist: wandb
37
- Requires-Dist: wholeslidedata<0.0.16
38
29
  Requires-Dist: einops
39
30
  Requires-Dist: timm
40
- Provides-Extra: cucim
41
- Requires-Dist: hs2p[cucim]<3,>=2.5.1; extra == "cucim"
42
- Provides-Extra: models
43
- Requires-Dist: huggingface-hub; extra == "models"
44
- Requires-Dist: sacremoses; extra == "models"
45
- Requires-Dist: einops-exts; extra == "models"
46
- Requires-Dist: xformers; extra == "models"
31
+ Requires-Dist: huggingface_hub
32
+ Provides-Extra: hoptimus
33
+ Requires-Dist: torch>=2.0; extra == "hoptimus"
34
+ Requires-Dist: torchvision>=0.15.0; extra == "hoptimus"
35
+ Requires-Dist: xformers>=0.0.18; extra == "hoptimus"
36
+ Provides-Extra: virchow
37
+ Requires-Dist: timm>=0.9.11; extra == "virchow"
38
+ Requires-Dist: torch>=2.0; extra == "virchow"
39
+ Provides-Extra: uni
40
+ Requires-Dist: torch>=2.0; extra == "uni"
41
+ Requires-Dist: timm>=0.9.8; extra == "uni"
42
+ Requires-Dist: xformers>=0.0.18; extra == "uni"
43
+ Provides-Extra: prism
44
+ Requires-Dist: transformers~=4.53.0; extra == "prism"
45
+ Requires-Dist: torch<2.8,>=2.3; extra == "prism"
46
+ Requires-Dist: einops==0.8.0; extra == "prism"
47
+ Requires-Dist: environs==11.0.0; extra == "prism"
48
+ Requires-Dist: sacremoses==0.1.1; extra == "prism"
49
+ Requires-Dist: xformers==0.0.31; extra == "prism"
50
+ Provides-Extra: hibou
51
+ Requires-Dist: scipy~=1.8.1; extra == "hibou"
52
+ Requires-Dist: scikit-image~=0.19.3; extra == "hibou"
53
+ Provides-Extra: titan
54
+ Requires-Dist: torch==2.0.1; extra == "titan"
55
+ Requires-Dist: timm==1.0.3; extra == "titan"
56
+ Requires-Dist: einops==0.6.1; extra == "titan"
57
+ Requires-Dist: einops-exts==0.0.4; extra == "titan"
58
+ Requires-Dist: transformers==4.46.0; extra == "titan"
59
+ Provides-Extra: fm
60
+ Requires-Dist: omegaconf>=2.3.0; extra == "fm"
61
+ Requires-Dist: matplotlib; extra == "fm"
62
+ Requires-Dist: numpy<2; extra == "fm"
63
+ Requires-Dist: pandas; extra == "fm"
64
+ Requires-Dist: pillow; extra == "fm"
65
+ Requires-Dist: rich; extra == "fm"
66
+ Requires-Dist: hs2p[asap,cucim,openslide,vips]>=3.1.4; extra == "fm"
67
+ Requires-Dist: wandb; extra == "fm"
68
+ Requires-Dist: torch<2.8,>=2.3; extra == "fm"
69
+ Requires-Dist: torchvision>=0.18.0; extra == "fm"
70
+ Requires-Dist: einops>=0.8.0; extra == "fm"
71
+ Requires-Dist: timm>=1.0.3; extra == "fm"
72
+ Requires-Dist: huggingface_hub<1.0,>=0.30.0; extra == "fm"
73
+ Requires-Dist: environs; extra == "fm"
74
+ Requires-Dist: einops-exts>=0.0.4; extra == "fm"
75
+ Requires-Dist: transformers>=4.53; extra == "fm"
76
+ Requires-Dist: sacremoses; extra == "fm"
77
+ Requires-Dist: xformers>=0.0.31; extra == "fm"
78
+ Requires-Dist: scipy>=1.8.1; extra == "fm"
79
+ Requires-Dist: scikit-image>=0.19.3; extra == "fm"
80
+ Requires-Dist: torchmetrics>=0.10.3; extra == "fm"
81
+ Requires-Dist: fvcore; extra == "fm"
82
+ Requires-Dist: iopath; extra == "fm"
83
+ Requires-Dist: webdataset; extra == "fm"
84
+ Requires-Dist: scikit-survival; extra == "fm"
85
+ Requires-Dist: scikit-learn; extra == "fm"
86
+ Requires-Dist: fairscale; extra == "fm"
87
+ Requires-Dist: packaging==23.2; extra == "fm"
88
+ Requires-Dist: ninja==1.11.1.1; extra == "fm"
89
+ Requires-Dist: psutil<6; extra == "fm"
47
90
  Provides-Extra: testing
48
91
  Requires-Dist: pytest>=6.0; extra == "testing"
49
92
  Requires-Dist: pytest-cov>=2.0; extra == "testing"
50
93
  Requires-Dist: mypy>=0.910; extra == "testing"
51
94
  Requires-Dist: flake8>=3.9; extra == "testing"
95
+ Requires-Dist: flake8-pyproject>=1.2.3; extra == "testing"
52
96
  Requires-Dist: tox>=3.24; extra == "testing"
53
- Dynamic: author-email
54
- Dynamic: description
55
- Dynamic: description-content-type
56
- Dynamic: home-page
57
97
  Dynamic: license-file
58
- Dynamic: project-url
59
98
 
60
99
  # slide2vec
61
100
 
@@ -67,16 +106,19 @@ Dynamic: project-url
67
106
 
68
107
  ```shell
69
108
  pip install slide2vec
109
+ pip install "slide2vec[fm]"
70
110
  ```
71
111
 
72
- Install the full model runtime only when you need embedding/model execution:
112
+ `slide2vec` keeps the base install focused on the core package surface. Use `slide2vec[fm]` when you want the PyPI-hosted FM dependencies.
113
+
114
+ Some model backends still rely on upstream Git repositories that PyPI will not accept as package metadata. Install those separately when needed:
73
115
 
74
116
  ```shell
75
- pip install "slide2vec[models]"
117
+ pip install git+https://github.com/lilab-stanford/MUSK.git
118
+ pip install git+https://github.com/Mahmoodlab/CONCH.git
119
+ pip install git+https://github.com/prov-gigapath/prov-gigapath.git
76
120
  ```
77
121
 
78
- `slide2vec` now keeps the base install focused on the core package surface and moves the heavier model stack into the optional `models` extra.
79
-
80
122
  ## Python API
81
123
 
82
124
  ```python
@@ -89,7 +131,8 @@ model = Model.from_preset("virchow2")
89
131
  embedded = model.embed_slide("/path/to/slide.svs")
90
132
 
91
133
  tile_embeddings = embedded.tile_embeddings
92
- coordinates = embedded.coordinates
134
+ x = embedded.x
135
+ y = embedded.y
93
136
  ```
94
137
 
95
138
  Use `Pipeline(...)` for manifest-driven batch processing when you want artifacts written to disk instead of only in-memory outputs:
@@ -111,6 +154,23 @@ result = pipeline.run(manifest_path="/path/to/slides.csv")
111
154
 
112
155
  By default, `ExecutionOptions()` uses all available GPUs. Set `ExecutionOptions(num_gpus=4)` when you want to cap the sharding explicitly.
113
156
 
157
+ ### Hierarchical Feature Extraction
158
+
159
+ Tile embeddings can be spatially grouped into regions for downstream models that consume region-level structure. Enable it by setting `region_tile_multiple` on `PreprocessingConfig`:
160
+
161
+ ```python
162
+ preprocessing = PreprocessingConfig(
163
+ target_spacing_um=0.5,
164
+ target_tile_size_px=224,
165
+ region_tile_multiple=6, # 6x6 tiles per region
166
+ )
167
+ embedded = model.embed_slide("/path/to/slide.svs", preprocessing=preprocessing)
168
+ ```
169
+
170
+ Hierarchical outputs have shape `(num_regions, tiles_per_region, feature_dim)` and are written to `hierarchical_embeddings/` when persisted.
171
+
172
+ See [`docs/python-api.md`](docs/python-api.md) for details.
173
+
114
174
  ### Input Manifest
115
175
 
116
176
  Manifest-driven runs use the schema below. `mask_path` and `spacing_at_level_0` are optional.
@@ -131,6 +191,8 @@ The package writes explicit artifact directories:
131
191
 
132
192
  - `tile_embeddings/<sample_id>.pt` or `.npz`
133
193
  - `tile_embeddings/<sample_id>.meta.json`
194
+ - `hierarchical_embeddings/<sample_id>.pt` or `.npz` (when `region_tile_multiple` is set)
195
+ - `hierarchical_embeddings/<sample_id>.meta.json`
134
196
  - `slide_embeddings/<sample_id>.pt` or `.npz`
135
197
  - `slide_embeddings/<sample_id>.meta.json`
136
198
  - optional `slide_latents/<sample_id>.pt` or `.npz`
@@ -139,7 +201,7 @@ The package writes explicit artifact directories:
139
201
 
140
202
  ### Supported Models
141
203
 
142
- `slide2vec` currently ships preset configs for 20 tile-level models and 3 slide-level models.
204
+ `slide2vec` currently ships preset configs for 17 tile-level models and 3 slide-level models.
143
205
  For the full catalog and preset names, see [`docs/models.md`](docs/models.md).
144
206
 
145
207
  ## CLI
@@ -8,16 +8,19 @@
8
8
 
9
9
  ```shell
10
10
  pip install slide2vec
11
+ pip install "slide2vec[fm]"
11
12
  ```
12
13
 
13
- Install the full model runtime only when you need embedding/model execution:
14
+ `slide2vec` keeps the base install focused on the core package surface. Use `slide2vec[fm]` when you want the PyPI-hosted FM dependencies.
15
+
16
+ Some model backends still rely on upstream Git repositories that PyPI will not accept as package metadata. Install those separately when needed:
14
17
 
15
18
  ```shell
16
- pip install "slide2vec[models]"
19
+ pip install git+https://github.com/lilab-stanford/MUSK.git
20
+ pip install git+https://github.com/Mahmoodlab/CONCH.git
21
+ pip install git+https://github.com/prov-gigapath/prov-gigapath.git
17
22
  ```
18
23
 
19
- `slide2vec` now keeps the base install focused on the core package surface and moves the heavier model stack into the optional `models` extra.
20
-
21
24
  ## Python API
22
25
 
23
26
  ```python
@@ -30,7 +33,8 @@ model = Model.from_preset("virchow2")
30
33
  embedded = model.embed_slide("/path/to/slide.svs")
31
34
 
32
35
  tile_embeddings = embedded.tile_embeddings
33
- coordinates = embedded.coordinates
36
+ x = embedded.x
37
+ y = embedded.y
34
38
  ```
35
39
 
36
40
  Use `Pipeline(...)` for manifest-driven batch processing when you want artifacts written to disk instead of only in-memory outputs:
@@ -52,6 +56,23 @@ result = pipeline.run(manifest_path="/path/to/slides.csv")
52
56
 
53
57
  By default, `ExecutionOptions()` uses all available GPUs. Set `ExecutionOptions(num_gpus=4)` when you want to cap the sharding explicitly.
54
58
 
59
+ ### Hierarchical Feature Extraction
60
+
61
+ Tile embeddings can be spatially grouped into regions for downstream models that consume region-level structure. Enable it by setting `region_tile_multiple` on `PreprocessingConfig`:
62
+
63
+ ```python
64
+ preprocessing = PreprocessingConfig(
65
+ target_spacing_um=0.5,
66
+ target_tile_size_px=224,
67
+ region_tile_multiple=6, # 6x6 tiles per region
68
+ )
69
+ embedded = model.embed_slide("/path/to/slide.svs", preprocessing=preprocessing)
70
+ ```
71
+
72
+ Hierarchical outputs have shape `(num_regions, tiles_per_region, feature_dim)` and are written to `hierarchical_embeddings/` when persisted.
73
+
74
+ See [`docs/python-api.md`](docs/python-api.md) for details.
75
+
55
76
  ### Input Manifest
56
77
 
57
78
  Manifest-driven runs use the schema below. `mask_path` and `spacing_at_level_0` are optional.
@@ -72,6 +93,8 @@ The package writes explicit artifact directories:
72
93
 
73
94
  - `tile_embeddings/<sample_id>.pt` or `.npz`
74
95
  - `tile_embeddings/<sample_id>.meta.json`
96
+ - `hierarchical_embeddings/<sample_id>.pt` or `.npz` (when `region_tile_multiple` is set)
97
+ - `hierarchical_embeddings/<sample_id>.meta.json`
75
98
  - `slide_embeddings/<sample_id>.pt` or `.npz`
76
99
  - `slide_embeddings/<sample_id>.meta.json`
77
100
  - optional `slide_latents/<sample_id>.pt` or `.npz`
@@ -80,7 +103,7 @@ The package writes explicit artifact directories:
80
103
 
81
104
  ### Supported Models
82
105
 
83
- `slide2vec` currently ships preset configs for 20 tile-level models and 3 slide-level models.
106
+ `slide2vec` currently ships preset configs for 17 tile-level models and 3 slide-level models.
84
107
  For the full catalog and preset names, see [`docs/models.md`](docs/models.md).
85
108
 
86
109
  ## CLI
@@ -0,0 +1,174 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "slide2vec"
7
+ version = "4.0.2"
8
+ description = "Embedding of whole slide images with Foundation Models"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "Apache-2.0"
12
+ authors = [
13
+ { name = "Clément Grisi", email = "clement.grisi@radboudumc.nl" },
14
+ ]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3 :: Only",
18
+ "Programming Language :: Python :: 3.10",
19
+ "Programming Language :: Python :: 3.11",
20
+ "Programming Language :: Python :: 3.12",
21
+ "Programming Language :: Python :: 3.13",
22
+ ]
23
+ dependencies = [
24
+ "hs2p[asap,cucim,openslide,vips]>=3.1.4",
25
+ "omegaconf",
26
+ "matplotlib",
27
+ "numpy<2",
28
+ "pandas",
29
+ "pillow",
30
+ "rich",
31
+ "torch",
32
+ "torchvision",
33
+ "transformers",
34
+ "wandb",
35
+ "einops",
36
+ "timm",
37
+ "huggingface_hub",
38
+ ]
39
+
40
+ [project.urls]
41
+ Homepage = "https://github.com/clemsgrs/slide2vec"
42
+ "Bug Tracker" = "https://github.com/clemsgrs/slide2vec/issues"
43
+
44
+ [project.scripts]
45
+ slide2vec = "slide2vec.cli:main"
46
+
47
+ [project.optional-dependencies]
48
+ hoptimus = [
49
+ "torch>=2.0",
50
+ "torchvision>=0.15.0",
51
+ "xformers>=0.0.18",
52
+ ]
53
+ virchow = [
54
+ "timm>=0.9.11",
55
+ "torch>=2.0",
56
+ ]
57
+ uni = [
58
+ "torch>=2.0",
59
+ "timm>=0.9.8",
60
+ "xformers>=0.0.18",
61
+ ]
62
+ prism = [
63
+ "transformers~=4.53.0",
64
+ "torch>=2.3,<2.8",
65
+ "einops==0.8.0",
66
+ "environs==11.0.0",
67
+ "sacremoses==0.1.1",
68
+ "xformers==0.0.31",
69
+ ]
70
+ hibou = [
71
+ "scipy~=1.8.1",
72
+ "scikit-image~=0.19.3",
73
+ ]
74
+ titan = [
75
+ "torch==2.0.1",
76
+ "timm==1.0.3",
77
+ "einops==0.6.1",
78
+ "einops-exts==0.0.4",
79
+ "transformers==4.46.0",
80
+ ]
81
+ fm = [
82
+ "omegaconf>=2.3.0",
83
+ "matplotlib",
84
+ "numpy<2",
85
+ "pandas",
86
+ "pillow",
87
+ "rich",
88
+ "hs2p[asap,cucim,openslide,vips]>=3.1.4",
89
+ "wandb",
90
+ "torch>=2.3,<2.8",
91
+ "torchvision>=0.18.0",
92
+ "einops>=0.8.0",
93
+ "timm>=1.0.3",
94
+ "huggingface_hub>=0.30.0,<1.0",
95
+ "environs",
96
+ "einops-exts>=0.0.4",
97
+ "transformers>=4.53",
98
+ "sacremoses",
99
+ "xformers>=0.0.31",
100
+ "scipy>=1.8.1",
101
+ "scikit-image>=0.19.3",
102
+ "torchmetrics>=0.10.3",
103
+ "fvcore",
104
+ "iopath",
105
+ "webdataset",
106
+ "scikit-survival",
107
+ "scikit-learn",
108
+ "fairscale",
109
+ "packaging==23.2",
110
+ "ninja==1.11.1.1",
111
+ "psutil<6",
112
+ ]
113
+ testing = [
114
+ "pytest>=6.0",
115
+ "pytest-cov>=2.0",
116
+ "mypy>=0.910",
117
+ "flake8>=3.9",
118
+ "flake8-pyproject>=1.2.3",
119
+ "tox>=3.24",
120
+ ]
121
+
122
+ [tool.setuptools]
123
+ include-package-data = true
124
+ zip-safe = false
125
+
126
+ [tool.setuptools.packages.find]
127
+ include = ["slide2vec*"]
128
+
129
+ [tool.setuptools.package-data]
130
+ slide2vec = ["py.typed"]
131
+ "slide2vec.configs" = ["*.yaml", "models/*.yaml", "preprocessing/*.yaml"]
132
+
133
+ [tool.pytest.ini_options]
134
+ addopts = "--cov=slide2vec"
135
+ testpaths = [
136
+ "tests",
137
+ ]
138
+
139
+ [tool.mypy]
140
+ mypy_path = "."
141
+ check_untyped_defs = true
142
+ disallow_any_generics = true
143
+ ignore_missing_imports = true
144
+ no_implicit_optional = true
145
+ show_error_codes = true
146
+ strict_equality = true
147
+ warn_redundant_casts = true
148
+ warn_return_any = true
149
+ warn_unreachable = true
150
+ warn_unused_configs = true
151
+ no_implicit_reexport = true
152
+
153
+ [tool.flake8]
154
+ max-line-length = 160
155
+
156
+ [tool.bumpver]
157
+ current_version = "4.0.2"
158
+ version_pattern = "MAJOR.MINOR.PATCH"
159
+ commit = false # We do version bumping in CI, not as a commit
160
+ tag = false # Git tag already exists — we don't auto-tag
161
+ push = false # Don't push anything in CI
162
+ files = [
163
+ "pyproject.toml",
164
+ "slide2vec/__init__.py"
165
+ ]
166
+
167
+ [tool.bumpver.file_patterns]
168
+ "pyproject.toml" = [
169
+ '^current_version = "{version}"$',
170
+ '^version = "{version}"$',
171
+ ]
172
+ "slide2vec/__init__.py" = [
173
+ '^__version__ = "{version}"$',
174
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -1,8 +1,8 @@
1
1
  from slide2vec.api import EmbeddedSlide, ExecutionOptions, Model, Pipeline, PreprocessingConfig, RunResult
2
- from slide2vec.artifacts import SlideEmbeddingArtifact, TileEmbeddingArtifact
2
+ from slide2vec.artifacts import HierarchicalEmbeddingArtifact, SlideEmbeddingArtifact, TileEmbeddingArtifact
3
3
 
4
4
 
5
- __version__ = "3.2.1"
5
+ __version__ = "4.0.2"
6
6
 
7
7
  __all__ = [
8
8
  "Model",
@@ -12,6 +12,7 @@ __all__ = [
12
12
  "RunResult",
13
13
  "EmbeddedSlide",
14
14
  "SlideEmbeddingArtifact",
15
+ "HierarchicalEmbeddingArtifact",
15
16
  "TileEmbeddingArtifact",
16
17
  "__version__",
17
18
  ]