multimodars 0.2.2__tar.gz → 0.3.0__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.
- {multimodars-0.2.2 → multimodars-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +8 -15
- {multimodars-0.2.2 → multimodars-0.3.0}/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/.github/workflows/CI.yml +22 -1
- multimodars-0.3.0/.pre-commit-config.yaml +52 -0
- multimodars-0.3.0/CHANGELOG.md +138 -0
- multimodars-0.3.0/CONTRIBUTING.md +164 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/Cargo.lock +1 -27
- {multimodars-0.2.2 → multimodars-0.3.0}/Cargo.toml +1 -2
- {multimodars-0.2.2 → multimodars-0.3.0}/PKG-INFO +15 -9
- {multimodars-0.2.2 → multimodars-0.3.0}/README.md +7 -6
- multimodars-0.3.0/ROADMAP.MD +90 -0
- multimodars-0.3.0/docs/api/adjust_ccta.rst +9 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/centerline.rst +2 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyContour.rst +1 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyGeometryPair.rst +1 -1
- multimodars-0.3.0/docs/api/converters_and_wrappers.rst +9 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/index.rst +2 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/conf.py +4 -10
- multimodars-0.3.0/docs/figures/dataprep.jpg +0 -0
- multimodars-0.3.0/docs/index.rst +82 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/installation.rst +1 -1
- multimodars-0.3.0/docs/tutorial_ccta.rst +485 -0
- multimodars-0.3.0/docs/tutorial_intravascular.rst +621 -0
- multimodars-0.3.0/multimodars/__init__.py +133 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/multimodars/_converters.py +222 -91
- multimodars-0.3.0/multimodars/_processing.py +1426 -0
- multimodars-0.3.0/multimodars/ccta/__init__.py +466 -0
- multimodars-0.3.0/multimodars/ccta/debug_plots.py +207 -0
- multimodars-0.3.0/multimodars/ccta/fixing_functions.py +239 -0
- multimodars-0.3.0/multimodars/ccta/labeling.py +561 -0
- multimodars-0.3.0/multimodars/ccta/manipulating.py +977 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/multimodars/io/write_geometries.py +3 -2
- multimodars-0.3.0/multimodars/multimodars.pyi +707 -0
- multimodars-0.3.0/multimodars/py.typed +0 -0
- multimodars-0.3.0/paper/REVIEWER1.md +140 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/paper/bibliography.bib +6 -3
- multimodars-0.3.0/paper/figures/Figure2.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/paper/paper.md +3 -3
- {multimodars-0.2.2 → multimodars-0.3.0}/pyproject.toml +10 -3
- {multimodars-0.2.2 → multimodars-0.3.0}/src/ccta/adjust_mesh/label_coronary.rs +1 -3
- {multimodars-0.2.2 → multimodars-0.3.0}/src/ccta/adjust_mesh/scale_coronary.rs +97 -42
- multimodars-0.3.0/src/ccta/binding/ccta_py.rs +461 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/ccta/mod.rs +0 -1
- multimodars-0.3.0/src/intravascular/binding/align.rs +335 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/binding/classes.rs +601 -271
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/binding/entry.rs +186 -195
- multimodars-0.3.0/src/intravascular/binding/mod.rs +1512 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/centerline_align/align_algorithms.rs +1 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/centerline_align/mod.rs +13 -13
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/io/geometry.rs +91 -26
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/io/input.rs +10 -13
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/io/integrity_check.rs +18 -21
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/io/mod.rs +2 -5
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/io/output.rs +1 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/processing/align_between.rs +16 -11
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/processing/align_within.rs +18 -20
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/processing/postprocessing.rs +3 -9
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/processing/preprocessing.rs +55 -22
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/processing/process_utils.rs +2 -4
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/processing/wall.rs +11 -19
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/to_object/interpolation.rs +8 -8
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/to_object/mod.rs +2 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/to_object/texture.rs +1 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/to_object/write_mtl.rs +5 -5
- multimodars-0.2.2/src/intravascular/utils/utils.rs → multimodars-0.3.0/src/intravascular/utils/general_utils.rs +4 -4
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/utils/mod.rs +1 -1
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/utils/test_utils.rs +11 -11
- {multimodars-0.2.2 → multimodars-0.3.0}/src/lib.rs +5 -2
- multimodars-0.3.0/tests/test_ccta.py +657 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/tests/test_wrappers.py +3 -5
- multimodars-0.2.2/.pre-commit-config.yaml +0 -38
- multimodars-0.2.2/CHANGELOG.md +0 -68
- multimodars-0.2.2/CONTRIBUTING.md +0 -61
- multimodars-0.2.2/ROADMAP.MD +0 -63
- multimodars-0.2.2/docs/api/converters_and_wrappers.rst +0 -13
- multimodars-0.2.2/docs/index.rst +0 -69
- multimodars-0.2.2/docs/tutorial_ccta.rst +0 -158
- multimodars-0.2.2/docs/tutorial_intravascular.rst +0 -411
- multimodars-0.2.2/multimodars/__init__.py +0 -63
- multimodars-0.2.2/multimodars/_wrappers.py +0 -725
- multimodars-0.2.2/multimodars/ccta/__init__.py +0 -1
- multimodars-0.2.2/multimodars/ccta/adjust_ccta.py +0 -689
- multimodars-0.2.2/paper/figures/Figure2.jpg +0 -0
- multimodars-0.2.2/src/ccta/binding/ccta_py.rs +0 -305
- multimodars-0.2.2/src/ccta/io/input.rs +0 -220
- multimodars-0.2.2/src/ccta/io/mod.rs +0 -1
- multimodars-0.2.2/src/intravascular/binding/align.rs +0 -267
- multimodars-0.2.2/src/intravascular/binding/mod.rs +0 -1274
- {multimodars-0.2.2 → multimodars-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/.github/workflows/draft-pdf.yml +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/.gitignore +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/.readthedocs.yaml +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/LICENSE +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/branch_diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/branch_systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/calcium_diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/calcium_systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/diastolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/eem_diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/eem_systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/idealized_geometry/systolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/branch_diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/branch_systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/calcium_diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/calcium_systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/diastolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/eem_diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/eem_systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_full/systolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_rest/combined_sorted_manual.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_rest/diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_rest/diastolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_rest/systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_rest/systolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_stress/combined_sorted_manual.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_stress/diastolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_stress/diastolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_stress/systolic_contours.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/data/fixtures/ivus_stress/systolic_reference_points.csv +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/Makefile +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/_static/.gitkeep +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyCenterline.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyCenterlinePoint.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyContourPoint.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyFrame.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyGeometry.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyInputData.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/PyRecord.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/classes/index.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/core.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/processing.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/api/utilities.rst +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/build.sh +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/changelog.md +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/figures/Alignment3p.png +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/figures/animation_stress_induced_systolic_deformation.gif +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/figures/anomalous_labeling.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/figures/initial_labeling.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/figures/scaling.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/docs/make.bat +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/media/coronary_artery_disease.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/media/dynamic_lumen_changes.png +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/media/multimoda-rs.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/multimodars/io/__init__.py +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/multimodars/io/read_geometrical.py +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/paper/figures/Figure1.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/paper/figures/Figure3.png +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/paper/figures/Figure4.jpg +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/ccta/adjust_mesh/mod.rs +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/ccta/binding/mod.rs +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/centerline_align/preprocessing.rs +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/mod.rs +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/src/intravascular/processing/mod.rs +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/tests/conftest.py +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/tests/test_converters.py +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/tests/test_core.py +0 -0
- {multimodars-0.2.2 → multimodars-0.3.0}/tests/tests_todo.md +0 -0
|
@@ -12,27 +12,20 @@ A clear and concise description of what the bug is.
|
|
|
12
12
|
|
|
13
13
|
**To Reproduce**
|
|
14
14
|
Steps to reproduce the behavior:
|
|
15
|
-
1.
|
|
16
|
-
2.
|
|
17
|
-
3.
|
|
18
|
-
4. See error
|
|
15
|
+
1. Load data with '...'
|
|
16
|
+
2. Call function '...'
|
|
17
|
+
3. See error
|
|
19
18
|
|
|
20
19
|
**Expected behavior**
|
|
21
20
|
A clear and concise description of what you expected to happen.
|
|
22
21
|
|
|
22
|
+
**Environment (please complete the following information):**
|
|
23
|
+
- OS: [e.g. Windows, Linux, macOS]
|
|
24
|
+
- Python version: [e.g. 3.10]
|
|
25
|
+
- Package version: [e.g. 0.1.0]
|
|
26
|
+
|
|
23
27
|
**Screenshots**
|
|
24
28
|
If applicable, add screenshots to help explain your problem.
|
|
25
29
|
|
|
26
|
-
**Desktop (please complete the following information):**
|
|
27
|
-
- OS: [e.g. iOS]
|
|
28
|
-
- Browser [e.g. chrome, safari]
|
|
29
|
-
- Version [e.g. 22]
|
|
30
|
-
|
|
31
|
-
**Smartphone (please complete the following information):**
|
|
32
|
-
- Device: [e.g. iPhone6]
|
|
33
|
-
- OS: [e.g. iOS8.1]
|
|
34
|
-
- Browser [e.g. stock browser, safari]
|
|
35
|
-
- Version [e.g. 22]
|
|
36
|
-
|
|
37
30
|
**Additional context**
|
|
38
31
|
Add any other context about the problem here.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
## Pull Request Checklist
|
|
2
2
|
|
|
3
3
|
- [ ] I have added tests that prove the fix is effective or that the feature works.
|
|
4
|
-
- [ ] I ran `pytest`
|
|
4
|
+
- [ ] I ran `pytest` locally and all tests pass.
|
|
5
5
|
- [ ] I updated `CHANGELOG.md` (or NEWS) and bumped the package version if applicable.
|
|
6
6
|
- [ ] I added/updated documentation (README, docstrings, or docs).
|
|
7
7
|
- [ ] This PR is linked to an issue: fixes #<issue-number> (if applicable).
|
|
@@ -19,6 +19,27 @@ permissions:
|
|
|
19
19
|
contents: read
|
|
20
20
|
|
|
21
21
|
jobs:
|
|
22
|
+
python-compat:
|
|
23
|
+
name: Python ${{ matrix.python-version }} compatibility
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
strategy:
|
|
26
|
+
fail-fast: false
|
|
27
|
+
matrix:
|
|
28
|
+
python-version: ['3.10', '3.11', '3.12', '3.13']
|
|
29
|
+
steps:
|
|
30
|
+
- uses: actions/checkout@v4
|
|
31
|
+
- uses: actions/setup-python@v5
|
|
32
|
+
with:
|
|
33
|
+
python-version: ${{ matrix.python-version }}
|
|
34
|
+
- name: Install Rust
|
|
35
|
+
uses: dtolnay/rust-toolchain@stable
|
|
36
|
+
- name: Install Python deps
|
|
37
|
+
run: |
|
|
38
|
+
python -m pip install --upgrade pip
|
|
39
|
+
pip install -e .[test]
|
|
40
|
+
- name: Run Python tests
|
|
41
|
+
run: pytest
|
|
42
|
+
|
|
22
43
|
linux:
|
|
23
44
|
runs-on: ${{ matrix.platform.runner }}
|
|
24
45
|
strategy:
|
|
@@ -205,7 +226,7 @@ jobs:
|
|
|
205
226
|
name: Release
|
|
206
227
|
runs-on: ubuntu-latest
|
|
207
228
|
if: ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
|
|
208
|
-
needs: [linux, musllinux, windows, macos, sdist]
|
|
229
|
+
needs: [linux, musllinux, windows, macos, sdist, python-compat]
|
|
209
230
|
permissions:
|
|
210
231
|
id-token: write
|
|
211
232
|
contents: write
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
# - id: pytest
|
|
5
|
+
# name: Run pytest
|
|
6
|
+
# entry: pytest
|
|
7
|
+
# language: system
|
|
8
|
+
# types: [python]
|
|
9
|
+
# pass_filenames: false
|
|
10
|
+
|
|
11
|
+
- id: rust-fmt
|
|
12
|
+
name: Rust format
|
|
13
|
+
entry: cargo fmt --all
|
|
14
|
+
language: system
|
|
15
|
+
types: [rust]
|
|
16
|
+
pass_filenames: false
|
|
17
|
+
|
|
18
|
+
- id: rust-clippy
|
|
19
|
+
name: Rust clippy
|
|
20
|
+
entry: cargo clippy --all-targets --all-features -- -D warnings
|
|
21
|
+
language: system
|
|
22
|
+
types: [rust]
|
|
23
|
+
pass_filenames: false
|
|
24
|
+
|
|
25
|
+
# - id: rust-test
|
|
26
|
+
# name: Rust unit tests
|
|
27
|
+
# entry: cargo test --lib # --quiet
|
|
28
|
+
# language: system
|
|
29
|
+
# types: [rust]
|
|
30
|
+
# pass_filenames: false
|
|
31
|
+
|
|
32
|
+
- id: python-black
|
|
33
|
+
name: Black formatting
|
|
34
|
+
entry: black
|
|
35
|
+
language: system
|
|
36
|
+
types: [python]
|
|
37
|
+
require_serial: true
|
|
38
|
+
args: [--quiet, --target-version, py312]
|
|
39
|
+
|
|
40
|
+
- id: python-ruff
|
|
41
|
+
name: Ruff linting
|
|
42
|
+
entry: ruff check
|
|
43
|
+
language: system
|
|
44
|
+
types: [python]
|
|
45
|
+
args: [--fix]
|
|
46
|
+
|
|
47
|
+
- id: python-mypy
|
|
48
|
+
name: Mypy type checking
|
|
49
|
+
entry: mypy multimodars --ignore-missing-imports
|
|
50
|
+
language: system
|
|
51
|
+
types: [python]
|
|
52
|
+
pass_filenames: false
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Changelog multimodars
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
This project adheres to [Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## [0.3.0] - 2026-04-30
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
- `stitch_ccta_to_intravascular()`: fuses an aligned intravascular `PyGeometry` with a CCTA
|
|
10
|
+
trimesh by triangulating a patch between the open boundary ring of the CCTA mesh and the
|
|
11
|
+
proximal/distal contour of the intravascular geometry. Supports two boundary-ring alignment
|
|
12
|
+
modes (`"nearest_iv"` and `"highest_z"`) for proximal and distal ends independently.
|
|
13
|
+
- `fix_and_remesh_stitched_mesh()`: repairs the stitched surface (non-manifold edges/vertices,
|
|
14
|
+
open holes) and applies isotropic remeshing via `pymeshlab`. Requires the optional
|
|
15
|
+
`multimodars[meshlab]` extra.
|
|
16
|
+
- `manual_hole_fill()`: flat-fills remaining open holes in a trimesh after automatic repair.
|
|
17
|
+
- `remove_labeled_points_from_mesh()`: deletes one or more labeled vertex regions from the mesh, remaps faces, and returns the open boundary ring as `"boundary_points"` for downstream stitching.
|
|
18
|
+
- `keep_labeled_points_from_mesh()`: retains only the vertices of a specified labeled region,
|
|
19
|
+
discarding all others.
|
|
20
|
+
- `sync_results_to_mesh()`: refreshes all coordinate lists in the results dictionary after
|
|
21
|
+
`scale_region_centerline_morphing()` moves vertices, keeping labels consistent with the
|
|
22
|
+
updated mesh.
|
|
23
|
+
- `find_aortic_wall_scaling()`: computes the optimal radial scaling factor for the aortic wall
|
|
24
|
+
region by minimising the distance to the first intravascular frame whose lumen elliptic ratio
|
|
25
|
+
drops below 1.3 (transition from intramural to free-segment lumen).
|
|
26
|
+
- `export_section_stl()`: exports the full mesh or a labeled sub-region (`"all"`, `"aorta"`,
|
|
27
|
+
`"rca"`, `"lca"`) as an STL file.
|
|
28
|
+
- `plot_results_key()`: opens an interactive 3-D trimesh scene visualising selected labeled
|
|
29
|
+
regions with colour coding (yellow = aorta, blue = RCA, green = LCA, red = removed/intramural,
|
|
30
|
+
cyan = proximal, magenta = distal, orange = anomalous).
|
|
31
|
+
- Tests for all new CCTA functions.
|
|
32
|
+
- `mypy` added to pre-commit hooks for static type checking.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
- Rust-side CCTA STL reader (`src/ccta/io/input.rs`) removed; mesh I/O is now handled
|
|
36
|
+
entirely via Python `trimesh`, eliminating the `stl_io` dependency.
|
|
37
|
+
- `pymeshlab` and `pyglet` are now optional dependencies; the core package installs without
|
|
38
|
+
them. Install extras with `pip install 'multimodars[meshlab]'`.
|
|
39
|
+
- Debug-plot helpers moved to a dedicated `ccta.debug_plots` module.
|
|
40
|
+
- CCTA Python module refactored into focused sub-modules (`labeling`, `manipulating`,
|
|
41
|
+
`fixing_functions`, `debug_plots`).
|
|
42
|
+
- Parameter order updated in several CCTA API calls for consistency.
|
|
43
|
+
- `diastole` argument removed from functions where it was not used.
|
|
44
|
+
- Labeling of aorta boundary points improved to avoid incorrect assignment at mesh edges.
|
|
45
|
+
- Type stubs updated and extended to cover all new public functions.
|
|
46
|
+
- Clippy lints applied across the Rust codebase (non-breaking).
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
- 3-D area and elliptic ratio calculation corrected for non-planar contours.
|
|
50
|
+
- Mesh face normals corrected after stitching to ensure consistent outward orientation.
|
|
51
|
+
|
|
52
|
+
### Documentation
|
|
53
|
+
- CCTA tutorial completely rewritten to cover the full stitching workflow:
|
|
54
|
+
`remove_labeled_points_from_mesh` → `stitch_ccta_to_intravascular` →
|
|
55
|
+
`fix_and_remesh_stitched_mesh` → Taubin smoothing → `export_section_stl` → re-labeling.
|
|
56
|
+
- Intravascular tutorial reviewed and completed: section numbering corrected (1–7),
|
|
57
|
+
CSV-vs-numpy workflow note added, column descriptions with units added to data tables,
|
|
58
|
+
Sphinx cross-references added throughout, `translate()` tuple-argument bug fixed.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
## [0.2.3] - 2026-03-06
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
- Type stubs for the Rust-implemented interface (via maturin)
|
|
65
|
+
- `PyFrame.get_frame_at_z`: retrieve a frame by its z position
|
|
66
|
+
- `PyFrame.get_frame_at_index`: retrieve a frame by its index
|
|
67
|
+
- `PyFrame.replace_frame`: replace an existing frame with another
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
- CI pipeline now tests against Python 3.10 through 3.13
|
|
71
|
+
- Updated documentation to reflect the current interface and Python version requirements
|
|
72
|
+
- Added direct download links to example data in the README and documentation
|
|
73
|
+
- Migrated to modern NumPy-style type annotations throughout the Python codebase
|
|
74
|
+
- All imports are now top-level across all Python modules
|
|
75
|
+
|
|
76
|
+
## [0.2.2] - 2026-03-03
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
- Uploaded new example data
|
|
80
|
+
- Updated docs to match the new example data
|
|
81
|
+
|
|
82
|
+
## [0.2.1] - 2026-01-12
|
|
83
|
+
|
|
84
|
+
### Changed
|
|
85
|
+
- Automatic version update based on Cargo.toml
|
|
86
|
+
|
|
87
|
+
## [0.2.0] - 2026-01-11
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
- Functionality to read in CCTA .stl files and label them according to centerline object
|
|
91
|
+
- Functionality to label the CCTA geometry additionally by an aligned intravascular aligned geometry.
|
|
92
|
+
- Functionality to better align intravascular geometry to a centerline using additionally the CCTA vertices `align_combined`
|
|
93
|
+
- Functionality to radially scale different regions radially to their corresponding centerline
|
|
94
|
+
- Algorihtm for finding the best radial scaling factor for distal and proximal region compared to the aligned geometry
|
|
95
|
+
- Algorithm for finding the best radial scaling factor for the aorta to minimize the distance between "wall" of `PyGeometry` object and the identified intramural vertices
|
|
96
|
+
|
|
97
|
+
### Changed
|
|
98
|
+
- Updated documentation to include a tutorial for the new functionality
|
|
99
|
+
- Reduced the amount of testing data to reduce size of the package
|
|
100
|
+
- Removed the examples folder from the repository and coupled to release (.zip file)
|
|
101
|
+
|
|
102
|
+
## [0.1.2] - 2025-11-21
|
|
103
|
+
|
|
104
|
+
### Changed
|
|
105
|
+
- intravascular::processing::align_within::fill_holes() now does not panic with gaps > 2
|
|
106
|
+
frames, but instead still fixes the holes and returns a warning to the user to check integrity of the data.
|
|
107
|
+
|
|
108
|
+
## [0.1.1] - 2025-11-17
|
|
109
|
+
|
|
110
|
+
### Changed
|
|
111
|
+
- Update documentation to match new functionality
|
|
112
|
+
|
|
113
|
+
## [0.1.0] - 2025-11-17
|
|
114
|
+
|
|
115
|
+
### Added
|
|
116
|
+
- Fill-holes functionality: when a geometry has a large gap between frames,
|
|
117
|
+
up to two frames will be inserted to improve continuity.
|
|
118
|
+
- Geometry integrity tests: after aligning frames within a geometry,
|
|
119
|
+
several integrity checks are performed before continuing the pipeline.
|
|
120
|
+
- `InputData`: the entire pipeline can be driven from an `InputData` object
|
|
121
|
+
that includes coordinates for different contours.
|
|
122
|
+
- Enum for contour types: `Lumen`, `EEM`, `sidebranch`, `calcification`,
|
|
123
|
+
`wall`, `catheter`.
|
|
124
|
+
- `PyFrame` struct: each frame can hold multiple contour types which are
|
|
125
|
+
processed in parallel.
|
|
126
|
+
|
|
127
|
+
### Changed
|
|
128
|
+
- Full architecture refactor:
|
|
129
|
+
- Raw data is read and ordered into a `Geometry` struct.
|
|
130
|
+
- The `Geometry` struct undergoes integrity checks to ensure data quality.
|
|
131
|
+
- Alignment is performed first *within* geometries, then *between* geometries.
|
|
132
|
+
- Modules are loosely coupled to improve maintainability.
|
|
133
|
+
- Parallelization model updated: each geometry is processed in parallel;
|
|
134
|
+
within-geometry alignment runs first, then between-geometry alignment runs in parallel.
|
|
135
|
+
- Multiple bug fixes in the alignment algorithms.
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
- Various stability and indexing bugs discovered during alignment testing.
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# ✩°。⋆ Contributing to the project ⋆。°✩
|
|
2
|
+
|
|
3
|
+
First off, thank you for considering contributing! **ദ്ദി(˵ •̀ ᴗ - ˵ ) ✧**
|
|
4
|
+
Whether you’re filing a bug, proposing a new feature, improving documentation, or refactoring code, your help makes this project better for you and the whole community.
|
|
5
|
+
|
|
6
|
+
## Code of Conduct
|
|
7
|
+
This project adheres to the [Contributor Covenant v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).
|
|
8
|
+
By participating, you agree to respect everyone in this community. **˗ˏˋ ♡ ˎˊ˗**
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
1. [Getting Started](#getting-started)
|
|
13
|
+
2. [I Have a Question](#i-have-a-question)
|
|
14
|
+
3. [Reporting Bugs](#reporting-bugs)
|
|
15
|
+
4. [Suggesting Enhancements](#suggesting-enhancements)
|
|
16
|
+
5. [Your First Code Contribution](#your-first-code-contribution)
|
|
17
|
+
6. [Pull Request Process](#pull-request-process)
|
|
18
|
+
7. [Coding Style & Tests](#coding-style--tests)
|
|
19
|
+
8. [Writing Documentation](#writing-documentation)
|
|
20
|
+
9. [Where to Get Help](#where-to-get-help)
|
|
21
|
+
|
|
22
|
+
## Getting started
|
|
23
|
+
1. Fork the repo and clone your fork
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://github.com/yungselm/multimoda-rs.git
|
|
26
|
+
cd multimoda-rs
|
|
27
|
+
```
|
|
28
|
+
2. Create a new branch
|
|
29
|
+
```bash
|
|
30
|
+
git checkout -b feature/sick-feature
|
|
31
|
+
```
|
|
32
|
+
3. install dependencies and run tests
|
|
33
|
+
```bash
|
|
34
|
+
pip install -e
|
|
35
|
+
pytest
|
|
36
|
+
```
|
|
37
|
+
## I have a Question
|
|
38
|
+
Before opening an issue:
|
|
39
|
+
- Read the [Documentation](https://multimoda-rs.readthedocs.io/en/latest/index.html)
|
|
40
|
+
- Search existing [Issues](https://github.com/yungselm/multimoda-rs/issues?q=is%3Aissue)
|
|
41
|
+
|
|
42
|
+
If you still need help:
|
|
43
|
+
- Open a new issue: [Click here](https://github.com/yungselm/multimoda-rs/issues/new/choose)
|
|
44
|
+
- Provide:
|
|
45
|
+
- A clear, descriptive title
|
|
46
|
+
- Context: what you're trying to do, expected vs. actual behaviour
|
|
47
|
+
- Project verion, OS/platform, Python version, and any relevant logs
|
|
48
|
+
|
|
49
|
+
## Reporting Bugs
|
|
50
|
+
If you find a bug, please help us fix it by opening a [a new issue](https://github.com/yungselm/multimoda-rs/issues/new/choose) and providing:
|
|
51
|
+
- **Title**: A short descriptive title
|
|
52
|
+
- **Steps to reproduce**: Minimal code snippet or sequence to trigger the bug
|
|
53
|
+
- **Expected behaviour** vs **Actual behaviour**
|
|
54
|
+
- **Environment**:
|
|
55
|
+
- `multimoda-rs` version
|
|
56
|
+
- Python version
|
|
57
|
+
- OS and architecture
|
|
58
|
+
|
|
59
|
+
## Suggesting Enhancements
|
|
60
|
+
Have an idea for a new feature or an improvement to existing behaviour? Open a [feature request issue](https://github.com/yungselm/multimoda-rs/issues/new/choose) and include:
|
|
61
|
+
- **Summary**: A concise description of the enhancement
|
|
62
|
+
- **Motivation**: Why would this be useful? What problem does it solve?
|
|
63
|
+
- **Proposed solution**: How you envision it working (API sketch, example usage, etc.)
|
|
64
|
+
- **Alternatives considered**: Other approaches you've thought about
|
|
65
|
+
|
|
66
|
+
We appreciate well-scoped proposals with clear use cases.
|
|
67
|
+
|
|
68
|
+
## Your First Code Contribution
|
|
69
|
+
Not sure where to start? Look for issues labelled [`good first issue`](https://github.com/yungselm/multimoda-rs/issues?q=is%3Aissue+label%3A%22good+first+issue%22) or [`help wanted`](https://github.com/yungselm/multimoda-rs/issues?q=is%3Aissue+label%3A%22help+wanted%22).
|
|
70
|
+
|
|
71
|
+
**Setup** (Python + Rust hybrid via [maturin](https://github.com/PyO3/maturin)):
|
|
72
|
+
```bash
|
|
73
|
+
# 1. Fork the repo on GitHub, then clone your fork
|
|
74
|
+
git clone https://github.com/<your-username>/multimoda-rs.git
|
|
75
|
+
cd multimoda-rs
|
|
76
|
+
|
|
77
|
+
# 2. Create and activate a virtual environment
|
|
78
|
+
python -m venv .venv
|
|
79
|
+
source .venv/bin/activate # Windows: .venv\Scripts\activate
|
|
80
|
+
|
|
81
|
+
# 3. Install the package in development mode (compiles the Rust extension)
|
|
82
|
+
pip install -e ".[dev]"
|
|
83
|
+
|
|
84
|
+
# 4. Install pre-commit hooks
|
|
85
|
+
pre-commit install
|
|
86
|
+
|
|
87
|
+
# 5. Verify everything works
|
|
88
|
+
pytest
|
|
89
|
+
cargo test --lib
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Pull Request Process
|
|
93
|
+
1. **Branch** – create a descriptive branch (`feature/my-feature`, `fix/issue-123`).
|
|
94
|
+
2. **Commit** – write clear, atomic commit messages.
|
|
95
|
+
3. **Tests** – add or update tests to cover your changes; all existing tests must pass.
|
|
96
|
+
4. **Docs** – update docstrings and, if applicable, the RST docs under `docs/`.
|
|
97
|
+
5. **Open the PR** – target the `main` branch. Fill in the PR template with a summary, motivation, and testing notes.
|
|
98
|
+
6. **Review** – address reviewer comments; once approved and CI is green, a maintainer will merge.
|
|
99
|
+
|
|
100
|
+
PRs that break existing tests or skip the pre-commit hooks will not be merged.
|
|
101
|
+
|
|
102
|
+
## Coding Style & Tests
|
|
103
|
+
|
|
104
|
+
### Python
|
|
105
|
+
- **Formatter**: [Black](https://black.readthedocs.io/) (enforced automatically via pre-commit).
|
|
106
|
+
- **Linter**: [Ruff](https://docs.astral.sh/ruff/) with `--fix` (enforced automatically via pre-commit).
|
|
107
|
+
- **Docstrings**: [NumPy docstring style](https://numpydoc.readthedocs.io/en/latest/format.html).
|
|
108
|
+
Example:
|
|
109
|
+
```python
|
|
110
|
+
def my_function(x: float, y: float) -> float:
|
|
111
|
+
"""Short one-line summary.
|
|
112
|
+
|
|
113
|
+
Longer description if needed.
|
|
114
|
+
|
|
115
|
+
Parameters
|
|
116
|
+
----------
|
|
117
|
+
x : float
|
|
118
|
+
Description of x.
|
|
119
|
+
y : float
|
|
120
|
+
Description of y.
|
|
121
|
+
|
|
122
|
+
Returns
|
|
123
|
+
-------
|
|
124
|
+
float
|
|
125
|
+
Description of the return value.
|
|
126
|
+
"""
|
|
127
|
+
```
|
|
128
|
+
- **Type annotations**: use `from __future__ import annotations` at the top of every module and annotate all public functions and methods.
|
|
129
|
+
- **Tests**: place tests under `tests/` and use [pytest](https://docs.pytest.org/). Run with `pytest`.
|
|
130
|
+
|
|
131
|
+
### Rust
|
|
132
|
+
- **Formatter**: `cargo fmt --all` (enforced automatically via pre-commit).
|
|
133
|
+
- **Tests**: unit tests live alongside the source (`#[cfg(test)]` blocks). Run with `cargo test --lib`.
|
|
134
|
+
|
|
135
|
+
All checks are wired up via pre-commit and run automatically on every commit. You can also run them manually:
|
|
136
|
+
```bash
|
|
137
|
+
pre-commit run --all-files
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Writing Documentation
|
|
141
|
+
Documentation lives under `docs/` and is built with [Sphinx](https://www.sphinx-doc.org/).
|
|
142
|
+
|
|
143
|
+
- Public API is documented via **NumPy-style docstrings** (see above) — Sphinx picks these up automatically.
|
|
144
|
+
- Narrative docs (tutorials, how-tos) go in `.rst` files under `docs/`.
|
|
145
|
+
- Build locally with:
|
|
146
|
+
```bash
|
|
147
|
+
cd docs
|
|
148
|
+
make html
|
|
149
|
+
# open _build/html/index.html in your browser
|
|
150
|
+
```
|
|
151
|
+
- Keep prose clear and concise. Include runnable code examples where possible.
|
|
152
|
+
|
|
153
|
+
## Where to Get Help
|
|
154
|
+
| Channel | When to use |
|
|
155
|
+
|---------|-------------|
|
|
156
|
+
| [Documentation](https://multimoda-rs.readthedocs.io/en/latest/index.html) | First stop, API reference and tutorials |
|
|
157
|
+
| [GitHub Issues](https://github.com/yungselm/multimoda-rs/issues) | Bug reports and feature requests |
|
|
158
|
+
| [GitHub Discussions](https://github.com/yungselm/multimoda-rs/discussions) | Questions, ideas, and general discussion |
|
|
159
|
+
|
|
160
|
+
When asking for help, please include your `multimoda-rs` version, Python version, OS, and a minimal reproducible example.
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
**ฅ^>⩊<^ ฅ**
|
|
164
|
+
------------------------------------------------------------------------------------
|
|
@@ -161,12 +161,6 @@ version = "1.23.1"
|
|
|
161
161
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
162
162
|
checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422"
|
|
163
163
|
|
|
164
|
-
[[package]]
|
|
165
|
-
name = "byteorder"
|
|
166
|
-
version = "1.5.0"
|
|
167
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
168
|
-
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
|
169
|
-
|
|
170
164
|
[[package]]
|
|
171
165
|
name = "byteorder-lite"
|
|
172
166
|
version = "0.1.0"
|
|
@@ -390,15 +384,6 @@ dependencies = [
|
|
|
390
384
|
"miniz_oxide",
|
|
391
385
|
]
|
|
392
386
|
|
|
393
|
-
[[package]]
|
|
394
|
-
name = "float-cmp"
|
|
395
|
-
version = "0.10.0"
|
|
396
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
397
|
-
checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8"
|
|
398
|
-
dependencies = [
|
|
399
|
-
"num-traits",
|
|
400
|
-
]
|
|
401
|
-
|
|
402
387
|
[[package]]
|
|
403
388
|
name = "getrandom"
|
|
404
389
|
version = "0.3.4"
|
|
@@ -726,7 +711,7 @@ dependencies = [
|
|
|
726
711
|
|
|
727
712
|
[[package]]
|
|
728
713
|
name = "multimodars"
|
|
729
|
-
version = "0.
|
|
714
|
+
version = "0.3.0"
|
|
730
715
|
dependencies = [
|
|
731
716
|
"anyhow",
|
|
732
717
|
"approx",
|
|
@@ -737,7 +722,6 @@ dependencies = [
|
|
|
737
722
|
"pyo3",
|
|
738
723
|
"rayon",
|
|
739
724
|
"serde",
|
|
740
|
-
"stl_io",
|
|
741
725
|
"toml",
|
|
742
726
|
]
|
|
743
727
|
|
|
@@ -1255,16 +1239,6 @@ version = "1.2.1"
|
|
|
1255
1239
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1256
1240
|
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
|
1257
1241
|
|
|
1258
|
-
[[package]]
|
|
1259
|
-
name = "stl_io"
|
|
1260
|
-
version = "0.10.0"
|
|
1261
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1262
|
-
checksum = "da63e75b86345156b191c021b3ce2a13b973941ecdb8c70d6f00cbbfe0076ed7"
|
|
1263
|
-
dependencies = [
|
|
1264
|
-
"byteorder",
|
|
1265
|
-
"float-cmp",
|
|
1266
|
-
]
|
|
1267
|
-
|
|
1268
1242
|
[[package]]
|
|
1269
1243
|
name = "syn"
|
|
1270
1244
|
version = "2.0.104"
|
|
@@ -1,30 +1,35 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: multimodars
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
7
|
Classifier: License :: OSI Approved :: MIT License
|
|
8
8
|
Requires-Dist: numpy>=2.0.0,<3.0.0
|
|
9
9
|
Requires-Dist: trimesh>=4.8.0
|
|
10
|
-
Requires-Dist:
|
|
10
|
+
Requires-Dist: scipy>=1.15.0
|
|
11
11
|
Requires-Dist: sphinx>=8.0,<9.0 ; extra == 'docs'
|
|
12
12
|
Requires-Dist: sphinx-rtd-theme ; extra == 'docs'
|
|
13
13
|
Requires-Dist: sphinx-autodoc-typehints ; extra == 'docs'
|
|
14
14
|
Requires-Dist: myst-parser ; extra == 'docs'
|
|
15
15
|
Requires-Dist: maturin>=1.7,<2.0 ; extra == 'docs'
|
|
16
16
|
Requires-Dist: furo ; extra == 'docs'
|
|
17
|
+
Requires-Dist: pymeshlab>=2023.12 ; extra == 'meshlab'
|
|
17
18
|
Requires-Dist: pytest>=9.0.2 ; extra == 'test'
|
|
18
19
|
Requires-Dist: pytest-cov ; extra == 'test'
|
|
19
20
|
Requires-Dist: ruff ; extra == 'test'
|
|
20
21
|
Requires-Dist: black ; extra == 'test'
|
|
22
|
+
Requires-Dist: mypy ; extra == 'test'
|
|
23
|
+
Requires-Dist: pyglet<2 ; extra == 'viz'
|
|
21
24
|
Provides-Extra: docs
|
|
25
|
+
Provides-Extra: meshlab
|
|
22
26
|
Provides-Extra: test
|
|
27
|
+
Provides-Extra: viz
|
|
23
28
|
License-File: LICENSE
|
|
24
29
|
Summary: A Rust-powered cardiac multi-image modality fusion package
|
|
25
30
|
Author: Anselm W. Stark
|
|
26
31
|
License-Expression: MIT
|
|
27
|
-
Requires-Python: >=3.
|
|
32
|
+
Requires-Python: >=3.10
|
|
28
33
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
29
34
|
Project-URL: Homepage, https://github.com/yungselm/multimoda-rs
|
|
30
35
|
Project-URL: Issues, https://github.com/yungselm/multimoda-rs/issues
|
|
@@ -71,7 +76,7 @@ Project-URL: Issues, https://github.com/yungselm/multimoda-rs/issues
|
|
|
71
76
|
- Centerline Alignment
|
|
72
77
|
- Align registered geometries onto a vessel centerline using three‑point or manual rotation methods.
|
|
73
78
|
- Geometry Utilities
|
|
74
|
-
- Smooth contours,
|
|
79
|
+
- Smooth contours, compute areas and elliptic ratios, find farthest/closest point pairs, and more.
|
|
75
80
|
|
|
76
81
|
## Installation
|
|
77
82
|
|
|
@@ -106,7 +111,8 @@ maturin develop
|
|
|
106
111
|
|
|
107
112
|
|
|
108
113
|
## Quickstart Example
|
|
109
|
-
Download
|
|
114
|
+
Download [examples.zip](https://github.com/yungselm/multimoda-rs/releases/latest/download/examples.zip) (SHA256: `d11ebc7607f43ab4571fb51c9ac9178caac57774cf5d97f4f068ace4eb070fee`) from the latest release and place it in your working directory. A Jupyter Notebook with step-by-step examples is available at `examples/ivus_to_centerline.ipynb`.
|
|
115
|
+
Provided you extraced examples to the project root you can just copy paste the below example to ensure proper setup:
|
|
110
116
|
|
|
111
117
|
```python
|
|
112
118
|
import multimodars as mm
|
|
@@ -114,8 +120,8 @@ import numpy as np
|
|
|
114
120
|
|
|
115
121
|
# IVUS pullbacks: full alignment of rest/stress & diastole/systole
|
|
116
122
|
rest, stress, dia, sys, _ = mm.from_file_full(
|
|
117
|
-
input_path_a="ivus_rest",
|
|
118
|
-
input_path_b="ivus_stress",
|
|
123
|
+
input_path_a="examples/data/ivus_rest",
|
|
124
|
+
input_path_b="examples/data/ivus_stress",
|
|
119
125
|
label="full",
|
|
120
126
|
step_rotation_deg=0.1,
|
|
121
127
|
range_rotation_deg=90,
|
|
@@ -128,12 +134,12 @@ rest, stress, dia, sys, _ = mm.from_file_full(
|
|
|
128
134
|
output_path_b="output/stress",
|
|
129
135
|
output_path_c="output/diastole",
|
|
130
136
|
output_path_d="output/systole",
|
|
131
|
-
interpolation_steps=
|
|
137
|
+
interpolation_steps=0,
|
|
132
138
|
contour_types=[mm.PyContourType.Lumen, mm.PyContourType.Catheter, mm.PyContourType.Wall]
|
|
133
139
|
)
|
|
134
140
|
|
|
135
141
|
# Load raw centerline and align geometry onto it
|
|
136
|
-
cl_raw = np.genfromtxt("centerline_raw.csv", delimiter=",")
|
|
142
|
+
cl_raw = np.genfromtxt("examples/data/centerline_raw.csv", delimiter=",")
|
|
137
143
|
centerline = mm.numpy_to_centerline(cl_raw)
|
|
138
144
|
|
|
139
145
|
aligned_pair, cl_resampled = mm.align_three_point(
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
- Centerline Alignment
|
|
41
41
|
- Align registered geometries onto a vessel centerline using three‑point or manual rotation methods.
|
|
42
42
|
- Geometry Utilities
|
|
43
|
-
- Smooth contours,
|
|
43
|
+
- Smooth contours, compute areas and elliptic ratios, find farthest/closest point pairs, and more.
|
|
44
44
|
|
|
45
45
|
## Installation
|
|
46
46
|
|
|
@@ -75,7 +75,8 @@ maturin develop
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
## Quickstart Example
|
|
78
|
-
Download
|
|
78
|
+
Download [examples.zip](https://github.com/yungselm/multimoda-rs/releases/latest/download/examples.zip) (SHA256: `d11ebc7607f43ab4571fb51c9ac9178caac57774cf5d97f4f068ace4eb070fee`) from the latest release and place it in your working directory. A Jupyter Notebook with step-by-step examples is available at `examples/ivus_to_centerline.ipynb`.
|
|
79
|
+
Provided you extraced examples to the project root you can just copy paste the below example to ensure proper setup:
|
|
79
80
|
|
|
80
81
|
```python
|
|
81
82
|
import multimodars as mm
|
|
@@ -83,8 +84,8 @@ import numpy as np
|
|
|
83
84
|
|
|
84
85
|
# IVUS pullbacks: full alignment of rest/stress & diastole/systole
|
|
85
86
|
rest, stress, dia, sys, _ = mm.from_file_full(
|
|
86
|
-
input_path_a="ivus_rest",
|
|
87
|
-
input_path_b="ivus_stress",
|
|
87
|
+
input_path_a="examples/data/ivus_rest",
|
|
88
|
+
input_path_b="examples/data/ivus_stress",
|
|
88
89
|
label="full",
|
|
89
90
|
step_rotation_deg=0.1,
|
|
90
91
|
range_rotation_deg=90,
|
|
@@ -97,12 +98,12 @@ rest, stress, dia, sys, _ = mm.from_file_full(
|
|
|
97
98
|
output_path_b="output/stress",
|
|
98
99
|
output_path_c="output/diastole",
|
|
99
100
|
output_path_d="output/systole",
|
|
100
|
-
interpolation_steps=
|
|
101
|
+
interpolation_steps=0,
|
|
101
102
|
contour_types=[mm.PyContourType.Lumen, mm.PyContourType.Catheter, mm.PyContourType.Wall]
|
|
102
103
|
)
|
|
103
104
|
|
|
104
105
|
# Load raw centerline and align geometry onto it
|
|
105
|
-
cl_raw = np.genfromtxt("centerline_raw.csv", delimiter=",")
|
|
106
|
+
cl_raw = np.genfromtxt("examples/data/centerline_raw.csv", delimiter=",")
|
|
106
107
|
centerline = mm.numpy_to_centerline(cl_raw)
|
|
107
108
|
|
|
108
109
|
aligned_pair, cl_resampled = mm.align_three_point(
|