BarcodeExtractor

The BarcodeExtractor class provides a higher-level interface for extracting persistence barcodes from images.

Overview

BarcodeExtractor wraps the persistent homology computation functions into a convenient class interface. It’s used internally by FeatureExtractor but can also be used standalone.

Key Features:

  • Simple interface for barcode extraction

  • Configurable filtration type and construction method

  • Automatic dimension detection

  • Flexible configuration

Basic Usage

Quick Start

from medtda import BarcodeExtractor

extractor = BarcodeExtractor()
barcodes = extractor.execute(image_array)

# Access barcodes by dimension
h0 = barcodes['H0']
h1 = barcodes['H1']

Custom Configuration

extractor = BarcodeExtractor(
    filtration_type='superlevel',
    construction='V',
    max_dimension=2
)

barcodes = extractor.execute(image_array)

Dynamic Reconfiguration

extractor = BarcodeExtractor()

# Extract with sublevel filtration
barcodes_sub = extractor.execute(image)

# Change to superlevel
extractor.set_filtration_type('superlevel')
barcodes_sup = extractor.execute(image)

Class Documentation

class medtda.BarcodeExtractor(spacing=None, window=None, normalize=False, normalize_method='minmax', clip_percentiles=None, background_value=None, label=1, crop_to_roi=True, roi_padding=1, filtration_type='sublevel', construction='T', max_dimension=-1)[source]

Bases: object

Extract raw persistence barcodes from medical images.

This class handles the full pipeline: image loading, preprocessing, and persistent homology computation, returning raw barcodes without vectorization.

Parameters:
  • spacing (tuple or None, default=None) – Target voxel spacing for resampling (3D/4D only). If None, no resampling is performed.

  • window (tuple or None, default=None) – Windowing parameters as (center, width). If None, no windowing is applied.

  • normalize (bool, default=False) – Whether to apply normalization.

  • normalize_method ({'minmax', 'zscore', 'robust'}, default='minmax') – Normalization method (only used if normalize=True).

  • clip_percentiles (tuple of float, optional) – If provided, clip intensities to percentile range (lower, upper) before normalization. For example, (1, 99) clips to 1st and 99th percentiles. Only applied if normalize=True.

  • background_value (float or None, default=None) – Value to assign to background pixels when a mask is provided. If None, automatically determined based on normalization and dimensionality.

  • label (int or None, default=1) – For multi-label masks, which label value to consider as foreground. If None, treat mask as binary (any non-zero value is foreground).

  • crop_to_roi (bool, default=True) – If True and a mask is provided, crop image and mask to the bounding box of the ROI with padding. This reduces memory usage and speeds up persistent homology computation.

  • roi_padding (int, default=1) – Number of background pixels to include on all sides of the ROI when crop_to_roi is enabled.

  • filtration_type ({'sublevel', 'superlevel'}, default='sublevel') – Type of filtration for persistent homology.

  • construction ({'T', 'V'}, default='T') – Type of cubical complex construction: - ‘T’: T-construction (pixels/voxels as top-cells, 8-neighborhood in 2D) - ‘V’: V-construction (pixels/voxels as 0-cells, 4-neighborhood in 2D)

  • max_dimension (int, default=-1) – Maximum homology dimension to compute (computes H0, H1, …, H_max_dimension). If -1, automatically determined based on image dimensionality (uses ndim - 1).

Examples

>>> from medtda import BarcodeExtractor
>>> extractor = BarcodeExtractor(
...     normalize=True,
...     normalize_method='minmax',
...     filtration_type='sublevel',
...     max_dimension=2
... )
>>> barcodes = extractor.execute(
...     image='path/to/image.nii.gz',
...     mask='path/to/mask.nii.gz'
... )
>>> print(barcodes.keys())  # e.g., dict_keys(['H0', 'H1', 'H2'])
>>> print(barcodes['H1'].shape)  # (n_features, 2) for (birth, death) pairs
__init__(spacing=None, window=None, normalize=False, normalize_method='minmax', clip_percentiles=None, background_value=None, label=1, crop_to_roi=True, roi_padding=1, filtration_type='sublevel', construction='T', max_dimension=-1)[source]

Initialize BarcodeExtractor with parameters.

set_spacing(spacing)[source]

Update spacing parameter.

Parameters:

spacing (tuple or None) – Target voxel spacing for resampling.

Return type:

None

set_window(window_center, window_width)[source]

Set windowing parameters.

Parameters:
  • window_center (float) – Center of the window.

  • window_width (float) – Width of the window.

Return type:

None

set_normalize(enabled, method='minmax')[source]

Enable/disable normalization and set method.

Parameters:
  • enabled (bool) – Whether to enable normalization.

  • method ({'minmax', 'zscore', 'robust'}, default='minmax') – Normalization method.

Return type:

None

set_clip_percentiles(percentiles)[source]

Set percentile clipping for outlier removal.

Parameters:

percentiles (tuple of float or None) – If provided, should be (lower_percentile, upper_percentile) where 0 <= lower_percentile < upper_percentile <= 100. Values outside these percentiles will be clipped. Set to None to disable clipping.

Return type:

None

set_background_value(value)[source]

Set background value for masked regions.

Parameters:

value (float or None) – Background value. If None, automatically determined.

Return type:

None

set_label(label)[source]

Set label value to extract from multi-label mask.

Parameters:

label (int or None) – Label value to extract. If None, treat mask as binary.

Return type:

None

set_filtration_type(filtration_type)[source]

Set persistent homology filtration type.

Parameters:

filtration_type ({'sublevel', 'superlevel'}) – Filtration type.

Return type:

None

set_construction(construction)[source]

Set cubical complex construction type.

Parameters:

construction ({'T', 'V'}) – Construction type.

Return type:

None

set_max_dimension(max_dimension)[source]

Set maximum homology dimension to compute.

Parameters:

max_dimension (int) – Maximum dimension to compute. Use -1 for automatic determination.

Return type:

None

get_settings()[source]

Get current settings for preprocessing and PH computation.

Returns:

Dictionary containing all current settings.

Return type:

dict

execute(image, mask=None, label=<object object>)[source]

Execute barcode extraction pipeline.

This method performs the complete extraction pipeline: 1. Preprocess image (load, resample, window, normalize, crop, mask) 2. Compute persistent homology 3. Format barcodes by dimension

Parameters:
  • image (str, Path, or numpy.ndarray) – Input image. Can be a file path or numpy array.

  • mask (str, Path, numpy.ndarray, or None, default=None) – Optional mask. Can be a file path or numpy array.

  • label (int or None, optional) – Label value to extract from mask. If None, uses instance default.

Returns:

barcodes – Dictionary with keys as homology dimensions (e.g., ‘H0’, ‘H1’, ‘H2’) and values as barcode arrays of shape (n_features, 2) containing (birth, death) pairs.

Return type:

dict

Examples

>>> extractor = BarcodeExtractor(normalize=True)
>>> barcodes = extractor.execute('image.nii.gz', 'mask.nii.gz')
>>> print(f"H1 has {len(barcodes['H1'])} features")

Constructor Parameters

Parameter

Type

Description

spacing

tuple or None

Target voxel spacing for resampling, e.g. (1.0, 1.0, 1.0) (default: None)

window

tuple or None

CT windowing as (center, width) (default: None)

normalize

bool

Enable intensity normalization (default: False)

normalize_method

str

Normalization method: 'minmax', 'zscore', or 'robust' (default: 'minmax')

clip_percentiles

tuple or None

Clip intensities to (lower, upper) percentiles before normalization (default: None)

background_value

float or None

Background pixel value, auto-determined if None (default: None)

label

int or None

Label to extract from multi-label mask (default: 1)

crop_to_roi

bool

Crop to ROI bounding box when mask is provided (default: True)

roi_padding

int

Padding around ROI in pixels (default: 1)

filtration_type

str

'sublevel' or 'superlevel' (default: 'sublevel')

construction

str

Cubical complex construction: 'T' or 'V' (default: 'T')

max_dimension

int

Maximum homology dimension, -1 for auto (default: -1)

Methods

execute

BarcodeExtractor.execute(image, mask=None, label=<object object>)[source]

Execute barcode extraction pipeline.

This method performs the complete extraction pipeline: 1. Preprocess image (load, resample, window, normalize, crop, mask) 2. Compute persistent homology 3. Format barcodes by dimension

Parameters:
  • image (str, Path, or numpy.ndarray) – Input image. Can be a file path or numpy array.

  • mask (str, Path, numpy.ndarray, or None, default=None) – Optional mask. Can be a file path or numpy array.

  • label (int or None, optional) – Label value to extract from mask. If None, uses instance default.

Returns:

barcodes – Dictionary with keys as homology dimensions (e.g., ‘H0’, ‘H1’, ‘H2’) and values as barcode arrays of shape (n_features, 2) containing (birth, death) pairs.

Return type:

dict

Examples

>>> extractor = BarcodeExtractor(normalize=True)
>>> barcodes = extractor.execute('image.nii.gz', 'mask.nii.gz')
>>> print(f"H1 has {len(barcodes['H1'])} features")

Execute the barcode extraction pipeline.

Signature:

def execute(
    self,
    image: Union[str, Path, np.ndarray],
    mask: Union[str, Path, np.ndarray, None] = None
) -> Dict[str, np.ndarray]

Parameters:

  • image (str, Path, or np.ndarray) - Input image (file path or array)

  • mask (str, Path, np.ndarray, or None) - Optional binary or multi-label mask

Returns:

  • barcodes (dict) - Dictionary mapping dimension to barcode arrays

    • Keys: homology dimension strings ('H0', 'H1', 'H2', …)

    • Values: NumPy arrays of shape (n_features, 2) with [birth, death] columns

Example:

extractor = BarcodeExtractor()
barcodes = extractor.execute(image)

for dim_key, barcode in barcodes.items():
    print(f"{dim_key}: {len(barcode)} features")

set_filtration_type

BarcodeExtractor.set_filtration_type(filtration_type)[source]

Set persistent homology filtration type.

Parameters:

filtration_type ({'sublevel', 'superlevel'}) – Filtration type.

Return type:

None

Change the filtration type.

Signature:

def set_filtration_type(self, filtration_type: str) -> None

Parameters:

  • filtration_type (str) - 'sublevel' or 'superlevel'

Example:

extractor = BarcodeExtractor()
extractor.set_filtration_type('superlevel')

set_construction

BarcodeExtractor.set_construction(construction)[source]

Set cubical complex construction type.

Parameters:

construction ({'T', 'V'}) – Construction type.

Return type:

None

Change the cubical complex construction method.

Signature:

def set_construction(self, construction: str) -> None

Parameters:

  • construction (str) - 'T' or 'V'

Example:

extractor = BarcodeExtractor()
extractor.set_construction('V')

set_max_dimension

BarcodeExtractor.set_max_dimension(max_dimension)[source]

Set maximum homology dimension to compute.

Parameters:

max_dimension (int) – Maximum dimension to compute. Use -1 for automatic determination.

Return type:

None

Change the maximum homology dimension.

Signature:

def set_max_dimension(self, max_dimension: int) -> None

Parameters:

  • max_dimension (int) - Maximum dimension, or -1 for auto

Example:

extractor = BarcodeExtractor()
extractor.set_max_dimension(1)  # Only H0 and H1

Complete Examples

Example 1: Basic Barcode Extraction

import numpy as np
from medtda import BarcodeExtractor
from medtda.loaders import load_image

# Load image
image, metadata = load_image('medical_image.nii.gz')

# Create extractor
extractor = BarcodeExtractor(
    filtration_type='sublevel',
    construction='T'
)

# Extract barcodes
barcodes = extractor.execute(image)

# Analyze results
for dim_key in barcodes:
    barcode = barcodes[dim_key]
    persistence = barcode[:, 1] - barcode[:, 0]

    print(f"\n{dim_key}:")
    print(f"  Features: {len(barcode)}")
    print(f"  Avg persistence: {persistence.mean():.4f}")
    print(f"  Max persistence: {persistence.max():.4f}")

Example 2: Comparing Filtrations

from medtda import BarcodeExtractor

extractor = BarcodeExtractor()

# Sublevel: features from low to high intensity
extractor.set_filtration_type('sublevel')
barcodes_sub = extractor.execute(image)

# Superlevel: features from high to low intensity
extractor.set_filtration_type('superlevel')
barcodes_sup = extractor.execute(image)

# Compare H1 features
print(f"Sublevel H1 features: {len(barcodes_sub['H1'])}")
print(f"Superlevel H1 features: {len(barcodes_sup['H1'])}")

Example 3: Progressive Dimension Analysis

from medtda import BarcodeExtractor

extractor = BarcodeExtractor(construction='T')

# Start with H0 only (fast)
extractor.set_max_dimension(0)
barcodes_h0 = extractor.execute(image)
print(f"H0 features: {len(barcodes_h0['H0'])}")

# Add H1 if needed
extractor.set_max_dimension(1)
barcodes_h01 = extractor.execute(image)
print(f"H1 features: {len(barcodes_h01['H1'])}")

# Add H2 for full 3D topology (slower)
extractor.set_max_dimension(2)
barcodes_full = extractor.execute(image)
print(f"H2 features: {len(barcodes_full['H2'])}")

Example 4: Integration with Preprocessing

from medtda import BarcodeExtractor, Preprocessor
from medtda.loaders import load_image, load_mask

# Load data
image, _ = load_image('ct_scan.nii.gz')
mask, _ = load_mask('tumor_mask.nii.gz')

# Preprocess
preprocessor = Preprocessor(
    normalize=True,
    crop_to_roi=True,
    roi_padding=5
)
processed_image, _ = preprocessor.preprocess(image, mask)

# Extract barcodes
extractor = BarcodeExtractor(
    filtration_type='sublevel',
    max_dimension=2
)
barcodes = extractor.execute(processed_image)

# Analyze topology
h1_persistence = barcodes['H1'][:, 1] - barcodes['H1'][:, 0]
significant_loops = np.sum(h1_persistence > 0.1)

print(f"Significant loops in tumor: {significant_loops}")

Example 5: Batch Processing

from medtda import BarcodeExtractor
import glob

extractor = BarcodeExtractor()

# Process multiple images
image_paths = glob.glob('images/*.nii.gz')

all_barcodes = []
for path in image_paths:
    image, _ = load_image(path)
    barcodes = extractor.execute(image)
    all_barcodes.append(barcodes)

    # Quick summary
    h1_count = len(barcodes['H1'])
    print(f"{path}: {h1_count} H1 features")

Common Use Cases

Use Case 1: Topology Characterization

Extract all topological features:

extractor = BarcodeExtractor(max_dimension=2)
barcodes = extractor.execute(preprocessed_image)

# Characterize topology
n_components = len(barcodes['H0'])
n_loops = len(barcodes['H1'])
n_voids = len(barcodes['H2'])

Use Case 2: Feature Filtering

Extract and filter by persistence:

extractor = BarcodeExtractor()
barcodes = extractor.execute(image)

# Keep only significant features
threshold = 0.1
for dim_key in barcodes:
    barcode = barcodes[dim_key]
    persistence = barcode[:, 1] - barcode[:, 0]
    barcodes[dim_key] = barcode[persistence > threshold]

Use Case 3: Method Comparison

Compare T and V construction:

# T-construction
extractor_t = BarcodeExtractor(construction='T')
barcodes_t = extractor_t.execute(image)

# V-construction
extractor_v = BarcodeExtractor(construction='V')
barcodes_v = extractor_v.execute(image)

# Compare feature counts
for dim_key in barcodes_t:
    print(f"{dim_key}: T={len(barcodes_t[dim_key])}, V={len(barcodes_v[dim_key])}")

Performance Tips

  1. Start with lower dimensions:

    Use max_dimension=0 or max_dimension=1 initially:

    extractor = BarcodeExtractor(max_dimension=1)
    
  2. Choose construction wisely:

    • T-construction: More features per image

    • V-construction: Fewer features, faster for large images

  3. Pass mask directly to execute:

    Let BarcodeExtractor handle preprocessing:

    extractor = BarcodeExtractor(crop_to_roi=True)
    barcodes = extractor.execute(image, mask)
    
  4. Reuse extractor:

    Create once, use multiple times:

    extractor = BarcodeExtractor()
    for image in images:
        barcodes = extractor.execute(image)
    

See Also