seqseg 2.1.7__tar.gz → 2.1.8__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 (83) hide show
  1. {seqseg-2.1.7 → seqseg-2.1.8}/PKG-INFO +28 -51
  2. seqseg-2.1.8/README.md +114 -0
  3. {seqseg-2.1.7 → seqseg-2.1.8}/pyproject.toml +1 -1
  4. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/cli.py +75 -34
  5. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/train.py +349 -43
  6. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_cli_helpers.py +58 -13
  7. seqseg-2.1.8/seqseg/tests/test_train_data.py +95 -0
  8. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_train_pipeline.py +290 -68
  9. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg.egg-info/PKG-INFO +28 -51
  10. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg.egg-info/SOURCES.txt +1 -0
  11. seqseg-2.1.7/README.md +0 -137
  12. {seqseg-2.1.7 → seqseg-2.1.8}/LICENSE +0 -0
  13. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/__init__.py +0 -0
  14. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/api.py +0 -0
  15. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/citations.py +0 -0
  16. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/__init__.py +0 -0
  17. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/aorta_tutorial.yaml +0 -0
  18. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global.yaml +0 -0
  19. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_aorta.yaml +0 -0
  20. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_cereb.yaml +0 -0
  21. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_coro.yaml +0 -0
  22. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_debug.yaml +0 -0
  23. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_default.yaml +0 -0
  24. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_pulm.yaml +0 -0
  25. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_seg.yaml +0 -0
  26. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config/global_test.yaml +0 -0
  27. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/config_models.py +0 -0
  28. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/__init__.py +0 -0
  29. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/assembly.py +0 -0
  30. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/capping.py +0 -0
  31. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/centerline.py +0 -0
  32. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/datasets.py +0 -0
  33. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/evaluation.py +0 -0
  34. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/initialization.py +0 -0
  35. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/local_assembly.py +0 -0
  36. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/nnunet.py +0 -0
  37. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/params.py +0 -0
  38. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/prediction.py +0 -0
  39. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/simvascular.py +0 -0
  40. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/simvascular_contour.py +0 -0
  41. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/sitk_functions.py +0 -0
  42. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/sweep.py +0 -0
  43. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/tracing.py +0 -0
  44. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/tracing_functions.py +0 -0
  45. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/vmtk_functions.py +0 -0
  46. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/modules/vtk_functions.py +0 -0
  47. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/parallel/old_auto_centerline.py +0 -0
  48. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline.py +0 -0
  49. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline2.py +0 -0
  50. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline3.py +0 -0
  51. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/parallel/parallel_auto_centerline4.py +0 -0
  52. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/__init__.py +0 -0
  53. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/classic.py +0 -0
  54. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/config.py +0 -0
  55. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/directories.py +0 -0
  56. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/plus.py +0 -0
  57. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/post.py +0 -0
  58. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/pipeline/single_trace.py +0 -0
  59. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/scripts/__init__.py +0 -0
  60. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/scripts/prepare_casx_dataset.py +0 -0
  61. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/scripts/taubin_smooth.py +0 -0
  62. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/seqseg.py +0 -0
  63. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/seqseg_plus.py +0 -0
  64. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/conftest.py +0 -0
  65. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_api_entry.py +0 -0
  66. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_centerline_get_end_points.py +0 -0
  67. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_centerline_gradient.py +0 -0
  68. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_datasets_paths.py +0 -0
  69. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_nnunet2.py +0 -0
  70. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_nnunet_device.py +0 -0
  71. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_prepare_casx_dataset.py +0 -0
  72. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_resample_spacing.py +0 -0
  73. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_segmentation.py +0 -0
  74. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_single_trace_staging.py +0 -0
  75. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_start_seg.py +0 -0
  76. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_user_paths.py +0 -0
  77. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/tests/test_vtk.py +0 -0
  78. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg/user_paths.py +0 -0
  79. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg.egg-info/dependency_links.txt +0 -0
  80. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg.egg-info/entry_points.txt +0 -0
  81. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg.egg-info/requires.txt +0 -0
  82. {seqseg-2.1.7 → seqseg-2.1.8}/seqseg.egg-info/top_level.txt +0 -0
  83. {seqseg-2.1.7 → seqseg-2.1.8}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: seqseg
3
- Version: 2.1.7
3
+ Version: 2.1.8
4
4
  Summary: A deep learning-based medical image blood vessel tracking and segmentation tool.
5
5
  Author-email: Numi Sveinsson Cepero <numi@berkeley.com>
6
6
  License: Apache-2.0
@@ -30,8 +30,8 @@ Provides-Extra: viz
30
30
  Requires-Dist: matplotlib>=3.5; extra == "viz"
31
31
  Dynamic: license-file
32
32
 
33
- ![example workflow](https://github.com/numisveinsson/SeqSeg/actions/workflows/python-app.yml/badge.svg)
34
- ![example workflow](https://github.com/numisveinsson/SeqSeg/actions/workflows/test.yml/badge.svg)
33
+ ![test seqseg without torch build](https://github.com/numisveinsson/SeqSeg/actions/workflows/python-app.yml/badge.svg)
34
+ ![test seqseg build](https://github.com/numisveinsson/SeqSeg/actions/workflows/test.yml/badge.svg)
35
35
 
36
36
  <p align="center">
37
37
  <img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/seqseg_logo.png" alt="SeqSeg — Sequential Vessel Segmentation" width="480"/><br/>
@@ -50,10 +50,6 @@ Dynamic: license-file
50
50
  <a href="https://www.python.org"><img src="https://img.shields.io/badge/Python-3.9%2B-blue.svg" alt="Python 3.9+"/></a>
51
51
  </p>
52
52
 
53
- > **News:** SeqSeg writes a full SimVascular project in the `simvascular/` subdirectory — open it directly in SimVascular with pathlines and contours for every segmented branch.
54
-
55
- ---
56
-
57
53
  ## Why SeqSeg?
58
54
 
59
55
  SeqSeg segments vessels **sequentially**, taking steps along vessel centerlines and detecting bifurcations to grow complete vascular trees from just **1–2 seed points**. By combining local deep-learning predictions (nnU-Net) with geometric tracking, it stays robust across vessel scales — from small coronaries to large aortas.
@@ -65,57 +61,38 @@ SeqSeg segments vessels **sequentially**, taking steps along vessel centerlines
65
61
  - ✅ **Clinically validated** — coronary, aortic, cerebral, and pulmonary anatomies (pre-trained weights for aorta CT/MR and coronary CT)
66
62
  - ⚡ **Fast** — on CPU, about 2–5 minutes for an aorta, 5–15 for a coronary tree, and 10–30 for a cerebral tree. GPU is faster. Details in [Benchmarks](docs/benchmarks.md).
67
63
 
64
+ A finished case includes a `simvascular/` project you can open directly in SimVascular, with pathlines and contours for every segmented branch.
65
+
68
66
  <p align="center">
69
67
  <img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/mr_model_tracing_fast_shorter.gif" alt="SeqSeg Demo"/><br/>
70
68
  <i>Real-time demonstration: automatic segmentation of an abdominal aorta in a 3D MR scan.</i>
71
69
  </p>
72
70
 
73
- ## What's new in 2.x
74
-
75
- SeqSeg **2.0** uses subcommands. A command from 1.x that starts with a flag, such as `seqseg -data_dir ...`, still runs: it is rewritten to `seqseg run batch` automatically.
76
-
77
- ### Commands
78
-
79
- | Command | Description |
80
- | -------- | ----------- |
81
- | **`seqseg run batch`** | Dataset batch tracing |
82
- | **`seqseg run single`** | One volume and seeds. Stages files under `<outdir>/_seqseg_single_staging/`, then traces |
83
- | **`seqseg run plus batch`** | Global nnU-Net sweep, then SeqSeg |
84
- | **`seqseg init dataset`** | Create `images/`, `centerlines/`, `truths/`, and a template `seeds.json` |
85
- | **`seqseg paths init` / `set` / `show`** | Save default nnU-Net, data, and output directories in `~/.seqseg/paths.yaml` |
86
- | **`seqseg train prepare`** | Extract patches or whole volumes and build an nnU-Net dataset |
87
- | **`seqseg train nnunet`** | Run nnU-Net planning, preprocessing, and training |
88
- | **`seqseg doctor`** | Check imports (SimpleITK, vtk, nnunetv2, scipy, vascular-segment-sampler) and paths |
89
- | **`seqseg config dump` / `fingerprint`** | Print a packaged YAML config, or list keys that differ from another |
90
- | **`seqseg post global-centerline`** | Build global centerlines from existing segmentations |
91
- | **`seqseg simvascular init`** | Create or refresh a SimVascular project under a case directory |
92
- | **`seqseg --version`** | Print the installed version |
93
-
94
- `seqseg run batch` flags use underscores (`-outdir` / `--outdir`). The data folder is `-data_dir` or `--data_directory`. `seqseg run single`, `seqseg train`, and `seqseg paths` use hyphens (`--image`, `--data-dir`).
71
+ ## Start here
95
72
 
96
- ### Migrating from 1.x
97
-
98
- 1. Prefer `seqseg run batch`. The old flag-only form still works.
99
- 2. Use `seqseg run plus batch` in place of `python -m seqseg.seqseg_plus`. The nnU-Net path flags are unchanged.
100
- 3. Check the install with `seqseg --version` after `pip install -U seqseg`.
73
+ - **First segmentation** — the [tutorial](seqseg/tutorial/tutorial.md) runs a sample abdominal-aorta MR scan.
74
+ - **Your own images** — [Usage](docs/usage.md) describes `images/` and `seeds.json`. The command is in [Quick Start](#quick-start).
75
+ - **Train a model** — [Training](docs/training.md).
101
76
 
102
77
  ## Quick Start
103
78
 
104
79
  Python 3.9 or newer. 3.11 is the version used in the tutorial and conda example.
105
80
 
81
+ The [tutorial](seqseg/tutorial/tutorial.md) is the sample run (abdominal-aorta MR, seed points, and Windows notes). Plan on 15–20 minutes including setup. Tracing is capped, so that part finishes in a few minutes; a real case should use the defaults.
82
+
83
+ Install SeqSeg and the aorta weights below, then run `seqseg run batch` on your own data. The folder needs `images/` and `seeds.json` ([Usage](docs/usage.md)). This example is an aorta MR case. Change `-train_dataset`, `-config_name`, and `-img_ext` to match your images and weights.
84
+
106
85
  ```bash
107
86
  pip install seqseg
108
87
 
109
- # Aorta and femoral weights (MR and CT). Coronary weights are a separate zip; see Installation.
88
+ # Aorta and femoral weights (MR and CT)
110
89
  curl -L -o nnUNet_results.zip https://zenodo.org/records/15020477/files/nnUNet_results.zip
111
90
  unzip nnUNet_results.zip
112
91
  ```
113
92
 
114
- `-nnunet_results_path` is the folder that contains `Dataset005_SEQAORTANDFEMOMR` (and the other dataset folders in that zip).
115
-
116
- **First run:** follow the [step-by-step tutorial](seqseg/tutorial/tutorial.md). It includes an abdominal-aorta MR scan, seed points, and Windows notes. The tutorial caps the number of steps so the example finishes in a few minutes; a real case should use the defaults.
93
+ [Aorta and femoral weights](https://zenodo.org/records/15020477) (`nnUNet_results.zip`). [Coronary CT weights](https://zenodo.org/records/19547894) are a separate archive, `nnUNet_results_coronary.zip`.
117
94
 
118
- **Your own data** needs `images/` and `seeds.json` (see [Usage](docs/usage.md)). This command is an aorta MR case. Change `-train_dataset`, `-config_name`, and `-img_ext` to match your images and weights:
95
+ `-nnunet_results_path` is the folder that contains `Dataset005_SEQAORTANDFEMOMR` (and the other dataset folders in that zip).
119
96
 
120
97
  ```bash
121
98
  seqseg run batch \
@@ -133,21 +110,21 @@ seqseg run batch \
133
110
  | Aorta / femoral CT | `Dataset006_SEQAORTANDFEMOCT` | `global_aorta` |
134
111
  | Coronary CT | `Dataset010_SEQCOROASOCACT` | `global_coro` |
135
112
 
136
- The tutorial uses `-config_name aorta_tutorial` for its sample scan. Download links and the trainer-folder layout are in [Installation](docs/installation.md).
113
+ The tutorial uses `-config_name aorta_tutorial` for its sample scan. The trainer-folder layout is in [Installation](docs/installation.md). The full command list and flag spelling are in [Usage](docs/usage.md).
137
114
 
138
115
  ## Documentation
139
116
 
140
- | Guide | Description |
141
- |-------|-------------|
142
- | [Installation](docs/installation.md) | Setup, dependencies, and pre-trained model weights |
143
- | [Tutorial](seqseg/tutorial/tutorial.md) | End-to-end aorta example with sample data |
144
- | [Usage](docs/usage.md) | Data layout, seeds, CLI arguments, and output files |
145
- | [Configuration](docs/configuration.md) | YAML configs and tracking parameters |
146
- | [Algorithm Overview](docs/algorithm.md) | Methodology, workflow, and training strategy |
147
- | [Training](docs/training.md) | Train nnU-Net models on a new dataset |
148
- | [Performance & Benchmarks](docs/benchmarks.md) | Accuracy, timing, and qualitative comparisons |
149
- | [API](docs/api.md) | Call tracing from Python |
150
- | [Research & Development](docs/development.md) | SimVascular, 3D Slicer, and repository layout |
117
+ | Job | Guide | Description |
118
+ |-----|-------|-------------|
119
+ | Run | [Installation](docs/installation.md) | Setup, dependencies, and pre-trained model weights |
120
+ | Run | [Tutorial](seqseg/tutorial/tutorial.md) | End-to-end aorta example with sample data |
121
+ | Run | [Usage](docs/usage.md) | Data layout, seeds, CLI arguments, and output files |
122
+ | Run | [Configuration](docs/configuration.md) | YAML configs and tracking parameters |
123
+ | Train | [Training](docs/training.md) | Train nnU-Net models on a new dataset |
124
+ | Understand | [Algorithm Overview](docs/algorithm.md) | Methodology, workflow, and training strategy |
125
+ | Understand | [Performance & Benchmarks](docs/benchmarks.md) | Accuracy, timing, and qualitative comparisons |
126
+ | Integrate | [API](docs/api.md) | Call tracing from Python |
127
+ | Integrate | [Research & Development](docs/development.md) | SimVascular, 3D Slicer, and repository layout |
151
128
 
152
129
  ## Citation
153
130
 
seqseg-2.1.8/README.md ADDED
@@ -0,0 +1,114 @@
1
+ ![test seqseg without torch build](https://github.com/numisveinsson/SeqSeg/actions/workflows/python-app.yml/badge.svg)
2
+ ![test seqseg build](https://github.com/numisveinsson/SeqSeg/actions/workflows/test.yml/badge.svg)
3
+
4
+ <p align="center">
5
+ <img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/seqseg_logo.png" alt="SeqSeg — Sequential Vessel Segmentation" width="480"/><br/>
6
+ <img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/coronary.png" alt="Example coronary segmentation (SeqSeg)" width="260"/>
7
+ </p>
8
+
9
+ <h1 align="center">SeqSeg: Sequential Vessel Segmentation and Tracking</h1>
10
+
11
+ <p align="center">
12
+ <b>Automatic tracking and segmentation of blood vessels in CT and MR images using deep learning and geometric tracking.</b>
13
+ </p>
14
+
15
+ <p align="center">
16
+ <a href="https://rdcu.be/dU0wy"><img src="https://img.shields.io/badge/Paper-Annals%20of%20BME-blue" alt="Paper"/></a>
17
+ <a href="https://github.com/numisveinsson/SeqSeg/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-green.svg" alt="License"/></a>
18
+ <a href="https://www.python.org"><img src="https://img.shields.io/badge/Python-3.9%2B-blue.svg" alt="Python 3.9+"/></a>
19
+ </p>
20
+
21
+ ## Why SeqSeg?
22
+
23
+ SeqSeg segments vessels **sequentially**, taking steps along vessel centerlines and detecting bifurcations to grow complete vascular trees from just **1–2 seed points**. By combining local deep-learning predictions (nnU-Net) with geometric tracking, it stays robust across vessel scales — from small coronaries to large aortas.
24
+
25
+ - 🌱 **Minimal supervision** — only 1–2 seed points to initialize
26
+ - 🌿 **Robust bifurcation detection** — automatically follows every branch
27
+ - 🩻 **Multi-modal** — works with CT and MR 3D medical images
28
+ - 📏 **Scalable** — vessels from ~1mm coronaries to ~30mm aortas
29
+ - ✅ **Clinically validated** — coronary, aortic, cerebral, and pulmonary anatomies (pre-trained weights for aorta CT/MR and coronary CT)
30
+ - ⚡ **Fast** — on CPU, about 2–5 minutes for an aorta, 5–15 for a coronary tree, and 10–30 for a cerebral tree. GPU is faster. Details in [Benchmarks](docs/benchmarks.md).
31
+
32
+ A finished case includes a `simvascular/` project you can open directly in SimVascular, with pathlines and contours for every segmented branch.
33
+
34
+ <p align="center">
35
+ <img src="https://raw.githubusercontent.com/numisveinsson/SeqSeg/main/seqseg/assets/mr_model_tracing_fast_shorter.gif" alt="SeqSeg Demo"/><br/>
36
+ <i>Real-time demonstration: automatic segmentation of an abdominal aorta in a 3D MR scan.</i>
37
+ </p>
38
+
39
+ ## Start here
40
+
41
+ - **First segmentation** — the [tutorial](seqseg/tutorial/tutorial.md) runs a sample abdominal-aorta MR scan.
42
+ - **Your own images** — [Usage](docs/usage.md) describes `images/` and `seeds.json`. The command is in [Quick Start](#quick-start).
43
+ - **Train a model** — [Training](docs/training.md).
44
+
45
+ ## Quick Start
46
+
47
+ Python 3.9 or newer. 3.11 is the version used in the tutorial and conda example.
48
+
49
+ The [tutorial](seqseg/tutorial/tutorial.md) is the sample run (abdominal-aorta MR, seed points, and Windows notes). Plan on 15–20 minutes including setup. Tracing is capped, so that part finishes in a few minutes; a real case should use the defaults.
50
+
51
+ Install SeqSeg and the aorta weights below, then run `seqseg run batch` on your own data. The folder needs `images/` and `seeds.json` ([Usage](docs/usage.md)). This example is an aorta MR case. Change `-train_dataset`, `-config_name`, and `-img_ext` to match your images and weights.
52
+
53
+ ```bash
54
+ pip install seqseg
55
+
56
+ # Aorta and femoral weights (MR and CT)
57
+ curl -L -o nnUNet_results.zip https://zenodo.org/records/15020477/files/nnUNet_results.zip
58
+ unzip nnUNet_results.zip
59
+ ```
60
+
61
+ [Aorta and femoral weights](https://zenodo.org/records/15020477) (`nnUNet_results.zip`). [Coronary CT weights](https://zenodo.org/records/19547894) are a separate archive, `nnUNet_results_coronary.zip`.
62
+
63
+ `-nnunet_results_path` is the folder that contains `Dataset005_SEQAORTANDFEMOMR` (and the other dataset folders in that zip).
64
+
65
+ ```bash
66
+ seqseg run batch \
67
+ -data_dir your_data/ \
68
+ -nnunet_results_path nnUNet_results/ \
69
+ -train_dataset Dataset005_SEQAORTANDFEMOMR \
70
+ -config_name global_aorta \
71
+ -img_ext .mha \
72
+ -outdir results/
73
+ ```
74
+
75
+ | Anatomy | `-train_dataset` | `-config_name` |
76
+ |---------|------------------|----------------|
77
+ | Aorta / femoral MR | `Dataset005_SEQAORTANDFEMOMR` | `global_aorta` |
78
+ | Aorta / femoral CT | `Dataset006_SEQAORTANDFEMOCT` | `global_aorta` |
79
+ | Coronary CT | `Dataset010_SEQCOROASOCACT` | `global_coro` |
80
+
81
+ The tutorial uses `-config_name aorta_tutorial` for its sample scan. The trainer-folder layout is in [Installation](docs/installation.md). The full command list and flag spelling are in [Usage](docs/usage.md).
82
+
83
+ ## Documentation
84
+
85
+ | Job | Guide | Description |
86
+ |-----|-------|-------------|
87
+ | Run | [Installation](docs/installation.md) | Setup, dependencies, and pre-trained model weights |
88
+ | Run | [Tutorial](seqseg/tutorial/tutorial.md) | End-to-end aorta example with sample data |
89
+ | Run | [Usage](docs/usage.md) | Data layout, seeds, CLI arguments, and output files |
90
+ | Run | [Configuration](docs/configuration.md) | YAML configs and tracking parameters |
91
+ | Train | [Training](docs/training.md) | Train nnU-Net models on a new dataset |
92
+ | Understand | [Algorithm Overview](docs/algorithm.md) | Methodology, workflow, and training strategy |
93
+ | Understand | [Performance & Benchmarks](docs/benchmarks.md) | Accuracy, timing, and qualitative comparisons |
94
+ | Integrate | [API](docs/api.md) | Call tracing from Python |
95
+ | Integrate | [Research & Development](docs/development.md) | SimVascular, 3D Slicer, and repository layout |
96
+
97
+ ## Citation
98
+
99
+ When using SeqSeg, please cite the following [paper](https://rdcu.be/dU0wy):
100
+
101
+ ```
102
+ @Article{SveinssonCepero2024,
103
+ author={Sveinsson Cepero, Numi
104
+ and Shadden, Shawn C.},
105
+ title={SeqSeg: Learning Local Segments for Automatic Vascular Model Construction},
106
+ journal={Annals of Biomedical Engineering},
107
+ year={2024},
108
+ month={Sep},
109
+ day={18},
110
+ issn={1573-9686},
111
+ doi={10.1007/s10439-024-03611-z},
112
+ url={https://doi.org/10.1007/s10439-024-03611-z},
113
+ }
114
+ ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "seqseg"
7
- version = "2.1.7"
7
+ version = "2.1.8"
8
8
  description = "A deep learning-based medical image blood vessel tracking and segmentation tool."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -437,7 +437,7 @@ def _cmd_init_dataset(ns: argparse.Namespace) -> None:
437
437
  "-nnunet_results_path ...\n"
438
438
  "\nNext (train a new model): also fill centerlines/ and truths/, then:\n"
439
439
  f" seqseg paths init --data-dir {root}/ --outdir ~/seqseg_train\n"
440
- " seqseg train prepare --name MYDATA --dataset-number 999 --modality CT\n"
440
+ " seqseg train prepare --name MYDATA --dataset-id 999 --modality CT\n"
441
441
  )
442
442
 
443
443
 
@@ -634,6 +634,12 @@ def _cmd_paths_export(_ns: argparse.Namespace) -> None:
634
634
 
635
635
 
636
636
  def _cmd_train_prepare(ns: argparse.Namespace) -> None:
637
+ if not ns.preprocess_only and not ns.name:
638
+ print(
639
+ "seqseg train prepare: --name is required",
640
+ file=sys.stderr,
641
+ )
642
+ sys.exit(2)
637
643
  try:
638
644
  result = prepare_training_dataset(
639
645
  data_dir=ns.data_dir,
@@ -656,11 +662,14 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
656
662
  skip_sample=ns.skip_sample,
657
663
  skip_convert=ns.skip_convert,
658
664
  also_test=ns.also_test,
659
- yes=ns.yes,
660
665
  verbose=ns.verbose,
661
666
  img_ext=ns.img_ext,
662
667
  global_volumes=ns.global_volumes,
663
668
  keep_extracted=ns.keep_extracted,
669
+ configuration=ns.configuration,
670
+ plans=ns.plans,
671
+ np=ns.np,
672
+ preprocess_only=ns.preprocess_only,
664
673
  )
665
674
  except TrainDependencyError as e:
666
675
  print(str(e), file=sys.stderr)
@@ -670,6 +679,9 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
670
679
  if message.startswith("Sampler config"):
671
680
  print(message, file=sys.stderr)
672
681
  sys.exit(2)
682
+ if "seqseg train prepare" in message:
683
+ print(message, file=sys.stderr)
684
+ sys.exit(1)
673
685
  import traceback
674
686
 
675
687
  traceback.print_exc()
@@ -691,7 +703,11 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
691
703
  sys.exit(1)
692
704
 
693
705
  print("\nPrepare complete.")
694
- if result.removed_staging:
706
+ if ns.preprocess_only:
707
+ print(
708
+ f" Preprocessed {ns.configuration} from the existing raw dataset."
709
+ )
710
+ elif result.removed_staging:
695
711
  print(
696
712
  " Extracted volumes were linked into nnU-Net raw and the "
697
713
  "temporary folder was removed."
@@ -699,9 +715,17 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
699
715
  else:
700
716
  kind = "Whole volumes" if ns.global_volumes else "Patches"
701
717
  print(f" {kind}: {result.extracted_dir}")
718
+ if not result.preprocessed:
719
+ print(
720
+ " nnU-Net preprocessing was skipped (--skip-convert). "
721
+ "Re-run prepare without --skip-convert before training."
722
+ )
702
723
  results = resolve_path("nnunet_results")
703
724
  if results:
704
725
  print(f" Trained models will be written under: {results}")
726
+ config_flag = ""
727
+ if ns.configuration != "3d_fullres":
728
+ config_flag = f" --configuration {ns.configuration}"
705
729
  for name, path in zip(result.dataset_names, result.dataset_dirs):
706
730
  try:
707
731
  ds_id = dataset_id_from_name(name)
@@ -709,11 +733,12 @@ def _cmd_train_prepare(ns: argparse.Namespace) -> None:
709
733
  ds_id = "?"
710
734
  print(f" nnU-Net dataset: {name}")
711
735
  print(f" path: {path}")
712
- print(
713
- " next:\n"
714
- f" seqseg train nnunet --dataset-id {ds_id} "
715
- "--configuration 3d_fullres --fold 0"
716
- )
736
+ if result.preprocessed:
737
+ print(
738
+ " next:\n"
739
+ f" seqseg train nnunet --dataset-id {ds_id}"
740
+ f"{config_flag} --fold 0"
741
+ )
717
742
 
718
743
 
719
744
  def _cmd_train_nnunet(ns: argparse.Namespace) -> None:
@@ -736,12 +761,10 @@ def _cmd_train_nnunet(ns: argparse.Namespace) -> None:
736
761
  dataset_id,
737
762
  configuration=ns.configuration,
738
763
  fold=ns.fold,
739
- skip_plan=ns.skip_plan,
740
- plan_only=ns.plan_only,
741
- np=ns.np,
742
764
  trainer=ns.trainer,
743
765
  plans=ns.plans,
744
766
  cleanup=ns.cleanup,
767
+ continue_training=ns.continue_training,
745
768
  )
746
769
  except Exception as e: # noqa: BLE001
747
770
  print(f"seqseg train nnunet failed: {e}", file=sys.stderr)
@@ -1021,7 +1044,7 @@ def _build_parser() -> argparse.ArgumentParser:
1021
1044
 
1022
1045
  p_prep = train_sub.add_parser(
1023
1046
  "prepare",
1024
- help="Prepare patches or whole volumes and convert to nnU-Net DatasetXXX format",
1047
+ help="Extract volumes, write an nnU-Net dataset, and plan/preprocess",
1025
1048
  formatter_class=argparse.ArgumentDefaultsHelpFormatter,
1026
1049
  )
1027
1050
  p_prep.add_argument(
@@ -1044,16 +1067,20 @@ def _build_parser() -> argparse.ArgumentParser:
1044
1067
  p_prep.add_argument(
1045
1068
  "--name",
1046
1069
  "-name",
1047
- required=True,
1070
+ default=None,
1048
1071
  type=str,
1049
- help="Dataset name stem (e.g. MYDATA → Dataset0XX_MYDATACT)",
1072
+ help="Dataset name stem (e.g. MYDATA → Dataset0XX_MYDATACT). "
1073
+ "Required unless --preprocess-only",
1050
1074
  )
1051
1075
  p_prep.add_argument(
1076
+ "--dataset-id",
1052
1077
  "--dataset-number",
1053
1078
  "-dataset_number",
1079
+ dest="dataset_number",
1054
1080
  required=True,
1055
1081
  type=int,
1056
- help="nnU-Net dataset id (e.g. 999). Incremented per modality if several",
1082
+ help="nnU-Net dataset id to create (e.g. 999). "
1083
+ "Incremented per modality if several",
1057
1084
  )
1058
1085
  p_prep.add_argument(
1059
1086
  "--modality",
@@ -1065,7 +1092,7 @@ def _build_parser() -> argparse.ArgumentParser:
1065
1092
  p_prep.add_argument(
1066
1093
  "--config-name",
1067
1094
  "-config_name",
1068
- default="global",
1095
+ default="default_mm",
1069
1096
  type=str,
1070
1097
  help="Sampler YAML name/path (from vascular-segment-sampler)",
1071
1098
  )
@@ -1125,18 +1152,41 @@ def _build_parser() -> argparse.ArgumentParser:
1125
1152
  action="store_true",
1126
1153
  help="Also convert modality_test folders when present",
1127
1154
  )
1128
- p_prep.add_argument("--yes", action="store_true", help="Non-interactive confirms")
1129
1155
  p_prep.add_argument("--verbose", action="store_true")
1130
1156
  p_prep.add_argument(
1131
1157
  "--keep-extracted",
1132
1158
  action="store_true",
1133
1159
  help="Keep <nnunet-root>/_seqseg_extracted after conversion into nnUNet_raw",
1134
1160
  )
1161
+ p_prep.add_argument(
1162
+ "--configuration",
1163
+ default="3d_fullres",
1164
+ choices=["3d_fullres", "2d", "3d_lowres", "3d_cascade_fullres"],
1165
+ help="nnU-Net configuration to preprocess. Default 3d_fullres",
1166
+ )
1167
+ p_prep.add_argument(
1168
+ "--plans",
1169
+ default="nnUNetPlans",
1170
+ type=str,
1171
+ help="nnU-Net plans name (training -p). Default nnUNetPlans",
1172
+ )
1173
+ p_prep.add_argument(
1174
+ "--np",
1175
+ type=int,
1176
+ default=None,
1177
+ help="Processes for nnU-Net preprocessing. Default: --num-cores",
1178
+ )
1179
+ p_prep.add_argument(
1180
+ "--preprocess-only",
1181
+ action="store_true",
1182
+ help="Preprocess another configuration from an existing raw dataset "
1183
+ "and plans file. Does not extract or convert subvolumes",
1184
+ )
1135
1185
  p_prep.set_defaults(_handler=_cmd_train_prepare, img_ext=None)
1136
1186
 
1137
1187
  p_nn = train_sub.add_parser(
1138
1188
  "nnunet",
1139
- help="Run nnUNetv2_plan_and_preprocess and/or nnUNetv2_train",
1189
+ help="Train with nnUNetv2_train (--c continues from the latest checkpoint)",
1140
1190
  formatter_class=argparse.ArgumentDefaultsHelpFormatter,
1141
1191
  )
1142
1192
  p_nn.add_argument(
@@ -1149,13 +1199,13 @@ def _build_parser() -> argparse.ArgumentParser:
1149
1199
  "--dataset-name",
1150
1200
  type=str,
1151
1201
  default=None,
1152
- help="Alternative to --dataset-id (e.g. Dataset0999_MYDATACT)",
1202
+ help="Alternative to --dataset-id (e.g. Dataset999_MYDATACT)",
1153
1203
  )
1154
1204
  p_nn.add_argument(
1155
1205
  "--configuration",
1156
1206
  default="3d_fullres",
1157
1207
  choices=["3d_fullres", "2d", "3d_lowres", "3d_cascade_fullres"],
1158
- help="nnU-Net configuration for preprocessing (-c) and training",
1208
+ help="nnU-Net configuration to train. Default 3d_fullres",
1159
1209
  )
1160
1210
  p_nn.add_argument(
1161
1211
  "--fold",
@@ -1164,20 +1214,11 @@ def _build_parser() -> argparse.ArgumentParser:
1164
1214
  help="Fold to train (0-4 or all)",
1165
1215
  )
1166
1216
  p_nn.add_argument(
1167
- "--skip-plan",
1168
- action="store_true",
1169
- help="Skip plan_and_preprocess; only train",
1170
- )
1171
- p_nn.add_argument(
1172
- "--plan-only",
1217
+ "--c",
1218
+ "--continue",
1219
+ dest="continue_training",
1173
1220
  action="store_true",
1174
- help="Only run plan_and_preprocess",
1175
- )
1176
- p_nn.add_argument(
1177
- "--np",
1178
- type=int,
1179
- default=None,
1180
- help="Processes for plan_and_preprocess (-np)",
1221
+ help="Continue training from checkpoint_latest.pth (nnU-Net --c)",
1181
1222
  )
1182
1223
  p_nn.add_argument("--trainer", default="nnUNetTrainer", type=str)
1183
1224
  p_nn.add_argument("--plans", default="nnUNetPlans", type=str)
@@ -1186,7 +1227,7 @@ def _build_parser() -> argparse.ArgumentParser:
1186
1227
  action="store_true",
1187
1228
  help="After training succeeds, delete this dataset's nnUNet_raw and "
1188
1229
  "nnUNet_preprocessed folders. Leaves nnUNet_results. "
1189
- "Ignored with --plan-only.",
1230
+ "A later --c run needs that preprocessed data.",
1190
1231
  )
1191
1232
  p_nn.set_defaults(_handler=_cmd_train_nnunet)
1192
1233