===========
Quick Start
===========

This guide will get you up and running with Med-TDA in 5 minutes.

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

If you haven't already, install Med-TDA:

.. code-block:: bash

   pip install medtda

All dependencies (including SimpleITK for medical images) will be installed automatically.

Basic Usage: Single Image
==========================

Extract TDA features from a single medical image with a few lines of code:

.. code-block:: python

   from medtda import FeatureExtractor
   
   # Initialize the feature extractor
   extractor = FeatureExtractor(
       normalize=True,
       vectorization_method='PersStats'
   )
   
   # Extract features from image and mask
   features = extractor.execute(
       image='path/to/image.nii.gz',
       mask='path/to/mask.nii.gz'
   )
   
   # features is a dictionary of TDA features
   print(f"Extracted {len(features)} features")
   print(list(features.keys())[:5])  # Show first 5 feature names

**Expected Output:**

.. code-block:: text

   Extracted 114 features
   ['PersStats_H0_mean', 'PersStats_H0_std', 
    'PersStats_H0_min', 'PersStats_H0_max', 
    'PersStats_H0_median']

Working with 2D Images
----------------------

MedTDA also works with 2D images (PNG, JPG, TIFF):

.. code-block:: python

   from medtda import FeatureExtractor
   import numpy as np
   from PIL import Image
   
   # Load 2D image
   image = np.array(Image.open('image.png').convert('L'))
   
   # Extract features
   extractor = FeatureExtractor(
       normalize=True,
       vectorization_method='PersStats'
   )
   features = extractor.execute(image)

Without a Mask
--------------

You can extract features without a mask:

.. code-block:: python

   # Extract features from full image (no mask)
   features = extractor.execute(image='image.nii.gz')

Using NumPy Arrays
------------------

Pass NumPy arrays directly instead of file paths:

.. code-block:: python

   import numpy as np
   import SimpleITK as sitk
   
   # Load image as NumPy array
   image_sitk = sitk.ReadImage('image.nii.gz')
   image_array = sitk.GetArrayFromImage(image_sitk)
   
   # Extract features from array
   features = extractor.execute(image=image_array)

Multiple Vectorization Methods
===============================

Extract features using multiple vectorization methods simultaneously:

.. code-block:: python

   extractor = FeatureExtractor(
       normalize=True,
       vectorization_method=[
           'PersStats',
           'BettiCurve',
           'EntropySummary'
       ]
   )
   
   features = extractor.execute('image.nii.gz', 'mask.nii.gz')
   print(f"Total features from all methods: {len(features)}")

This combines features from all specified methods into a single dictionary.

Preprocessing Options
=====================

Customize preprocessing with various options:

.. code-block:: python

   extractor = FeatureExtractor(
       # Preprocessing
       spacing=(1.0, 1.0, 1.0),      # Resample to 1mm isotropic
       window=(40, 400),              # CT windowing (center, width)
       normalize=True,                # Normalize intensities
       normalize_method='minmax',     # Normalization method
       crop_to_roi=True,             # Crop to ROI for efficiency
       roi_padding=2,                # Padding around ROI
       
       # Persistent Homology
       filtration_type='sublevel',   # Filtration type
       construction='T',             # Cubical complex construction
       max_dimension=2,              # Compute H0, H1, H2
       
       # Vectorization
       vectorization_method='PersStats'
   )
   
   features = extractor.execute('image.nii.gz', 'mask.nii.gz')

Getting Barcodes
================

Return persistence barcodes along with features:

.. code-block:: python

   extractor = FeatureExtractor(
       normalize=True,
       vectorization_method='PersStats',
       return_barcodes=True  # Return barcodes
   )
   
   # Now returns a tuple: (features, barcodes)
   features, barcodes = extractor.execute('image.nii.gz', 'mask.nii.gz')
   
   # barcodes is a dictionary: {'H0': array, 'H1': array, 'H2': array}
   # where keys are homology dimension labels
   print(f"H0 features: {barcodes['H0'].shape}")  # (n_features, 2) birth-death pairs
   print(f"H1 features: {barcodes['H1'].shape}")

Batch Processing (Python)
==========================

Process multiple images in a loop:

.. code-block:: python

   import pandas as pd
   from medtda import FeatureExtractor
   
   # List of images to process
   cases = [
       {'id': 'case001', 'image': 'scan1.nii.gz', 'mask': 'mask1.nii.gz'},
       {'id': 'case002', 'image': 'scan2.nii.gz', 'mask': 'mask2.nii.gz'},
       {'id': 'case003', 'image': 'scan3.nii.gz', 'mask': 'mask3.nii.gz'},
   ]
   
   # Initialize extractor
   extractor = FeatureExtractor(
       normalize=True,
       vectorization_method='PersStats'
   )
   
   # Extract features for all cases
   results = []
   for case in cases:
       try:
           features = extractor.execute(case['image'], case['mask'])
           features['id'] = case['id']
           results.append(features)
       except Exception as e:
           print(f"Error processing {case['id']}: {e}")
   
   # Convert to DataFrame
   df = pd.DataFrame(results)
   print(df.head())
   
   # Save to CSV
   df.to_csv('tda_features.csv', index=False)

Command-Line Interface
======================

MedTDA provides a powerful CLI for batch processing:

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

.. code-block:: bash

   # Basic usage
   medtda image.nii.gz --output-dir ./results
   
   # With mask and preprocessing
   medtda image.nii.gz --mask mask.nii.gz --output-dir ./results \
       --normalize --spacing 1.0 1.0 1.0 \
       --methods persistence_stats betti_curve

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

Create a CSV file with your cases:

.. code-block:: csv

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

Process all cases:

.. code-block:: bash

   # Sequential processing
   medtda cases.csv --output-dir ./results --normalize --verbose
   
   # Parallel processing with 4 workers
   medtda cases.csv --output-dir ./results --workers 4 --verbose
   
   # Use all CPU cores
   medtda cases.csv --output-dir ./results --workers -1

Configuration Files
-------------------

Use YAML configuration files for reproducibility:

.. code-block:: yaml

   # config.yaml
   preprocessing:
     normalize: true
     normalize_method: minmax
     spacing: [1.0, 1.0, 1.0]
     crop_roi: true
   
   persistent_homology:
     filtration: sublevel
     max_dimension: 2
   
   vectorization:
     methods:
       - persistence_stats
       - betti_curve
   
   output:
     output_dir: ./results

Then run:

.. code-block:: bash

   medtda cases.csv --config config.yaml

Outputs
=======

Single File Processing
----------------------

When processing a single file, MedTDA creates:

* ``image_name_features.csv`` - Feature vectors (one row)
* ``image_name_config.yaml`` - Configuration used (for reproducibility)
* ``image_name_barcodes.pkl`` - Persistence barcodes (if ``--save-barcodes``)

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

When processing multiple files, MedTDA creates:

* ``batch_features.csv`` - All features combined (one row per case)
* ``config.yaml`` - Configuration used
* ``case_id_barcodes.pkl`` - Individual barcodes (if ``--save-barcodes``)

Using Features in Machine Learning
===================================

The extracted features are ready for machine learning:

.. code-block:: python

   import pandas as pd
   from sklearn.ensemble import RandomForestClassifier
   from sklearn.model_selection import train_test_split
   
   # Load extracted features
   features_df = pd.read_csv('batch_features.csv')
   
   # Prepare data (assuming you have labels)
   X = features_df.drop(['id', 'label'], axis=1)
   y = features_df['label']
   
   # Split data
   X_train, X_test, y_train, y_test = train_test_split(
       X, y, test_size=0.2, random_state=42
   )
   
   # Train classifier
   clf = RandomForestClassifier(n_estimators=100, random_state=42)
   clf.fit(X_train, y_train)
   
   # Evaluate
   score = clf.score(X_test, y_test)
   print(f"Accuracy: {score:.3f}")

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

Now that you know the basics:

- **Learn More:** :doc:`user_guide` - Comprehensive guide to all features
- **CLI Reference:** :doc:`cli` - Complete command-line documentation
- **API Docs:** :doc:`api/index` - Detailed API reference
- **Theory:** :doc:`theory/index` - Understanding TDA concepts
- **Examples:** :doc:`examples/index` - More practical examples

Common Next Questions
=====================

**How do I choose a vectorization method?**
   See :doc:`user_guide/vectorization` for guidance on selecting methods.

**What preprocessing should I use?**
   See :doc:`user_guide/preprocessing` for detailed preprocessing options.

**How does persistent homology work?**
   See :doc:`theory/persistent_homology` for TDA background.

**How can I visualize persistence diagrams?**
   See :doc:`examples/basic_usage` for visualization examples.

**My processing is slow, how can I speed it up?**
   See :doc:`faq` for performance optimization tips.
