slide2vec 4.6.2__tar.gz → 4.6.3__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.
- {slide2vec-4.6.2 → slide2vec-4.6.3}/PKG-INFO +1 -1
- {slide2vec-4.6.2 → slide2vec-4.6.3}/pyproject.toml +2 -2
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/__init__.py +1 -1
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/utils/config.py +25 -7
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec.egg-info/PKG-INFO +1 -1
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_regression_core.py +28 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/LICENSE +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/README.md +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/setup.cfg +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/__main__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/api.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/artifacts.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/cli.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/configs/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/configs/default.yaml +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/configs/resources.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/data/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/data/dataset.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/data/tile_reader.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/data/tile_store.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/distributed/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/distributed/direct_embed_worker.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/distributed/pipeline_worker.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/base.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/conch.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/gigapath.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/hibou.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/hoptimus.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/lunit.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/midnight.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/moozy/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/moozy/blocks.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/moozy/case.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/moozy/loading.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/moozy/slide.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/moozy/types.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/musk.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/phikon.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/prism.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/prost40m.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/titan.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/uni.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/models/virchow.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/registry.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/encoders/validation.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/inference.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/progress.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/artifacts_collect.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/batching.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/cpu_budget.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/distributed.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/distributed_stage.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/embedding.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/embedding_persist.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/embedding_pipeline.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/hierarchical.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/manifest.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/model_settings.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/patient_pipeline.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/persist_callbacks.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/persistence.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/process_list.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/progress_bridge.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/registry.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/serialization.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/slide_encode.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/tiling.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/tiling_pipeline.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/types.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/runtime/worker_io.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/utils/__init__.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/utils/coordinates.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/utils/log_utils.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/utils/tiling_io.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec/utils/utils.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec.egg-info/SOURCES.txt +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec.egg-info/dependency_links.txt +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec.egg-info/entry_points.txt +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec.egg-info/not-zip-safe +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec.egg-info/requires.txt +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/slide2vec.egg-info/top_level.txt +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_architecture_runtime_split.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_attention_extraction.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_dense_extraction.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_dense_locality_gated.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_encoder_registry.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_hs2p_package_cutover.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_output_consistency.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_progress.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_regression_inference.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_regression_models.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_runtime_batching.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_tile_store.py +0 -0
- {slide2vec-4.6.2 → slide2vec-4.6.3}/tests/test_tiling_pipeline.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "slide2vec"
|
|
7
|
-
version = "4.6.
|
|
7
|
+
version = "4.6.3"
|
|
8
8
|
description = "Embedding of whole slide images with Foundation Models"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -164,7 +164,7 @@ no_implicit_reexport = true
|
|
|
164
164
|
max-line-length = 160
|
|
165
165
|
|
|
166
166
|
[tool.bumpver]
|
|
167
|
-
current_version = "4.6.
|
|
167
|
+
current_version = "4.6.3"
|
|
168
168
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
169
169
|
commit = false # We do version bumping in CI, not as a commit
|
|
170
170
|
tag = false # Git tag already exists — we don't auto-tag
|
|
@@ -41,6 +41,21 @@ def _encoder_derived_cfg(model_name: str) -> dict:
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
|
|
44
|
+
def _fill_null_encoder_defaults(cfg, encoder_defaults: dict) -> None:
|
|
45
|
+
"""Fill null leaves with encoder defaults after user/CLI config merging."""
|
|
46
|
+
defaults_cfg = OmegaConf.create(encoder_defaults)
|
|
47
|
+
for path in (
|
|
48
|
+
"tiling.params.requested_tile_size_px",
|
|
49
|
+
"tiling.params.requested_spacing_um",
|
|
50
|
+
"speed.precision",
|
|
51
|
+
):
|
|
52
|
+
if OmegaConf.select(cfg, path) is not None:
|
|
53
|
+
continue
|
|
54
|
+
default_value = OmegaConf.select(defaults_cfg, path)
|
|
55
|
+
if default_value is not None:
|
|
56
|
+
OmegaConf.update(cfg, path, default_value, merge=False)
|
|
57
|
+
|
|
58
|
+
|
|
44
59
|
def validate_model_recommended_settings(cfg, *, run_on_cpu: bool = False) -> None:
|
|
45
60
|
from slide2vec.encoders.registry import encoder_registry
|
|
46
61
|
from slide2vec.encoders.validation import validate_encoder_config
|
|
@@ -88,14 +103,17 @@ def get_cfg_from_args(args):
|
|
|
88
103
|
|
|
89
104
|
default_cfg = OmegaConf.create(default_config)
|
|
90
105
|
model_name = OmegaConf.select(requested_cfg, "model.name")
|
|
91
|
-
spacing = OmegaConf.select(requested_cfg, "tiling.params.requested_spacing_um")
|
|
92
|
-
tile_size = OmegaConf.select(requested_cfg, "tiling.params.requested_tile_size_px")
|
|
93
|
-
if model_name and (spacing is None or tile_size is None):
|
|
94
|
-
encoder_defaults = _encoder_derived_cfg(model_name)
|
|
95
|
-
if encoder_defaults:
|
|
96
|
-
default_cfg = OmegaConf.merge(default_cfg, OmegaConf.create(encoder_defaults))
|
|
97
|
-
|
|
98
106
|
cfg = OmegaConf.merge(default_cfg, user_cfg, cli_cfg)
|
|
107
|
+
if model_name and any(
|
|
108
|
+
OmegaConf.select(cfg, path) is None
|
|
109
|
+
for path in (
|
|
110
|
+
"tiling.params.requested_tile_size_px",
|
|
111
|
+
"tiling.params.requested_spacing_um",
|
|
112
|
+
"speed.precision",
|
|
113
|
+
)
|
|
114
|
+
):
|
|
115
|
+
encoder_defaults = _encoder_derived_cfg(model_name)
|
|
116
|
+
_fill_null_encoder_defaults(cfg, encoder_defaults)
|
|
99
117
|
OmegaConf.resolve(cfg)
|
|
100
118
|
validate_model_recommended_settings(cfg, run_on_cpu=bool(getattr(args, "run_on_cpu", False)))
|
|
101
119
|
return cfg
|
|
@@ -79,6 +79,34 @@ def test_get_cfg_from_args_fills_missing_preprocessing_from_single_spacing_model
|
|
|
79
79
|
assert cfg.tiling.params.requested_tile_size_px == 448
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
def test_get_cfg_from_args_fills_null_spacing_from_model_default(tmp_path: Path):
|
|
83
|
+
pytest.importorskip("omegaconf")
|
|
84
|
+
|
|
85
|
+
from slide2vec.utils.config import get_cfg_from_args
|
|
86
|
+
|
|
87
|
+
cfg_path = tmp_path / "config.yaml"
|
|
88
|
+
cfg_path.write_text(
|
|
89
|
+
"\n".join(
|
|
90
|
+
[
|
|
91
|
+
"csv: /tmp/slides.csv",
|
|
92
|
+
"output_dir: /tmp/output",
|
|
93
|
+
"model:",
|
|
94
|
+
" name: conchv15",
|
|
95
|
+
"tiling:",
|
|
96
|
+
" params:",
|
|
97
|
+
" requested_spacing_um:",
|
|
98
|
+
" requested_tile_size_px: 448",
|
|
99
|
+
]
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
args = SimpleNamespace(config_file=str(cfg_path), output_dir=None, opts=[], run_on_cpu=False)
|
|
103
|
+
|
|
104
|
+
cfg = get_cfg_from_args(args)
|
|
105
|
+
|
|
106
|
+
assert cfg.tiling.params.requested_spacing_um == pytest.approx(0.5)
|
|
107
|
+
assert cfg.tiling.params.requested_tile_size_px == 448
|
|
108
|
+
|
|
109
|
+
|
|
82
110
|
def test_get_cfg_from_args_rejects_models_with_ambiguous_spacing_defaults(tmp_path: Path):
|
|
83
111
|
pytest.importorskip("omegaconf")
|
|
84
112
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|