-
Notifications
You must be signed in to change notification settings - Fork 3
Refactor #106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Refactor #106
Changes from 4 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
3ec43f3
changed order for split key
Hendrik-code fc63815
remove comment
Hendrik-code 55d313b
added a simple from_numpy function
Hendrik-code 7e16dac
Phase 1: linting setup, CLAUDE.md, and ruff D/ANN201 enforcement
Hendrik-code c7faff8
Phase 2: add Google-style docstrings and return-type annotations thro…
Hendrik-code dc784af
Phase 3: add per-folder README.md API reference files
Hendrik-code 24765c8
Phase 4: add MkDocs + ReadTheDocs documentation infrastructure
Hendrik-code 48d3e52
Fix post-merge errors, missing docstrings, and docs build config
Hendrik-code File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. | ||
|
|
||
| ## Project Overview | ||
|
|
||
| TPTBox is a Python package for processing BIDS-compliant medical imaging datasets (CT, MRI), with a focus on torso/spine analysis. It provides NIfTI I/O, reorientation/resampling, Points of Interest (POI) computation for vertebrae, 2D/3D snapshots, registration, and segmentation integrations (SPINEPS, nnU-Net). | ||
|
|
||
| ## Commands | ||
|
|
||
| ### Installation | ||
| ```bash | ||
| pip install poetry | ||
| poetry install --with dev | ||
| ``` | ||
|
|
||
| ### Running Tests | ||
| ```bash | ||
| # All tests | ||
| pytest unit_tests/ | ||
|
|
||
| # Single test file | ||
| pytest unit_tests/test_nii.py | ||
|
|
||
| # Single test function | ||
| pytest unit_tests/test_nii.py::test_function_name | ||
|
|
||
| # With coverage | ||
| coverage run --source=TPTBox -m pytest unit_tests/ | ||
| ``` | ||
|
|
||
| ### Linting & Formatting | ||
| ```bash | ||
| # Lint (auto-fix where possible) | ||
| ruff check . --fix | ||
|
|
||
| # Format | ||
| ruff format . | ||
|
|
||
| # Both (mirrors pre-commit behavior) | ||
| pre-commit run --all-files | ||
| ``` | ||
|
|
||
| ### CI Linting (as run in GitHub Actions) | ||
| ```bash | ||
| flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics | ||
| ``` | ||
|
|
||
| ## Architecture | ||
|
|
||
| ### Core Abstractions | ||
|
|
||
| **`NII`** (`TPTBox/core/nii_wrapper.py`) — Central class wrapping nibabel NIfTI images. Handles reorientation, resampling, affine transforms, boolean masking, and mathematical operations. Nearly all image operations in the package go through `NII`. Math operations live in `nii_wrapper_math.py` as mixins. | ||
|
|
||
| **`POI`** (`TPTBox/core/poi.py`) — Points of Interest container mapping `(vertebra_id, subregion_id) → 3D coordinate`. Coordinates can be in voxel or world space. POI computation strategies live in `TPTBox/core/poi_fun/`. | ||
|
|
||
| **`BIDS_FILE` / `BIDS_Global_info`** (`TPTBox/core/bids_files.py`) — BIDS dataset navigator. `BIDS_Global_info` scans a dataset root, while `BIDS_FILE` represents a single file parsed according to BIDS naming entities. Constants for BIDS key/value vocabulary are in `bids_constants.py`. | ||
|
|
||
| **`Location` / `Vertebra_Instance`** (`TPTBox/core/vert_constants.py`) — Enum-like constants for vertebral anatomy (vertebra IDs, subregion labels). Used as keys into `POI` objects throughout the codebase. | ||
|
|
||
| ### Package Layout | ||
|
|
||
| ``` | ||
| TPTBox/ | ||
| ├── core/ # NII, POI, BIDS parsing, numpy utilities, vertebra constants | ||
| │ └── poi_fun/ # POI calculation strategies and serialization | ||
| ├── spine/ # Spine-specific: 2D snapshots, statistics (distances, angles) | ||
| ├── segmentation/ # SPINEPS integration, nnU-Net inference, defacing | ||
| ├── registration/ # ANTs rigid/deformable, DeepALI deep learning registration | ||
| ├── mesh3D/ # 3D mesh generation and rendering from segmentations | ||
| ├── stitching/ # Multi-station image stitching | ||
| └── logger/ # Logging infrastructure (Logger, Print_Logger, No_Logger) | ||
| ``` | ||
|
|
||
| Public API is re-exported from `TPTBox/__init__.py`. All major classes and utility functions are importable directly from `TPTBox`. | ||
|
|
||
| ### Key Relationships | ||
|
|
||
| - `NII` + `POI` are used together constantly: compute POIs from segmentation `NII`s, then use POIs to guide further processing. | ||
| - `BIDS_Global_info` iterates subjects/sessions; each subject has a `Subject_Container` with `BIDS_FILE` entries; `BIDS_FILE.get_nii()` returns a `NII`. | ||
| - `vert_constants.py` defines the shared label space (`Location` enum) that ties segmentation labels to POI keys to snapshot rendering. | ||
| - External tool integrations (SPINEPS, nnU-Net, ANTs, DeepALI) are optional; their imports are guarded so the core works without them. | ||
|
|
||
| ### Test Layout | ||
|
|
||
| Tests live in `unit_tests/` (not `TPTBox/tests/`). `TPTBox/tests/` contains test utilities and sample data (CT/MRI NIfTIs) used by the unit tests. Some generated test files are very large (>20K LOC) — they are autogenerated and should not be edited by hand. | ||
|
|
||
| ## Code Style | ||
|
|
||
| - **Line length**: 140 characters | ||
| - **Formatter**: Ruff (Black-compatible, double quotes) | ||
| - **Target Python**: 3.10+ syntax, but the package supports 3.9–3.14 | ||
| - **Naming**: Ruff N-rules are largely ignored — mixed-case class/method names are acceptable in this codebase (medical domain conventions) | ||
| - **Complexity**: McCabe max=20; research code legitimately has deep branching | ||
| - `from __future__ import annotations` is used widely for forward references |
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
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| if __name__ == "__main__": | ||
| # speed test dilation | ||
| import random | ||
|
|
||
| import numpy as np | ||
| from panoptica.utils.input_check_and_conversion.sanity_checker import sanity_check_and_convert_to_array | ||
| from scipy.ndimage import center_of_mass | ||
|
|
||
| from TPTBox.core.nii_wrapper import NII | ||
| from TPTBox.core.np_utils import ( | ||
| _to_labels, | ||
| np_extract_label, | ||
| ) | ||
| from TPTBox.tests.speedtests.speedtest import speed_test | ||
| from TPTBox.tests.test_utils import get_nii | ||
|
|
||
| def get_nii_array(): | ||
| num_points = random.randint(5, 10) | ||
| nii, points, orientation, sizes = get_nii(x=(10, 10, 10), num_point=num_points) | ||
| # nii.map_labels_({1: -1}, verbose=False) | ||
| arr = nii.get_seg_array().astype(np.uint8) | ||
| # arr[arr == 1] = -1 | ||
| # arr_r = arr.copy() | ||
| return arr | ||
|
|
||
| def check_sanity(arr: np.ndarray): | ||
| _, c = sanity_check_and_convert_to_array(arr, arr) | ||
| return c.name | ||
|
|
||
| speed_test( | ||
| repeats=5, | ||
| get_input_func=get_nii_array, | ||
| functions=[check_sanity], | ||
| assert_equal_function=lambda x, y: np.array_equal(x, y), # noqa: ARG005 | ||
| # np.all([x[i] == y[i] for i in range(len(x))]) | ||
| ) | ||
| # print(time_measures) |
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
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh shit the ai comitted this accidentially. will remove it.