myoL3
Automated L3-level trunk-muscle analysis from CT. Give it a full-body CT; it localizes the L3 level and crops to it, segments the trunk muscles, strips interior fat, and quantifies per-muscle, per-side body composition.
Pipeline
full-body CT -> L3 localizer (presence-gated sliding window) -> z-crop
-> muscle segmentation (nnU-Net, in-Python) -> raw labels
-> strip interior fat (intramuscular adipose tissue) -> TOTAL muscle seg
-> per-muscle / per-side composition metrics -> JSON
Muscles: psoas, quadratus lumborum, erector spinae / multifidus. The muscle/low-attenuation split is a per-scan, per-muscle Gaussian Mixture Model (GMM) crossover; interior fat (< −30 Hounsfield units, HU) is removed to form the total-muscle segmentation.
GMM crossover — a muscle's HU values form two overlapping populations, denser normal muscle and lower-HU fatty muscle. The GMM fits one bell curve to each and puts the split where they cross, so the threshold adapts to each patient rather than using a fixed cutoff.
Models. The L3 localizer is a Residual Network (ResNet-18) slice encoder with a bidirectional Gated Recurrent Unit (GRU) over the superior–inferior axis, a soft-argmax boundary head, and a presence head. The muscle segmenter is a 3D UNet (no-new-UNet / nnU-Net, full-resolution configuration) run with sliding-window inference in Python.
Installation
Install PyTorch first (pytorch.org), then:
pip install myoL3
Download the model weights (localizer + segmenter, once only):
myol3-install /path/to/models/dir
On shared HPC clusters, point at existing files instead:
export MYOL3_LOCALIZER_CKPT=/shared/models/myol3/l3_localizer.pt
export MYOL3_SEGMENTER_CKPT=/shared/models/myol3/muscle_seg.pth
Usage
# full pipeline -> total muscle seg + composition map + metrics JSON
myol3 -i fullbody_ct.nii.gz -o total_muscle_seg.nii.gz \
--save-comp composition.nii.gz --save-metrics metrics.json
# already cropped to L3 yourself -> skip localization
myol3 -i my_l3_crop.nii.gz -o total_muscle_seg.nii.gz --cropped
# localize + crop only (no segmentation model needed)
myol3 -i fullbody_ct.nii.gz --save-crop l3_crop.nii.gz
| Flag | Description |
|---|---|
-i, --input |
full-body CT (.nii / .nii.gz) — required |
-o, --output |
total muscle segmentation (interior fat stripped); omit to only localize/crop |
--cropped |
input is already cropped to L3; skip the localizer |
--split-drop FRAC |
slice cleaning: an interior slice with muscle area < FRAC × median is a boundary; only the longest piece is averaged, then edge-trimmed (default 0.5; 0 = off) |
--save-crop |
also write the L3-cropped CT |
--save-comp |
also write the 4-compartment map (muscle*10 + compartment) |
--save-metrics |
also write per-muscle / per-side metrics (.json) |
--localizer-ckpt / --segmenter-ckpt |
checkpoint overrides |
--pad |
extra slices each side of the L3 crop |
--device |
cpu | cuda (auto if unset) |
Python API:
import myol3
myol3.run("fullbody_ct.nii.gz", "total_muscle_seg.nii.gz",
save_comp="composition.nii.gz", save_metrics="metrics.json")
Metrics
Per muscle × side (L/R), in mm² (mean, median, std, n_slices):
muscle_csa— total-muscle cross-sectional areafat_pv_muscle_csa— low-attenuation ("fat partial-volume") muscleintramuscular_fat_csa— solidly-fat interior (intramuscular adipose tissue, IMAT)outer_edge_pv_fat_csa— partial-volume boundary rimslice_range— first/last crop slice averaged over
Slice cleaning. All four metrics are averaged over the same cleaned slices:
- Split at drops — any mid-crop slice whose muscle area falls below 0.5 × the median (e.g. a muscle that disappears at a disc level) is a boundary, widened over the transition slices either side (< 0.75 × median). Only the longest piece is kept.
- Edge trim — under-segmented first/last slices of that piece are dropped.
- Shared L/R range — left and right of each muscle use the overlap of their two cleaned ranges.
--split-drop FRAC sets the step-1 fraction; 0 turns the split off.
License
MIT
Metadata
Release files for myoL3 0.1.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| myol3-0.1.7.tar.gz | 19.1 kB | Without provenance | Details for myol3-0.1.7.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| myol3-0.1.7-py3-none-any.whl | Python 3 | none | any | Details for myol3-0.1.7-py3-none-any.whl |
Total release size: 39.5 kB
Release files / myol3-0.1.7.tar.gz
| Download URL | myol3-0.1.7.tar.gz |
|---|---|
| Size | 19.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a1beb842d4f32db573991dfdb1a60130af312e0469124058c3532cfd117d83af
|
|
BLAKE2b-256 checksum How to use checksums |
79d3c46c9974b2fc43c0646bb7308bb0187eda9800ec8898d014f2c54645e83f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.2
|
Release files / myol3-0.1.7-py3-none-any.whl
| Download URL | myol3-0.1.7-py3-none-any.whl |
|---|---|
| Size | 20.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9f40e5c92680c1bb391040928e2e0e90cfad56b86cf7ed574b2e323de12aa33a
|
|
BLAKE2b-256 checksum How to use checksums |
ccb57b4ce213a017ef99cdf15d72fdd5104eb21291a9e7355aafca54464e65fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.2
|
Security for myoL3 0.1.7
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.