VTT -> PyTheraTwin : Web UI, code restructure, better comments + doctoring, general cleanup, dosimetry batch system, CPU profiler#20
Open
peteryazdi wants to merge 38 commits into
Open
Conversation
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Web UI implementation, fixed alot of bugs, computational performance profiler
There was a problem hiding this comment.
Pull request overview
This PR renames and restructures the pipeline into PyTheraTwin, introducing a web UI launcher, new shared utilities, and a persistent rerun-safety / provenance system so cached outputs can be reused only when CT + config + upstream dependencies still match.
Changes:
- Adds a web UI server entrypoint (
run_server.py) and new developer-controlled option/path JSONs for the UI + runtime config injection. - Refactors pipeline stages and shared utilities (segmentation/ROI unification, PBPK TACs, SIMIND/OpenGATE helpers, NIfTI/DICOM utilities).
- Introduces persistent rerun metadata, file fingerprinting, and optional per-stage CPU/RAM profiling.
Reviewed changes
Copilot reviewed 39 out of 44 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/utils/tac_utils.py |
Adds shared PBPK/TAC helpers (VOI-name resolution + cumulated activity integration). |
src/utils/simind_runtime_utils.py |
Adds SIMIND runtime helpers (env, templates, calibration, projection aggregation). |
src/utils/simind_projection_utils.py |
Adds SIMIND projection/header I/O helpers for post-processing. |
src/utils/resize_utils.py |
Centralizes CT/seg downsampling grid resolution logic for SIMIND/OpenGATE. |
src/utils/opengate_utils.py |
Adds SimpleITK/OpenGATE resampling and HU-table discovery helpers. |
src/utils/nifti_utils.py |
Adds shared NIfTI load/save + axis/spacing helpers (nibabel + SimpleITK). |
src/utils/lesion_utils.py |
Adds geometry/sampling utilities for synthetic lesion placement. |
src/utils/label_utils.py |
Adds canonical ROI/PBPK metadata loaders and ROI→VOI mapping from the new ROI map. |
src/utils/dicom_utils.py |
Adds optional DICOM height/weight extraction helper. |
src/utils/body_mask_utils.py |
Adds shared “body outline” masking for post-processing stages. |
src/tests/validate_ct.py |
Adds preflight CT path validation + batch CT discovery helpers. |
src/stages/segmentation_stage.py |
Refactors segmentation to be data-driven from the new ROI map; adds rerun-guard metadata and overlap-resolution logging. |
src/stages/pbpk_tac_stage.py |
Refactors PBPK stage to use ROI-map-driven observables/VOIs + isotope config JSON; adds rerun-guard metadata and optional DICOM HW extraction. |
src/stages/dosemap_postprocess_stage.py |
Refactors dose post-processing to use shared TAC helpers, apply body masking, record per-ROI contributions, and add rerun-guard metadata. |
src/io/stage_metadata.py |
Introduces persistent stage-metadata helpers used by rerun guards. |
src/io/runtime_config.py |
Adds runtime config loading + injection + validation helpers to keep main.py simpler. |
src/io/rerun_snapshots.py |
Adds per-stage config snapshot builders for rerun compatibility checks. |
src/io/rerun_guard.py |
Adds shared rerun-safety checks with fingerprint comparisons and conflict errors. |
src/io/rerun_fingerprints.py |
Adds SHA256 fingerprinting for files/dirs plus JSON normalization/digest helpers. |
src/io/profiler.py |
Adds optional per-stage CPU/RAM sampling profiler (psutil-based). |
src/io/pipeline_logging.py |
Centralizes terminal/log reporting (banners, summaries, stage completion logging). |
src/io/context.py |
Updates the shared Context structure to include CT identity + stage skip state + reorganized fields. |
src/io/config_paths.py |
Adds pipeline path injection/stripping from src/data/pipeline_paths.json. |
src/data/tdt_map.json |
Removes legacy TDT label map JSON. |
src/data/pipeline_paths.json |
Adds developer-controlled paths and per-phase/stage naming defaults. |
src/data/pipeline_options.json |
Adds developer-controlled dropdown option lists for the web UI (ROIs, collimators, recon params, etc.). |
src/data/isotope_config.json |
Adds isotope half-life/attenuation/nuclear config shared across stages. |
run_server.py |
Adds web UI launcher that installs deps if missing, manages port conflicts, and runs uvicorn. |
README.md |
Updates documentation for PyTheraTwin, new UI/CLI workflows, outputs, and ROI configuration files. |
environment.yml |
Renames conda env and adds psutil for profiling. |
config_template.json |
Replaces/updates config template to match new stage keys/fields and ROI conventions. |
.gitignore |
Updates ignored outputs/temp files for the renamed pipeline and web UI artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+119
to
+133
| cmd = ( | ||
| f"{simind_exe} jaszak calib" | ||
| f"/fi:{isotope}" | ||
| f"/cc:{collimator}" | ||
| "/29:1" | ||
| "/15:5" | ||
| "/fa:11" | ||
| "/fa:15" | ||
| "/fa:14" | ||
| ) | ||
| result = subprocess.run( | ||
| cmd, | ||
| shell=True, | ||
| cwd=output_dir, | ||
| stdout=subprocess.DEVNULL, |
Comment on lines
+71
to
+75
| def read_sensitivity_from_calibration_file(calibration_file: str) -> float: | ||
| """Read sensitivity (counts/s/MBq) from SIMIND ``calib.res``.""" | ||
| with open(calibration_file, "r", encoding="utf-8") as fh: | ||
| lines = fh.readlines() | ||
| return float(lines[70].strip().split(":")[-1].strip().split()[0]) |
Comment on lines
+36
to
+41
| candidates = [] | ||
| try: | ||
| for fp in sorted(Path(dicom_dir).rglob("*")): | ||
| if fp.is_file(): | ||
| candidates.append(str(fp)) | ||
| except Exception: |
Comment on lines
+59
to
+67
| if xyz_spacing_mm is None: | ||
| return None | ||
|
|
||
| sx, sy, sz = int(current_size_xyz[0]), int(current_size_xyz[1]), int(current_size_xyz[2]) | ||
| spx, spy, spz = float(current_spacing_xyz_mm[0]), float(current_spacing_xyz_mm[1]), float(current_spacing_xyz_mm[2]) | ||
|
|
||
| target_spx = float(xyz_spacing_mm[0]) | ||
| target_spy = float(xyz_spacing_mm[1]) | ||
| target_spz = float(xyz_spacing_mm[2]) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
added/adjusted: