README.md 3.7 KB

Spatial SUV Characterization

Utilities for exploratory analysis of spatial SUV distributions in PET NIfTI images.

The main goal is to investigate whether high-SUV spatial patterns contain biomarker information beyond simple scalar summaries such as SUV percentiles.


Repository structure

.
├── data/
│   ├── raw/              # raw PET and segmentation NIfTI files
│   └── gen/              # generated tables and outputs
├── notebooks/            # exploratory notebooks
├── notes/                # methodological notes
├── shiny_app/            # interactive Shiny app
├── src/                  # Python functions
├── pyproject.toml
└── README.md

Function modules

metadata.py          -> dataframe / patient metadata utilities
image_io.py          -> NIfTI loading and segmentation application
suv_stats.py         -> simple SUV distribution features
spatial_features.py  -> spatial tail-region features
plotting.py          -> Plotly visualization

Basic usage

from pathlib import Path

from src.metadata import (
    get_meta_data,
    flag_corrupted_files,
    flag_AE_patients,
)

from src.image_io import get_processed_image
from src.suv_stats import get_suv_percentiles
from src.spatial_features import compute_tail_spatial_features
from src.plotting import plot_suv_pdf_plotly, plot_hot_voxels_plotly

Collect metadata:

DATA_RAW = Path("data/raw")

df_meta = get_meta_data(DATA_RAW)
df_meta = flag_corrupted_files(df_meta)
df_meta = flag_AE_patients(df_meta)

Load one processed image:

patient_id = "NIX-LJU-D2002-IRAE-A001"
organ = "Lung"
visit = 0

row, processed_image = get_processed_image(
    df_meta,
    patient_id=patient_id,
    organ=organ,
    visit=visit,
)

Compute SUV percentiles:

probs = (80, 90, 95)

df_perc = get_suv_percentiles(
    processed_image,
    percentiles=probs,
)

Plot SUV distribution:

fig, suv_percentiles = plot_suv_pdf_plotly(
    processed_image,
    percentiles=probs,
    bins=100,
    log_x=True,
    min_suv=0.1,
)

fig.show()

Compute spatial features:

features = compute_tail_spatial_features(
    image=processed_image,
    percentiles=probs,
    component_connectivity=26,
    contrast_connectivity=26,
    min_component_voxels=3,
    compute_spread=True,
    compute_local_contrast=True,
    compute_sphericity=True,
    crop_to_roi=True,
    image_id=(patient_id, organ, visit),
)

features

Spatial features

For a percentile threshold (q), the high-SUV tail region is

$$

R_q = {v : SUV(v) \ge Q_q},

$$

where $Q_q$ is the $q$-th percentile of SUV values inside the processed image.

The package computes features such as:

  • tail mean, median, max and coefficient of variation,
  • tail excess above percentile threshold,
  • number of connected components,
  • largest-component fraction,
  • component entropy,
  • local contrast,
  • spatial spread,
  • SUV-weighted spatial spread,
  • optional largest-component sphericity.

These features are intended to describe intensity, heterogeneity, fragmentation, and spatial organization of high-SUV uptake.

Shiny app

The Shiny app is in:

shiny_app/app.py

Run from the repository root:

shiny run --reload shiny_app/app.py

The app allows interactive inspection of:

  • metadata table rows,
  • SUV distribution plots,
  • hot-voxel plots,
  • computed spatial features.

Notes

Methodological notes on testing candidate spatial metrics are in:

notes/testing_spatial_metric.md

Status

This project is exploratory and intended for biomarker discovery. Candidate metrics should be validated carefully, especially when the number of AE cases is small.