T1Prep 0.3.8__py3-none-any.whl
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.
- t1prep/__init__.py +25 -0
- t1prep/_models.py +222 -0
- t1prep/_segment_utils.py +1031 -0
- t1prep/data/Names.tsv +44 -0
- t1prep/data/__init__.py +1 -0
- t1prep/data/atlases_surfaces_32k/atlases_surfaces_32k.md +68 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_100Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_100Parcels_17Networks_order.txt +17 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_200Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_200Parcels_17Networks_order.txt +17 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_400Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_400Parcels_17Networks_order.txt +17 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_600Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/lh.Schaefer2018_600Parcels_17Networks_order.txt +17 -0
- t1prep/data/atlases_surfaces_32k/lh.aparc_DK40.freesurfer.annot +0 -0
- t1prep/data/atlases_surfaces_32k/lh.aparc_DK40.freesurfer.txt +13 -0
- t1prep/data/atlases_surfaces_32k/lh.aparc_HCP_MMP1.freesurfer.annot +0 -0
- t1prep/data/atlases_surfaces_32k/lh.aparc_HCP_MMP1.freesurfer.txt +14 -0
- t1prep/data/atlases_surfaces_32k/lh.aparc_a2009s.freesurfer.annot +0 -0
- t1prep/data/atlases_surfaces_32k/lh.aparc_a2009s.freesurfer.txt +12 -0
- t1prep/data/atlases_surfaces_32k/rh.Schaefer2018_100Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/rh.Schaefer2018_200Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/rh.Schaefer2018_400Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/rh.Schaefer2018_600Parcels_17Networks_order.annot +0 -0
- t1prep/data/atlases_surfaces_32k/rh.aparc_DK40.freesurfer.annot +0 -0
- t1prep/data/atlases_surfaces_32k/rh.aparc_HCP_MMP1.freesurfer.annot +0 -0
- t1prep/data/atlases_surfaces_32k/rh.aparc_a2009s.freesurfer.annot +0 -0
- t1prep/data/cat_viewsurf_defaults.txt +36 -0
- t1prep/data/icon.png +0 -0
- t1prep/data/patches.csv +28 -0
- t1prep/data/templates_MNI152NLin2009cAsym/AAL3.csv +171 -0
- t1prep/data/templates_MNI152NLin2009cAsym/AAL3.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/AAL3.txt +50 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Anatomy3.csv +187 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Anatomy3.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Anatomy3.txt +135 -0
- t1prep/data/templates_MNI152NLin2009cAsym/CoBra.csv +53 -0
- t1prep/data/templates_MNI152NLin2009cAsym/CoBra.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/CoBra.txt +154 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Hammers.csv +96 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Hammers.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Hammers.txt +55 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Hypothalamus.csv +51 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Hypothalamus.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Hypothalamus.txt +9 -0
- t1prep/data/templates_MNI152NLin2009cAsym/IBSR.csv +33 -0
- t1prep/data/templates_MNI152NLin2009cAsym/IBSR.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/IBSR.txt +577 -0
- t1prep/data/templates_MNI152NLin2009cAsym/JulichBrain.csv +249 -0
- t1prep/data/templates_MNI152NLin2009cAsym/JulichBrain.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/JulichBrain.txt +23 -0
- t1prep/data/templates_MNI152NLin2009cAsym/LPBA40.csv +57 -0
- t1prep/data/templates_MNI152NLin2009cAsym/LPBA40.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/LPBA40.txt +50 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Melbourne-Subcortex-Atlas-7T.csv +63 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Melbourne-Subcortex-Atlas-7T.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Melbourne-Subcortex-Atlas-7T.txt +24 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Mori.csv +129 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Mori.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Mori.txt +32 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Neuromorphometrics.csv +137 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Neuromorphometrics.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Neuromorphometrics.txt +140 -0
- t1prep/data/templates_MNI152NLin2009cAsym/SUIT.csv +29 -0
- t1prep/data/templates_MNI152NLin2009cAsym/SUIT.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/SUIT.txt +16 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_100Parcels_17Networks_order.csv +101 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_100Parcels_17Networks_order.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_100Parcels_17Networks_order.txt +17 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_200Parcels_17Networks_order.csv +201 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_200Parcels_17Networks_order.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_200Parcels_17Networks_order.txt +17 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_400Parcels_17Networks_order.csv +401 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_400Parcels_17Networks_order.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_400Parcels_17Networks_order.txt +17 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_600Parcels_17Networks_order.csv +601 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_600Parcels_17Networks_order.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Schaefer2018_600Parcels_17Networks_order.txt +17 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Template_05mm_bet.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Template_4_GS.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Thalamic-Nuclei.csv +25 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Thalamic-Nuclei.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Thalamic-Nuclei.txt +33 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Thalamus.csv +15 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Thalamus.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/Thalamus.txt +39 -0
- t1prep/data/templates_MNI152NLin2009cAsym/cat_bloodvessels.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/cat_wmh.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/cat_wmh_miccai2017.nii.gz +0 -0
- t1prep/data/templates_MNI152NLin2009cAsym/csf_TPM.nii.gz +0 -0
- t1prep/data/templates_surfaces_32k/fsavg.index2D_256x128.txt +32768 -0
- t1prep/data/templates_surfaces_32k/lh.central.Template_T1.gii +77 -0
- t1prep/data/templates_surfaces_32k/lh.central.freesurfer.gii +114 -0
- t1prep/data/templates_surfaces_32k/lh.inflated.freesurfer.gii +73 -0
- t1prep/data/templates_surfaces_32k/lh.mask +0 -0
- t1prep/data/templates_surfaces_32k/lh.mc.freesurfer.gii +32 -0
- t1prep/data/templates_surfaces_32k/lh.patch.freesurfer.gii +66 -0
- t1prep/data/templates_surfaces_32k/lh.sphere.freesurfer.gii +126 -0
- t1prep/data/templates_surfaces_32k/lh.sqrtsulc.freesurfer.gii +32 -0
- t1prep/data/templates_surfaces_32k/lh.thickness.Template_T1 +0 -0
- t1prep/data/templates_surfaces_32k/mesh.central.Template_T1.gii +39 -0
- t1prep/data/templates_surfaces_32k/mesh.central.freesurfer.gii +39 -0
- t1prep/data/templates_surfaces_32k/mesh.inflated.freesurfer.gii +39 -0
- t1prep/data/templates_surfaces_32k/rh.central.Template_T1.gii +77 -0
- t1prep/data/templates_surfaces_32k/rh.central.freesurfer.gii +114 -0
- t1prep/data/templates_surfaces_32k/rh.inflated.freesurfer.gii +73 -0
- t1prep/data/templates_surfaces_32k/rh.mask +0 -0
- t1prep/data/templates_surfaces_32k/rh.mc.freesurfer.gii +32 -0
- t1prep/data/templates_surfaces_32k/rh.patch.freesurfer.gii +74 -0
- t1prep/data/templates_surfaces_32k/rh.sphere.freesurfer.gii +126 -0
- t1prep/data/templates_surfaces_32k/rh.sqrtsulc.freesurfer.gii +32 -0
- t1prep/data/templates_surfaces_32k/rh.thickness.Template_T1 +0 -0
- t1prep/data/templates_surfaces_32k/templates_surfaces_32k.md +75 -0
- t1prep/data/templates_surfaces_4k/lh.central.freesurfer.gii +77 -0
- t1prep/data/templates_surfaces_4k/lh.inflated.freesurfer.gii +73 -0
- t1prep/data/templates_surfaces_4k/lh.mask +0 -0
- t1prep/data/templates_surfaces_4k/lh.sphere.freesurfer.gii +90 -0
- t1prep/data/templates_surfaces_4k/rh.central.freesurfer.gii +77 -0
- t1prep/data/templates_surfaces_4k/rh.inflated.freesurfer.gii +73 -0
- t1prep/data/templates_surfaces_4k/rh.mask +0 -0
- t1prep/data/templates_surfaces_4k/rh.sphere.freesurfer.gii +78 -0
- t1prep/dice.py +19 -0
- t1prep/gui/__init__.py +11 -0
- t1prep/gui/cat_viewimage.py +1241 -0
- t1prep/gui/cat_viewsurf.py +4043 -0
- t1prep/metrics.py +407 -0
- t1prep/qa.py +625 -0
- t1prep/realign_longitudinal.py +734 -0
- t1prep/report.py +126 -0
- t1prep/segment.py +1491 -0
- t1prep/surface_estimation.py +632 -0
- t1prep/t1prep.py +229 -0
- t1prep/utils.py +730 -0
- t1prep-0.3.8.dist-info/METADATA +765 -0
- t1prep-0.3.8.dist-info/RECORD +139 -0
- t1prep-0.3.8.dist-info/WHEEL +5 -0
- t1prep-0.3.8.dist-info/entry_points.txt +3 -0
- t1prep-0.3.8.dist-info/licenses/LICENSE +201 -0
- t1prep-0.3.8.dist-info/top_level.txt +1 -0
t1prep/__init__.py
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
__version__ = "0.3.8"
|
|
2
|
+
|
|
3
|
+
from .t1prep import run_t1prep
|
|
4
|
+
from .utils import (
|
|
5
|
+
progress_bar,
|
|
6
|
+
remove_file,
|
|
7
|
+
resample_and_save_nifti,
|
|
8
|
+
get_resampled_header,
|
|
9
|
+
align_brain,
|
|
10
|
+
get_filenames,
|
|
11
|
+
get_volume_native_space,
|
|
12
|
+
)
|
|
13
|
+
from .metrics import compute_dice_nifti
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"run_t1prep",
|
|
17
|
+
"progress_bar",
|
|
18
|
+
"remove_file",
|
|
19
|
+
"resample_and_save_nifti",
|
|
20
|
+
"get_resampled_header",
|
|
21
|
+
"align_brain",
|
|
22
|
+
"get_filenames",
|
|
23
|
+
"get_volume_native_space",
|
|
24
|
+
"compute_dice_nifti",
|
|
25
|
+
]
|
t1prep/_models.py
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"""Model file management: location constants, presence checks, and downloading.
|
|
2
|
+
|
|
3
|
+
Model weights are not bundled in the PyPI wheel (they exceed the 100 MB
|
|
4
|
+
limit). This module is responsible for locating the model directory,
|
|
5
|
+
checking whether all required files are present, and downloading them from
|
|
6
|
+
the GitHub release asset when they are missing.
|
|
7
|
+
|
|
8
|
+
The download can be triggered:
|
|
9
|
+
- automatically at first use (called by ``segment.py``)
|
|
10
|
+
- manually by the user via the ``t1prep-download-models`` console script
|
|
11
|
+
|
|
12
|
+
Console script entry point: ``t1prep._models:main``
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import shutil
|
|
18
|
+
import sys
|
|
19
|
+
import tempfile
|
|
20
|
+
import urllib.request
|
|
21
|
+
import zipfile
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
from deepmriprep.utils import DATA_PATH
|
|
25
|
+
|
|
26
|
+
# ---------------------------------------------------------------------------
|
|
27
|
+
# Constants
|
|
28
|
+
# ---------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
#: Directory where model weight files are stored at runtime.
|
|
31
|
+
MODEL_DIR: Path = Path(DATA_PATH) / "models"
|
|
32
|
+
|
|
33
|
+
#: All model filenames that must be present for the pipeline to run.
|
|
34
|
+
MODEL_FILES: list[str] = (
|
|
35
|
+
[
|
|
36
|
+
"brain_extraction_bbox_model.pt",
|
|
37
|
+
"brain_extraction_model.pt",
|
|
38
|
+
"segmentation_nogm_model.pt",
|
|
39
|
+
]
|
|
40
|
+
+ [f"segmentation_patch_{i}_model.pt" for i in range(18)]
|
|
41
|
+
+ ["segmentation_model.pt", "warp_model.pt"]
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
#: URL of the GitHub release archive that contains the model weights.
|
|
45
|
+
#: Override with the ``T1PREP_MODEL_ZIP_URL`` environment variable if needed.
|
|
46
|
+
import os as _os
|
|
47
|
+
_DEFAULT_MODEL_ZIP_URL = (
|
|
48
|
+
"https://github.com/ChristianGaser/T1Prep/releases/download/"
|
|
49
|
+
"v0.2.0-beta/T1Prep_Models.zip"
|
|
50
|
+
)
|
|
51
|
+
MODEL_ZIP_URL: str = _os.environ.get("T1PREP_MODEL_ZIP_URL", _DEFAULT_MODEL_ZIP_URL)
|
|
52
|
+
|
|
53
|
+
#: Dev-mode fallback: models bundled inside the source tree (not in the wheel).
|
|
54
|
+
_DEV_MODEL_DIR: Path = Path(__file__).resolve().parent / "data" / "models"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# ---------------------------------------------------------------------------
|
|
58
|
+
# Helpers
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def all_models_present() -> bool:
|
|
63
|
+
"""Return ``True`` if every required model file exists in :data:`MODEL_DIR`."""
|
|
64
|
+
return all((MODEL_DIR / f).exists() for f in MODEL_FILES)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _download_with_progress(url: str, dest: Path) -> None:
|
|
68
|
+
"""Download *url* to *dest*, printing a simple progress indicator."""
|
|
69
|
+
|
|
70
|
+
def _reporthook(count: int, block_size: int, total_size: int) -> None:
|
|
71
|
+
if total_size <= 0:
|
|
72
|
+
print(f"\r Downloaded {count * block_size // 1_048_576} MB ...", end="", flush=True)
|
|
73
|
+
else:
|
|
74
|
+
downloaded = count * block_size
|
|
75
|
+
pct = min(100, int(100 * downloaded / total_size))
|
|
76
|
+
bar = "#" * (pct // 2) + "-" * (50 - pct // 2)
|
|
77
|
+
mb_done = downloaded // 1_048_576
|
|
78
|
+
mb_total = total_size // 1_048_576
|
|
79
|
+
print(f"\r [{bar}] {pct:3d}% ({mb_done}/{mb_total} MB)", end="", flush=True)
|
|
80
|
+
|
|
81
|
+
urllib.request.urlretrieve(url, str(dest), reporthook=_reporthook)
|
|
82
|
+
print() # newline after progress bar
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def download_models(verbose: bool = True) -> None:
|
|
86
|
+
"""Download model weights from GitHub and extract them to :data:`MODEL_DIR`.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
verbose:
|
|
91
|
+
When ``True`` (default) print progress to stdout.
|
|
92
|
+
"""
|
|
93
|
+
MODEL_DIR.mkdir(parents=True, exist_ok=True)
|
|
94
|
+
|
|
95
|
+
if verbose:
|
|
96
|
+
print(f"Downloading model weights from:\n {MODEL_ZIP_URL}")
|
|
97
|
+
|
|
98
|
+
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
99
|
+
zip_path = Path(tmp_dir) / "T1Prep_Models.zip"
|
|
100
|
+
try:
|
|
101
|
+
_download_with_progress(MODEL_ZIP_URL, zip_path)
|
|
102
|
+
except Exception as exc:
|
|
103
|
+
raise RuntimeError(
|
|
104
|
+
f"Failed to download model weights from {MODEL_ZIP_URL}: {exc}\n"
|
|
105
|
+
"Check your internet connection or set the T1PREP_MODEL_ZIP_URL "
|
|
106
|
+
"environment variable to an alternative URL."
|
|
107
|
+
) from exc
|
|
108
|
+
|
|
109
|
+
if verbose:
|
|
110
|
+
print(f"Extracting to {MODEL_DIR} ...")
|
|
111
|
+
|
|
112
|
+
with zipfile.ZipFile(zip_path, "r") as zf:
|
|
113
|
+
for member in zf.namelist():
|
|
114
|
+
filename = Path(member).name
|
|
115
|
+
if not filename or filename not in MODEL_FILES:
|
|
116
|
+
continue
|
|
117
|
+
dest = MODEL_DIR / filename
|
|
118
|
+
with zf.open(member) as src, open(dest, "wb") as out:
|
|
119
|
+
shutil.copyfileobj(src, out)
|
|
120
|
+
|
|
121
|
+
if verbose:
|
|
122
|
+
print("Model weights downloaded successfully.")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# ---------------------------------------------------------------------------
|
|
126
|
+
# Public API
|
|
127
|
+
# ---------------------------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def prepare_model_files(verbose: bool = True) -> None:
|
|
131
|
+
"""Ensure all model weight files are present, downloading if necessary.
|
|
132
|
+
|
|
133
|
+
Strategy (in order):
|
|
134
|
+
1. If all files already exist in :data:`MODEL_DIR` → nothing to do.
|
|
135
|
+
2. Dev-mode: if the source-tree ``data/models/`` directory is populated
|
|
136
|
+
(e.g. a git clone with model files present), copy missing files from
|
|
137
|
+
there — avoids a network round-trip during development.
|
|
138
|
+
3. Download the model archive from GitHub and extract to :data:`MODEL_DIR`.
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
verbose:
|
|
143
|
+
When ``True`` (default) print progress to stdout.
|
|
144
|
+
"""
|
|
145
|
+
if all_models_present():
|
|
146
|
+
return
|
|
147
|
+
|
|
148
|
+
MODEL_DIR.mkdir(parents=True, exist_ok=True)
|
|
149
|
+
|
|
150
|
+
# --- dev-mode: copy from source tree if available ---
|
|
151
|
+
if _DEV_MODEL_DIR.is_dir():
|
|
152
|
+
missing = [f for f in MODEL_FILES if not (MODEL_DIR / f).exists()]
|
|
153
|
+
copied = []
|
|
154
|
+
for filename in missing:
|
|
155
|
+
src = _DEV_MODEL_DIR / filename
|
|
156
|
+
if src.exists():
|
|
157
|
+
shutil.copy2(str(src), str(MODEL_DIR / filename))
|
|
158
|
+
copied.append(filename)
|
|
159
|
+
if copied and verbose:
|
|
160
|
+
print(f"Copied {len(copied)} model file(s) from local data directory.")
|
|
161
|
+
if all_models_present():
|
|
162
|
+
return
|
|
163
|
+
|
|
164
|
+
# --- download from GitHub ---
|
|
165
|
+
if verbose:
|
|
166
|
+
missing_count = sum(1 for f in MODEL_FILES if not (MODEL_DIR / f).exists())
|
|
167
|
+
print(f"{missing_count} model file(s) missing — downloading from GitHub ...")
|
|
168
|
+
download_models(verbose=verbose)
|
|
169
|
+
|
|
170
|
+
if not all_models_present():
|
|
171
|
+
still_missing = [f for f in MODEL_FILES if not (MODEL_DIR / f).exists()]
|
|
172
|
+
raise RuntimeError(
|
|
173
|
+
"Model download completed but the following files are still missing:\n"
|
|
174
|
+
+ "\n".join(f" {MODEL_DIR / f}" for f in still_missing)
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def main() -> None:
|
|
179
|
+
"""Console script entry point for ``t1prep-download-models``.
|
|
180
|
+
|
|
181
|
+
Downloads model weights to :data:`MODEL_DIR` if not already present.
|
|
182
|
+
Pass ``--force`` to re-download even if models are present.
|
|
183
|
+
"""
|
|
184
|
+
import argparse
|
|
185
|
+
|
|
186
|
+
parser = argparse.ArgumentParser(
|
|
187
|
+
description="Download T1Prep model weights from GitHub.",
|
|
188
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
189
|
+
)
|
|
190
|
+
parser.add_argument(
|
|
191
|
+
"--force",
|
|
192
|
+
action="store_true",
|
|
193
|
+
help="Re-download model weights even if they are already present.",
|
|
194
|
+
)
|
|
195
|
+
parser.add_argument(
|
|
196
|
+
"--model-dir",
|
|
197
|
+
type=str,
|
|
198
|
+
default=None,
|
|
199
|
+
help="Override the target directory for model weights.",
|
|
200
|
+
)
|
|
201
|
+
args = parser.parse_args()
|
|
202
|
+
|
|
203
|
+
if args.model_dir is not None:
|
|
204
|
+
global MODEL_DIR
|
|
205
|
+
MODEL_DIR = Path(args.model_dir)
|
|
206
|
+
|
|
207
|
+
if args.force and MODEL_DIR.exists():
|
|
208
|
+
print(f"--force: removing existing models in {MODEL_DIR}")
|
|
209
|
+
for f in MODEL_FILES:
|
|
210
|
+
p = MODEL_DIR / f
|
|
211
|
+
if p.exists():
|
|
212
|
+
p.unlink()
|
|
213
|
+
|
|
214
|
+
if all_models_present() and not args.force:
|
|
215
|
+
print(f"All model weights already present in {MODEL_DIR}")
|
|
216
|
+
sys.exit(0)
|
|
217
|
+
|
|
218
|
+
try:
|
|
219
|
+
prepare_model_files(verbose=True)
|
|
220
|
+
except RuntimeError as exc:
|
|
221
|
+
print(f"Error: {exc}", file=sys.stderr)
|
|
222
|
+
sys.exit(1)
|