Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/nightly-health.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
# Python 3.11 is required because the [physicsnemo] extra pulls in
# nvidia-physicsnemo, which requires Python >= 3.11.
run: |
& py -m venv "$env:RUNNER_TEMP\physiotwin4d-venv"
& py -3.11 -m venv "$env:RUNNER_TEMP\physiotwin4d-venv"
echo "$env:RUNNER_TEMP\physiotwin4d-venv\Scripts" >> $env:GITHUB_PATH

- name: Cache uv packages
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ build
__pycache__
_version.py
htmlcov
.cursor
.vscode/*
!.vscode/settings.json

# AI files
.claude
Expand Down
2 changes: 1 addition & 1 deletion data/DirLab-4DCT/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ points for registration validation.

### Dataset Details

- **Format**: `.mhd`/`.raw` (MetaImage format)
- **Format**: `.mhd` headers + `.img` raw volumes (MetaImage format)
- **Cases**: 10 patient cases (Case 1-10)
- **Phases**: 10 respiratory phases per case (T00-T90)
- **Content**: Non-contrast lung CT
Expand Down
84 changes: 28 additions & 56 deletions data/README.md
Original file line number Diff line number Diff line change
@@ -1,61 +1,33 @@
# PhysioTwin4D Data Directory

This directory holds the example datasets used by PhysioTwin4D's tutorials,
experiments, and tests. Each subdirectory is one dataset and has its own
`README.md` with the download URL(s), directory layout, data sizes, and the
exact `physiotwin4d-download-data` command for that dataset. This file is
just the map — see the subdirectory README before downloading anything.
This directory holds the sample datasets used for experiments, testing, and
development of the PhysioTwin4D library. Each subdirectory contains one
dataset and its own `README.md` with download instructions, specifications,
and citation — this file is just an index; treat the per-dataset READMEs as
the source of truth.

## Datasets

| Directory | Data Type | Provided By | Auto-Download |
| ----------------------------------- | ------------------------------------------------------- | --------------------------------------- | ------------- |
| [`Slicer-Heart-CT/`](Slicer-Heart-CT/README.md) | 4D gated cardiac CT (`.seq.nrrd`) | Jolley Lab (CHOP) / SlicerHeart on GitHub | Yes |
| [`DirLab-4DCT/`](DirLab-4DCT/README.md) | 4D lung CT respiratory benchmark + landmarks (`.mhd/.raw`) | DIR-Lab (Emory / MD Anderson) | No — manual, may require registration |
| [`KCL-Heart-Model/`](KCL-Heart-Model/README.md) | Statistical heart shape model meshes (`.vtk`) | King's College London, via Zenodo | Yes |
| [`CHOP-Valve4D/`](CHOP-Valve4D/README.md) | FEBio valve FE model, converted to VTK/ITK + Simpleware segmentation | Jolley Lab (CHOP), converted by PhysioTwin4D | Yes |

[`data/test/`](test/README.md) is not a dataset — it is a cache
automatically managed by the pytest infrastructure (mainly from
`Slicer-Heart-CT`) and is not used by the workflows, tutorials, or CLIs.

## Downloading Data

Datasets marked **Yes** above can be fetched with the
`physiotwin4d-download-data` CLI (or the corresponding
`DataDownloadTools.Download*` method), for example:

```bash
physiotwin4d-download-data Slicer-Heart-CT --directory data/Slicer-Heart-CT
physiotwin4d-download-data KCL-Heart-Model --directory data/KCL-Heart-Model
physiotwin4d-download-data CHOP-Valve4D --directory data/CHOP-Valve4D
```

Datasets marked **No** must be downloaded by hand following the
instructions in that dataset's own README (`DirLab-4DCT/README.md`).

### Verification Helpers

Each dataset also has a `DataDownloadTools.Verify*Data()` helper that checks
whether the expected files are already present, so scripts can skip
downloading when the data is cached:

```python
from physiotwin4d import DataDownloadTools

DataDownloadTools.VerifySlicerHeartCTData("data/Slicer-Heart-CT")
DataDownloadTools.VerifyDirLab4DCTData("data/DirLab-4DCT")
DataDownloadTools.VerifyKCLHeartModelData("data/KCL-Heart-Model")
DataDownloadTools.VerifyCHOPValve4DData("data/CHOP-Valve4D")
```

## Guidelines

- Keep original downloaded data unmodified; write experiment/tutorial
results under `experiments/*/results/` or `tutorials/*/results/`, not
back into `data/`.
- Always respect the license and citation requirements of each dataset —
see the "Citation" / "Acknowledgement" section in the relevant
subdirectory README.
- If you add a new dataset, add both a row above and a subdirectory
`README.md` following the existing datasets as a template.
| Directory | Description | Provided By | Download | README |
| --- | --- | --- | --- | --- |
| `Slicer-Heart-CT/` | 4D cardiac CT with gated cardiac phases | Jolley Lab, Children's Hospital of Philadelphia (CHOP) | Automatic | [Slicer-Heart-CT/README.md](Slicer-Heart-CT/README.md) |
| `DirLab-4DCT/` | 4D lung CT respiratory motion benchmark | DIR-Lab, MD Anderson Cancer Center / Emory University | Manual | [DirLab-4DCT/README.md](DirLab-4DCT/README.md) |
| `KCL-Heart-Model/` | Statistical shape model of the heart | King's College London (KCL) | Automatic | [KCL-Heart-Model/README.md](KCL-Heart-Model/README.md) |
| `CHOP-Valve4D/` | 4D valve reconstruction models | Jolley Lab, CHOP (original FEBio model) | Automatic | [CHOP-Valve4D/README.md](CHOP-Valve4D/README.md) |
| `test/` | pytest-managed cache; not a downloadable dataset | — | N/A | [test/README.md](test/README.md) |

## Automatic Download

`Slicer-Heart-CT`, `KCL-Heart-Model`, and `CHOP-Valve4D` can be fetched with
the `physiotwin4d-download-data` CLI or `DataDownloadTools`; see each
dataset's README for the exact command. `DirLab-4DCT` has no automatic
downloader — DIR-Lab distributes each case individually and may require
registration, so it must be obtained manually; see
[DirLab-4DCT/README.md](DirLab-4DCT/README.md).

## Notes

- Always cite the original data source in publications — see each dataset's
README for the required citation.
- The full set of datasets is ~10-20 GB; ensure adequate disk space before
downloading everything.
12 changes: 2 additions & 10 deletions src/physiotwin4d/vtk_to_usd/usd_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,11 @@ def numpy_to_vt_array(array: NDArray, data_type: DataType) -> Any:
array_uc = array.astype(np.uint8)
return Vt.UCharArray.FromNumpy(array_uc.flatten())

elif data_type in [DataType.SHORT, DataType.USHORT]:
else: # DataType.SHORT, DataType.USHORT
# Convert to int
array_i = array.astype(np.int32)
return Vt.IntArray.FromNumpy(array_i.flatten())
Comment thread
aylward marked this conversation as resolved.

else:
# Fallback to float
array_f = array.astype(np.float32)
return Vt.FloatArray.FromNumpy(array_f.flatten())


def get_sdf_value_type(data_type: DataType, num_components: int) -> Sdf.ValueTypeName:
"""Get appropriate SDF value type for primvar creation.
Expand Down Expand Up @@ -214,12 +209,9 @@ def get_sdf_value_type(data_type: DataType, num_components: int) -> Sdf.ValueTyp
elif data_type in [DataType.UCHAR, DataType.CHAR]:
return Sdf.ValueTypeNames.UCharArray

elif data_type in [DataType.SHORT, DataType.USHORT]:
else: # DataType.SHORT, DataType.USHORT
return Sdf.ValueTypeNames.IntArray
Comment thread
aylward marked this conversation as resolved.

else:
return Sdf.ValueTypeNames.FloatArray


def sanitize_primvar_name(name: str) -> str:
"""Sanitize a name to be USD-compliant.
Expand Down
2 changes: 1 addition & 1 deletion tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ When creating new tests:
## Test Data

### Slicer-Heart-CT Dataset
- **Source**: [Slicer-Heart-CT GitHub](https://github.com/Slicer-Heart-CT/Slicer-Heart-CT)
- **Source**: [SlicerHeart GitHub](https://github.com/SlicerHeart/SlicerHeart)
- **File**: `TruncalValve_4DCT.seq.nrrd` (~1.2 GB)
- **Content**: 21-phase pediatric cardiac CT
- **Usage**: Tests use first 2 time points for speed
Expand Down
2 changes: 1 addition & 1 deletion tutorials/tutorial_01_heart_gated_ct_to_usd.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
Data Required
-------------
See data/README.md for download instructions and dataset licensing.
Dataset: Slicer-Heart-CT - https://github.com/Slicer-Heart-CT/Slicer-Heart-CT
Dataset: Slicer-Heart-CT - https://github.com/SlicerHeart/SlicerHeart
This script expects the data to already exist at
``data/Slicer-Heart-CT/TruncalValve_4DCT.seq.nrrd``. Run the repository data
download notebook or download the file manually before running this tutorial.
Expand Down
Loading