===========================
Command-Line Interface (CLI)
===========================

MedTDA provides a powerful command-line interface for feature extraction, batch processing, and integration with pipelines.

Overview
========

The CLI auto-detects operating mode based on input file extension:

* **Single file mode**: Input is an image file (`.nii.gz`, `.nrrd`, `.png`, etc.)
* **Batch mode**: Input is a CSV file (`.csv`)

Installation
============

The CLI is automatically available after installing MedTDA:

.. code-block:: bash

   pip install medtda

Two ways to run:

.. code-block:: bash

   # As command (recommended)
   medtda --version
   
   # As module
   python -m medtda --version

Basic Usage
===========

Single File
-----------

Extract features from a single image:

.. code-block:: bash

   medtda image.nii.gz --output-dir ./results

With mask and preprocessing:

.. code-block:: bash

   medtda image.nii.gz --mask mask.nii.gz --output-dir ./results \\
       --normalize --spacing 1.0 1.0 1.0

Batch Processing
----------------

Create a CSV file with your cases:

.. code-block:: csv

   id,image_path,mask_path
   case001,scan1.nii.gz,mask1.nii.gz   case002,scan2.nii.gz,mask2.nii.gz
   case003,scan3.nii.gz,

Process all cases:

.. code-block:: bash

   medtda cases.csv --output-dir ./results --normalize --workers 4

Complete Example
----------------

.. code-block:: bash

   medtda cases.csv --output-dir ./results \\
       --normalize --normalize-method minmax \\
       --spacing 1.0 1.0 1.0 \\
       --crop-roi --roi-padding 2 \\
       --filtration sublevel --max-dimension 2 \\
       --methods persistence_stats betti_curve \\
       --workers 4 --verbose

Command-Line Arguments
======================

General Options
---------------

**Input** (positional, required)
   
   Input file: image file (single mode) or CSV (batch mode)
   
   .. code-block:: bash
   
      medtda image.nii.gz ...
      medtda cases.csv ...

**--mask** ``PATH``
   
   Mask file (single file mode only)
   
   .. code-block:: bash
   
      medtda image.nii.gz --mask mask.nii.gz --output-dir ./results

**-o, --output-dir** ``PATH`` (required)
   
   Output directory for results
   
   .. code-block:: bash
   
      medtda image.nii.gz -o ./results
      medtda image.nii.gz --output-dir /path/to/output

**-c, --config** ``PATH``
   
   YAML configuration file
   
   .. code-block:: bash
   
      medtda image.nii.gz --config config.yaml --output-dir ./results

**--version**
   
   Show version and exit
   
   .. code-block:: bash
   
      medtda --version

**--help**, **-h**
   
   Show help message and exit
   
   .. code-block:: bash
   
      medtda --help

Preprocessing Options
---------------------

**--spacing** ``S [S ...]``
   
   Target voxel spacing for resampling (3D/4D only)
   
   .. code-block:: bash
   
      # Isotropic 1mm
      medtda image.nii.gz -o ./results --spacing 1.0 1.0 1.0
      
      # Anisotropic
      medtda image.nii.gz -o ./results --spacing 0.5 0.5 2.0

**--window** ``CENTER WIDTH``
   
   Intensity windowing (e.g., for CT images)
   
   .. code-block:: bash
   
      # Soft tissue window
      medtda ct_scan.nii.gz -o ./results --window 40 400
      
      # Lung window
      medtda ct_scan.nii.gz -o ./results --window -600 1500

**--normalize**
   
   Enable intensity normalization
   
   .. code-block:: bash
   
      medtda image.nii.gz -o ./results --normalize

**--normalize-method** ``{minmax,zscore,robust}``
   
   Normalization method (default: minmax)
   
   .. code-block:: bash
   
      medtda image.nii.gz -o ./results --normalize --normalize-method minmax
      medtda image.nii.gz -o ./results --normalize --normalize-method zscore
      medtda image.nii.gz -o ./results --normalize --normalize-method robust

**--background-value** ``VALUE``
   
   Background value for masked regions
   
   .. code-block:: bash
   
      medtda image.nii.gz --mask mask.nii.gz -o ./results \\
          --background-value 0

**--label** ``INT``
   
   Label value for multi-label masks (default: 1)
   
   .. code-block:: bash
   
      # Extract label 2 from multi-label mask
      medtda image.nii.gz --mask multilabel.nii.gz -o ./results --label 2

**--crop-roi** / **--no-crop-roi**
   
   Enable/disable ROI cropping (default: enabled)
   
   .. code-block:: bash
   
      medtda image.nii.gz --mask mask.nii.gz -o ./results --crop-roi
      medtda image.nii.gz --mask mask.nii.gz -o ./results --no-crop-roi

**--roi-padding** ``INT``
   
   Padding around ROI bounding box in pixels (default: 1)
   
   .. code-block:: bash
   
      medtda image.nii.gz --mask mask.nii.gz -o ./results --roi-padding 2

Persistent Homology Options
----------------------------

**--filtration** ``{sublevel,superlevel}``
   
   Filtration type (default: sublevel)
   
   .. code-block:: bash
   
      medtda image.nii.gz -o ./results --filtration sublevel
      medtda image.nii.gz -o ./results --filtration superlevel

**--construction** ``{T,V}``
   
   Cubical complex construction type (default: T)
   
   .. code-block:: bash
   
      medtda image.nii.gz -o ./results --construction T
      medtda image.nii.gz -o ./results --construction V

**--max-dimension** ``INT``
   
   Maximum homology dimension (default: -1 for auto-detect)
   
   .. code-block:: bash
   
      # Auto-detect based on image dimensionality
      medtda image.nii.gz -o ./results --max-dimension -1
      
      # Compute only H0 and H1
      medtda image.nii.gz -o ./results --max-dimension 1
      
      # Compute H0, H1, H2
      medtda image.nii.gz -o ./results --max-dimension 2

Vectorization Options
---------------------

**--methods** ``METHOD [METHOD ...]``
   
   Vectorization method(s) (default: persistence_stats)
   
   Available methods:
   
   * ``persistence_stats`` - Statistical summaries
   * ``betti_curve`` - Betti number curves
   * ``persistence_image`` - 2D histogram representation
   * ``persistence_landscape`` - Landscape functions
   * ``persistence_silhouette`` - Silhouette representation
   * ``entropy_summary`` - Entropy-based features
   * ``persistence_lifespan`` - Lifespan distributions
   * ``persistence_tropical_coordinates`` - Tropical coordinates
   
   .. code-block:: bash
   
      # Single method
      medtda image.nii.gz -o ./results --methods persistence_stats
      
      # Multiple methods
      medtda image.nii.gz -o ./results \\
          --methods persistence_stats betti_curve entropy_summary

**--save-barcodes**
   
   Save raw persistence barcodes as pickle files
   
   .. code-block:: bash
   
      medtda image.nii.gz -o ./results --save-barcodes

Parallelization Options
-----------------------

**-j, --workers** ``N``
   
   Number of parallel workers for batch processing (default: 1)
   
   * ``1`` - Sequential processing (default)
   * ``>1`` - Parallel processing with N workers
   * ``-1`` - Use all available CPU cores
   
   .. code-block:: bash
   
      # Sequential
      medtda cases.csv -o ./results --workers 1
      
      # 4 parallel workers
      medtda cases.csv -o ./results -j 4
      
      # All CPU cores
      medtda cases.csv -o ./results --workers -1

Logging Options
---------------

**-v, --verbose**
   
   Enable verbose output
   
   .. code-block:: bash
   
      medtda cases.csv -o ./results --verbose

**-q, --quiet**
   
   Suppress all non-error output
   
   .. code-block:: bash
   
      medtda cases.csv -o ./results --quiet

Configuration Files
===================

YAML Format
-----------

Create a configuration file to store parameters:

.. code-block:: yaml

   # config.yaml
   preprocessing:
     normalize: true
     normalize_method: minmax
     spacing: [1.0, 1.0, 1.0]
     window: null
     crop_roi: true
     roi_padding: 2
     background_value: null
     label: 1
   
   persistent_homology:
     filtration: sublevel
     construction: T
     max_dimension: 2
   
   vectorization:
     methods:
       - persistence_stats
       - betti_curve
     save_barcodes: false
   
   parallel:
     workers: 4
   
   output:
     output_dir: ./results
     verbose: true
     quiet: false

Using Config Files
------------------

.. code-block:: bash

   # Use config file
   medtda cases.csv --config config.yaml
   
   # Override specific parameters (CLI takes precedence)
   medtda cases.csv --config config.yaml --workers 8 --methods persistence_stats

**Priority:** CLI arguments > Config file > Defaults

Benefits
--------

* **Reproducibility** - Same parameters across runs
* **Documentation** - Self-documenting pipeline
* **Sharing** - Easy to share exact parameters
* **Version Control** - Track parameter changes

Examples
========

Single File Examples
--------------------

**Basic extraction**

.. code-block:: bash

   medtda image.nii.gz --output-dir ./results

**With mask and normalization**

.. code-block:: bash

   medtda image.nii.gz --mask mask.nii.gz --output-dir ./results --normalize

**Full preprocessing**

.. code-block:: bash

   medtda ct_scan.nii.gz --mask tumor_mask.nii.gz --output-dir ./results \\
       --normalize --normalize-method minmax \\
       --spacing 1.0 1.0 1.0 \\
       --window 40 400 \\
       --crop-roi --roi-padding 2 \\
       --filtration sublevel \\
       --max-dimension 2 \\
       --methods persistence_stats betti_curve \\
       --save-barcodes \\
       --verbose

**Multiple vectorization methods**

.. code-block:: bash

   medtda image.nii.gz --output-dir ./results \\
       --normalize \\
       --methods persistence_stats betti_curve entropy_summary \\
       persistence_landscape

**Multi-label mask**

.. code-block:: bash

   # Process label 2 from multi-label segmentation
   medtda image.nii.gz --mask multilabel_mask.nii.gz \\
       --output-dir ./results \\
       --label 2 --normalize

Batch Processing Examples
--------------------------

**Basic batch**

.. code-block:: bash

   medtda cases.csv --output-dir ./results --normalize

**Parallel processing**

.. code-block:: bash

   # 4 workers
   medtda cases.csv --output-dir ./results --workers 4 --verbose
   
   # All CPU cores
   medtda cases.csv --output-dir ./results -j -1 --verbose

**Complete batch workflow**

.. code-block:: bash

   medtda cases.csv --output-dir ./results \\
       --normalize --normalize-method minmax \\
       --spacing 1.0 1.0 1.0 \\
       --crop-roi --roi-padding 1 \\
       --filtration sublevel --max-dimension 2 \\
       --methods persistence_stats betti_curve \\
       --save-barcodes \\
       --workers 8 --verbose

**Using configuration file**

.. code-block:: bash

   medtda cases.csv --config config.yaml --verbose

**Override config values**

.. code-block:: bash

   # Use config but override workers and methods
   medtda cases.csv --config config.yaml \\
       --workers 16 \\
       --methods persistence_stats

Output Files
============

Single File Mode
----------------

Creates 3 files in output directory:

* ``<basename>_features.csv`` - Feature vectors (1 row)
* ``<basename>_config.yaml`` - Configuration used
* ``<basename>_barcodes.pkl`` - Barcodes (if ``--save-barcodes``)

.. code-block:: bash

   medtda scan001.nii.gz --output-dir ./results --save-barcodes --normalize

Creates:

.. code-block:: text

   results/
   ├── scan001_features.csv
   ├── scan001_config.yaml
   └── scan001_barcodes.pkl

Batch Mode
----------

Creates files in output directory:

* ``batch_features.csv`` - All features (one row per case)
* ``config.yaml`` - Configuration used
* ``<id>_barcodes.pkl`` × N - Individual barcodes (if ``--save-barcodes``)

.. code-block:: bash

   medtda cases.csv --output-dir ./results --workers 4 --save-barcodes

Creates:

.. code-block:: text

   results/
   ├── batch_features.csv
   ├── config.yaml
   ├── case001_barcodes.pkl
   ├── case002_barcodes.pkl
   └── ...

batch_features.csv Format
--------------------------

.. code-block:: csv

   id,status,error_message,PersStats_H0_mean,PersStats_H0_std,...
   case001,success,,0.523,0.142,...
   case002,success,,0.487,0.156,...
   case003,error,File not found,,,

Columns:

* ``id`` - Case identifier
* ``status`` - 'success' or 'error'
* ``error_message`` - Error details if failed
* Feature columns - All TDA features

Integration with Pipelines
===========================

Shell Scripts
-------------

.. code-block:: bash

   #!/bin/bash
   # process_cohort.sh
   
   # Process training set
   medtda train_cases.csv --config config.yaml --output-dir ./train_features -j -1
   
   # Process validation set
   medtda val_cases.csv --config config.yaml --output-dir ./val_features -j -1
   
   # Process test set
   medtda test_cases.csv --config config.yaml --output-dir ./test_features -j -1
   
   echo "Feature extraction complete!"

Makefiles
---------

.. code-block:: bash

   # Makefile
   
   .PHONY: all features clean
   
   all: features
   
   features: results/batch_features.csv
   
   results/batch_features.csv: cases.csv config.yaml
   	medtda cases.csv --config config.yaml --output-dir results -j 8 --verbose
   
   clean:
   	rm -rf results

Python Subprocess
-----------------

.. code-block:: python

   import subprocess
   
   # Run CLI from Python
   result = subprocess.run([
       'medtda', 'cases.csv',
       '--output-dir', './results',
       '--config', 'config.yaml',
       '--workers', '8',
       '--verbose'
   ], capture_output=True, text=True)
   
   if result.returncode == 0:
       print("Success!")
   else:
       print(f"Error: {result.stderr}")

Snakemake
---------

.. code-block:: python

   # Snakefile
   
   rule extract_features:
       input:
           cases="cases.csv",
           config="config.yaml"
       output:
           "results/batch_features.csv"
       threads: 8
       shell:
           "medtda {input.cases} --config {input.config} "
           "--output-dir results --workers {threads} --verbose"

Nextflow
--------

.. code-block:: groovy

   // main.nf
   
   process extractFeatures {
       publishDir 'results'
       
       input:
       path cases
       path config
       
       output:
       path 'batch_features.csv'
       
       script:
       """
       medtda ${cases} --config ${config} \\
           --output-dir . --workers ${task.cpus} --verbose
       """
   }

Error Handling
==============

Exit Codes
----------

* ``0`` - Success
* ``1`` - Error (file not found, invalid input, processing failed)
* ``130`` - Interrupted by user (Ctrl+C)

Checking Errors
---------------

.. code-block:: bash

   # Run and check exit code
   medtda cases.csv --output-dir ./results
   
   if [ $? -eq 0 ]; then
       echo "Success"
   else
       echo "Failed"
       exit 1
   fi

Batch Error Handling
--------------------

Batch processing continues even when individual cases fail:

.. code-block:: bash

   medtda cases.csv --output-dir ./results --workers 4 --verbose

Failed cases are recorded in output CSV with:

* ``status = 'error'``
* ``error_message`` field populated

Check results:

.. code-block:: bash

   python -c "
   import pandas as pd
   df = pd.read_csv('results/batch_features.csv')
   errors = df[df['status'] == 'error']
   print(f'Failed: {len(errors)}/{len(df)}')
   if len(errors) > 0:
       print(errors[['id', 'error_message']])
   "

Performance Tips
================

Speed Optimization
------------------

.. code-block:: bash

   # Fast processing (for large batches)
   medtda cases.csv --output-dir ./results \\
       --max-dimension 1 \\              # Skip H2
       --spacing 2.0 2.0 2.0 \\          # Downsample
       --crop-roi --roi-padding 1 \\    # Reduce image size
       --methods persistence_stats \\   # Fastest method
       --workers -1                      # All cores

Memory Optimization
-------------------

.. code-block:: bash

   # Reduce memory usage
   medtda cases.csv --output-dir ./results \\
       --max-dimension 1 \\              # Less memory
       --spacing 2.0 2.0 2.0 \\          # Smaller images
       --crop-roi --roi-padding 0 \\    # Minimal ROI
       --workers 4                       # Limit parallel processes

Quality Settings
----------------

.. code-block:: bash

   # High-quality comprehensive analysis
   medtda cases.csv --output-dir ./results \\
       --normalize --normalize-method minmax \\
       --spacing 1.0 1.0 1.0 \\
       --crop-roi --roi-padding 2 \\
       --filtration sublevel \\
       --construction T \\
       --max-dimension 2 \\
       --methods persistence_stats betti_curve entropy_summary \\
       --save-barcodes \\
       --workers 8 --verbose

Troubleshooting
===============

**Command not found: medtda**

.. code-block:: bash

   # Reinstall or use module form
   pip install --force-reinstall medtda
   # Or
   python -m medtda --version

**--mask ignored in batch mode**

Use CSV ``mask_path`` column instead of ``--mask`` argument.

**Workers argument ignored in single file mode**

Parallelization only applies to batch mode. Single files process sequentially.

**Output directory not created**

The CLI creates the directory automatically. Check write permissions.

**Different number of features per case**

Check batch_features.csv for errors. Failed cases will have ``status='error'``.

**Processing very slow**

* Use parallel processing (``--workers 4`` or more)
* Enable ROI cropping (``--crop-roi``)
* Reduce max_dimension (``--max-dimension 1``)
* Downsample (``--spacing 2.0 2.0 2.0``)

Full Help Output
================

.. code-block:: bash

   $ medtda --help

Shows complete usage information with all arguments and examples.

Next Steps
==========

* :doc:`user_guide/batch_processing` - Detailed batch processing guide
* :doc:`user_guide/preprocessing` - Preprocessing options
* :doc:`user_guide/vectorization` - Choosing vectorization methods
* :doc:`examples/cli_workflows` - CLI workflow examples
* :doc:`api/cli` - CLI module API reference
