CLI

The cli module provides the command-line interface for MedTDA, including argument parsing, configuration management, and batch processing.

Overview

This module implements the medtda command-line tool. It can be used for:

  • Single file processing

  • Batch processing from CSV

  • Configuration file management

  • Parallel processing

Main Functions:

  • main() - CLI entry point

  • create_parser() - Argument parser

  • process_single_file() - Single file processing

  • process_batch() - Batch processing

  • load_config() - Load configuration from YAML

  • save_config() - Save configuration to YAML

Functions

Entry Point

main

medtda.cli.main()[source]

Main CLI entry point.

Returns:

Exit code (0 for success, non-zero for failure).

Return type:

int

Main entry point for the CLI.

Signature:

def main() -> int

Returns:

  • exit_code (int) - 0 for success, non-zero for error

Example:

# Called automatically when using CLI
# $ medtda -i image.nii.gz -o output.csv

Argument Parser

create_parser

medtda.cli.create_parser()[source]

Create and configure the argument parser.

Returns:

Configured argument parser for MedTDA CLI.

Return type:

argparse.ArgumentParser

Create the argument parser.

Signature:

def create_parser() -> argparse.ArgumentParser

Returns:

  • parser (ArgumentParser) - Configured argument parser

Example:

from medtda.cli import create_parser

parser = create_parser()
args = parser.parse_args(['--help'])

Processing Functions

process_single_file

medtda.cli.process_single_file(args)[source]

Process a single image file.

Parameters:

args (argparse.Namespace) – Parsed command-line arguments.

Returns:

Exit code (0 for success, 1 for failure).

Return type:

int

Process a single image file.

Signature:

def process_single_file(args: argparse.Namespace) -> int

Parameters:

  • args (Namespace) - Parsed command-line arguments

Returns:

  • exit_code (int) - 0 for success, non-zero for error

Example:

from medtda.cli import create_parser, process_single_file

parser = create_parser()
args = parser.parse_args([
    '-i', 'image.nii.gz',
    '-o', 'output.csv',
    '-v', 'persistence_image'
])

exit_code = process_single_file(args)

process_batch

medtda.cli.process_batch(args)[source]

Process multiple files from CSV.

Parameters:

args (argparse.Namespace) – Parsed command-line arguments.

Returns:

Exit code (0 for success, 1 for failure).

Return type:

int

Process multiple images from a CSV file.

Signature:

def process_batch(args: argparse.Namespace) -> int

Parameters:

  • args (Namespace) - Parsed command-line arguments

Returns:

  • exit_code (int) - 0 for success, non-zero for error

Example:

from medtda.cli import create_parser, process_batch

parser = create_parser()
args = parser.parse_args([
    '-i', 'batch_list.csv',
    '-o', 'output_dir',
    '--workers', '4'
])

exit_code = process_batch(args)

Configuration Functions

load_config

medtda.cli.load_config(config_path)[source]

Load configuration from YAML file.

Parameters:

config_path (str) – Path to YAML configuration file.

Returns:

Configuration dictionary.

Return type:

dict

Raises:

ValueError – If config file is invalid or cannot be loaded.

Load configuration from a YAML file.

Signature:

def load_config(config_path: str) -> Dict[str, Any]

Parameters:

  • config_path (str) - Path to YAML configuration file

Returns:

  • config (dict) - Configuration dictionary

Example:

from medtda.cli import load_config

config = load_config('config.yaml')
print(config['vectorization_method'])

save_config

medtda.cli.save_config(args, output_path)[source]

Save configuration to YAML file for reproducibility.

Parameters:
  • args (argparse.Namespace) – Parsed command-line arguments.

  • output_path (Path) – Path to save configuration file.

Return type:

None

Save configuration to a YAML file.

Signature:

def save_config(
    args: argparse.Namespace,
    output_path: Path
) -> None

Parameters:

  • args (Namespace) - Arguments to save

  • output_path (Path) - Output file path

Example:

from medtda.cli import save_config
from pathlib import Path

save_config(args, Path('saved_config.yaml'))

merge_config_with_args

medtda.cli.merge_config_with_args(config, args)[source]

Merge YAML configuration with CLI arguments. CLI arguments take precedence over config file values.

Parameters:
  • config (dict) – Configuration dictionary from YAML file.

  • args (argparse.Namespace) – Parsed command-line arguments.

Returns:

Merged arguments with CLI values overriding config values.

Return type:

argparse.Namespace

Merge configuration file with command-line arguments.

Signature:

def merge_config_with_args(
    config: Dict[str, Any],
    args: argparse.Namespace
) -> argparse.Namespace

Parameters:

  • config (dict) - Configuration dictionary

  • args (Namespace) - Command-line arguments

Returns:

  • merged_args (Namespace) - Merged arguments (CLI overrides config)

Validation Functions

validate_args

medtda.cli.validate_args(args)[source]

Validate parsed arguments.

Parameters:

args (argparse.Namespace) – Parsed command-line arguments.

Raises:

ValueError – If arguments are invalid or incompatible.

Return type:

None

Validate command-line arguments.

Signature:

def validate_args(args: argparse.Namespace) -> None

Raises:

  • ValueError if arguments are invalid

Example:

from medtda.cli import validate_args

try:
    validate_args(args)
except ValueError as e:
    print(f"Invalid arguments: {e}")

detect_mode

medtda.cli.detect_mode(input_path)[source]

Detect processing mode based on input file extension.

Parameters:

input_path (str) – Path to input file.

Returns:

‘batch’ if CSV file, ‘single’ otherwise.

Return type:

str

Detect processing mode (single vs batch) from input path.

Signature:

def detect_mode(input_path: str) -> str

Parameters:

  • input_path (str) - Path to input file

Returns:

  • mode (str) - 'single' or 'batch'

Command-Line Arguments

Input/Output

Argument

Description

-i, --input

Input image file or batch CSV

-o, --output

Output CSV file or directory

-m, --mask

Mask file (single mode only)

--config

YAML configuration file

--save-config

Save configuration to file

Preprocessing

Argument

Description

--spacing

Target voxel spacing (e.g., 1.0 1.0 1.0)

--window

CT windowing (center width)

--normalize

Enable normalization

--normalize-method

Normalization method (minmax/zscore/robust)

--crop-to-roi

Crop to ROI bounding box

--roi-padding

ROI padding in pixels

--label

Extract specific label from mask

Persistent Homology

Argument

Description

--filtration-type

Filtration type (sublevel/superlevel)

--construction

Construction method (T/V)

--max-dimension

Maximum homology dimension

Vectorization

Argument

Description

-v, --vectorization-method

Vectorization method(s)

--return-barcodes

Save raw barcodes

Batch Processing

Argument

Description

--workers

Number of parallel workers

--continue-on-error

Continue batch on errors

Other

Argument

Description

--verbose

Verbose output

--quiet

Suppress output

-h, --help

Show help message

Complete Examples

Example 1: Basic Single File

from medtda.cli import main
import sys

# Process single file
sys.argv = [
    'medtda',
    '-i', 'image.nii.gz',
    '-o', 'features.csv',
    '-v', 'persistence_image'
]

exit_code = main()

Example 2: With Mask and Preprocessing

sys.argv = [
    'medtda',
    '-i', 'ct_scan.nii.gz',
    '-m', 'liver_mask.nii.gz',
    '-o', 'liver_features.csv',
    '--spacing', '1.0', '1.0', '1.0',
    '--window', '40', '400',
    '--normalize',
    '--normalize-method', 'robust',
    '-v', 'persistence_image'
]

main()

Example 3: Batch Processing

sys.argv = [
    'medtda',
    '-i', 'batch_list.csv',
    '-o', 'output_directory',
    '--workers', '4',
    '--continue-on-error',
    '-v', 'persistence_stats',
    '--verbose'
]

main()

Example 4: Using Configuration File

from medtda.cli import load_config, create_parser, process_single_file

# Load config
config = load_config('config.yaml')

# Create parser and parse args
parser = create_parser()
args = parser.parse_args([
    '-i', 'image.nii.gz',
    '-o', 'output.csv'
])

# Merge config with args
from medtda.cli import merge_config_with_args
merged_args = merge_config_with_args(config, args)

# Process
process_single_file(merged_args)

Example 5: Programmatic Batch Processing

from medtda.cli import create_parser, process_batch

# Create arguments programmatically
parser = create_parser()
args = parser.parse_args([
    '-i', 'batch.csv',
    '-o', 'results',
    '--workers', '8',
    '--spacing', '1.0', '1.0', '1.0',
    '--normalize',
    '-v', 'persistence_image',
    '--continue-on-error'
])

# Process batch
exit_code = process_batch(args)

if exit_code == 0:
    print("Batch processing completed successfully")
else:
    print(f"Batch processing failed with code {exit_code}")

Configuration File Format

YAML Configuration

Create a config.yaml file:

# Input/Output
input: data/images
output: results/features.csv

# Preprocessing
spacing: [1.0, 1.0, 1.0]
window: [40, 400]
normalize: true
normalize_method: robust
crop_to_roi: true
roi_padding: 5

# Persistent Homology
filtration_type: sublevel
construction: T
max_dimension: 2

# Vectorization
vectorization_method: persistence_image
return_barcodes: false

# Batch Processing
workers: 4
continue_on_error: true

Load and use:

from medtda.cli import load_config, create_parser, merge_config_with_args

config = load_config('config.yaml')
parser = create_parser()
args = parser.parse_args(['--input', 'override.nii.gz'])
merged = merge_config_with_args(config, args)

Batch CSV Format

For batch processing, create a CSV file:

image_path,mask_path,case_id
data/patient001.nii.gz,data/patient001_mask.nii.gz,patient001
data/patient002.nii.gz,data/patient002_mask.nii.gz,patient002
data/patient003.nii.gz,data/patient003_mask.nii.gz,patient003

Columns:

  • image_path - Required: path to image

  • mask_path - Optional: path to mask

  • case_id - Optional: identifier for output files

Error Handling

Single File Mode

from medtda.cli import process_single_file

try:
    exit_code = process_single_file(args)
    if exit_code != 0:
        print("Processing failed")
except Exception as e:
    print(f"Error: {e}")

Batch Mode

from medtda.cli import process_batch

# With continue-on-error
args.continue_on_error = True
exit_code = process_batch(args)

# Check exit code
if exit_code == 0:
    print("All files processed successfully")
else:
    print("Some files failed (check error log)")

Parallel Processing

Control Workers

# Single worker (sequential)
args.workers = 1

# 4 workers (parallel)
args.workers = 4

# Auto-detect (number of CPUs)
args.workers = -1

exit_code = process_batch(args)

Performance Tips

  1. Use parallel processing for batch:

    Set workers to number of CPU cores:

    --workers 8
    
  2. Enable continue-on-error:

    Don’t stop on individual failures:

    --continue-on-error
    
  3. Use configuration files:

    Avoid long command lines:

    --config config.yaml
    
  4. Choose efficient vectorization:

    For large batches, use fast methods:

    -v persistence_stats  # Fastest
    -v betti_curve        # Fast
    -v persistence_image  # Medium
    

Internal Functions

The following functions are used internally by the CLI:

medtda.cli._process_single_case(case_id, image_path, mask_path, args)[source]

Process a single case (worker function for batch processing).

Parameters:
  • case_id (str) – Case identifier.

  • image_path (str) – Path to image file.

  • mask_path (str or None) – Path to mask file (optional).

  • args (argparse.Namespace) – Processing arguments.

Returns:

Result dictionary with keys: id, status, features (if success), error (if failed).

Return type:

dict

Process a single case (internal helper).

medtda.cli._process_batch_sequential(cases_df, args)[source]

Process cases sequentially with progress bar.

Parameters:
  • cases_df (pd.DataFrame) – DataFrame with cases to process.

  • args (argparse.Namespace) – Processing arguments.

Returns:

List of result dictionaries.

Return type:

list

Process batch sequentially (internal helper).

medtda.cli._process_batch_parallel(cases_df, args, n_workers)[source]

Process cases in parallel with progress bar.

Parameters:
  • cases_df (pd.DataFrame) – DataFrame with cases to process.

  • args (argparse.Namespace) – Processing arguments.

  • n_workers (int) – Number of parallel workers.

Returns:

List of result dictionaries.

Return type:

list

Process batch in parallel (internal helper).

See Also