.. _api_featureextractor: ================ FeatureExtractor ================ .. currentmodule:: medtda The ``FeatureExtractor`` class is the main high-level interface for extracting topological features from medical images. .. contents:: Contents :local: :depth: 2 Overview ======== ``FeatureExtractor`` combines preprocessing, persistent homology computation, and vectorization into a single convenient interface. It is the recommended entry point for most users. **Key Features:** * End-to-end feature extraction pipeline * Configurable preprocessing options * Multiple vectorization methods * Batch processing support * Optional raw barcode extraction Basic Usage =========== Quick Start ----------- Extract features from a single image:: from medtda import FeatureExtractor # Create extractor with default settings extractor = FeatureExtractor() # Extract features features = extractor.execute('path/to/image.nii.gz') With Mask --------- Process an image with a binary mask:: extractor = FeatureExtractor( normalize=True, vectorization_method='PersImage' features = extractor.execute( image='path/to/image.nii.gz', mask='path/to/mask.nii.gz' ) Multiple Vectorization Methods ------------------------------- Extract features using multiple methods simultaneously:: extractor = FeatureExtractor() extractor.enable_vectorization_methods([ 'PersStats', 'BettiCurve', 'PersImage' ]) features = extractor.execute('image.nii.gz') # features is a dict with keys like: 'PersStats_H0_mean', 'BettiCurve_H0_f0', etc. Class Documentation =================== .. autoclass:: medtda.FeatureExtractor :members: :undoc-members: :show-inheritance: :special-members: __init__ Constructor Parameters ====================== Preprocessing Parameters ------------------------ .. list-table:: :widths: 20 20 60 :header-rows: 1 * - Parameter - Type - Description * - ``spacing`` - tuple or None - Target voxel spacing for resampling (e.g., ``(1.0, 1.0, 1.0)``) * - ``window`` - tuple or None - Windowing as ``(center, width)`` for CT images * - ``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-detected if ``None``) * - ``label`` - int or None - Extract specific label from multi-label mask (default: ``1``) * - ``crop_to_roi`` - bool - Crop to ROI bounding box (default: ``True``) * - ``roi_padding`` - int - Padding around ROI in pixels (default: ``1``) Persistent Homology Parameters ------------------------------- .. list-table:: :widths: 20 20 60 :header-rows: 1 * - Parameter - Type - Description * - ``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``) Vectorization Parameters ------------------------- .. list-table:: :widths: 20 20 60 :header-rows: 1 * - Parameter - Type - Description * - ``vectorization_method`` - str or list - Vectorization method(s) to use (default: ``'PersStats'``) * - ``return_barcodes`` - bool - Return raw barcodes with features (default: ``False``) Valid vectorization methods: * ``'PersStats'`` - Statistical summaries * ``'BettiCurve'`` - Betti numbers over filtration * ``'PersImage'`` - 2D histogram representation * ``'PersLandscape'`` - Functional landscape * ``'PersSilhouette'`` - Average landscape * ``'EntropySummary'`` - Information-theoretic features * ``'PersLifespan'`` - Lifespan distribution * ``'PersTropicalCoordinates'`` - Tropical algebra Methods ======= execute ------- .. automethod:: medtda.FeatureExtractor.execute :noindex: **Signature:** .. code-block:: python def execute( self, image: Union[str, Path, np.ndarray], mask: Union[str, Path, np.ndarray, None] = None ) -> Union[Dict[str, np.ndarray], Tuple[Dict[str, np.ndarray], Dict[int, np.ndarray]]] **Parameters:** * **image** (*str, Path, or np.ndarray*) - Input image (file path or array) * **mask** (*str, Path, np.ndarray, or None*) - Optional binary mask **Returns:** * **features** (*dict*) - Dictionary mapping feature names to values. Keys follow format: '{method}_{dimension}_{feature}' for dict-based methods or '{method}_{dimension}_f{i}' for array-based methods. * **OR (features, barcodes)** (*tuple*) - If ``return_barcodes=True`` **Example:** :: extractor = FeatureExtractor( normalize=True, vectorization_method='PersImage', return_barcodes=True ) features, barcodes = extractor.execute('image.nii.gz', mask='mask.nii.gz') # features is a dict: {'PersImage_H0_f0': 0.12, 'PersImage_H0_f1': 0.45, ...} # barcodes is a dict: {0: array([[b,d],...]), 1: array([[b,d],...])} set_vectorization_method ------------------------- .. automethod:: medtda.FeatureExtractor.set_vectorization_method :noindex: Change the vectorization method and its parameters. **Signature:** .. code-block:: python def set_vectorization_method(self, method: str, **params) -> None **Parameters:** * **method** (*str*) - Vectorization method name * **params** - Method-specific parameters **Example:** :: extractor = FeatureExtractor() # Change to persistence image with custom parameters extractor.set_vectorization_method( 'PersImage', resolution=50, bandwidth=0.1 ) enable_vectorization_methods ----------------------------- .. automethod:: medtda.FeatureExtractor.enable_vectorization_methods :noindex: Enable multiple vectorization methods. **Signature:** .. code-block:: python def enable_vectorization_methods(self, methods: List[str]) -> None **Parameters:** * **methods** (*list of str*) - List of vectorization method names **Example:** :: extractor = FeatureExtractor() extractor.enable_vectorization_methods([ 'PersStats', 'BettiCurve', 'PersImage' ]) features = extractor.execute('image.nii.gz') # Returns dict with 3 keys set_vectorization_params ------------------------------- .. automethod:: medtda.FeatureExtractor.set_vectorization_params :noindex: Configure parameters for a specific vectorization method when using multiple methods. **Signature:** .. code-block:: python def set_vectorization_params(self, method: str, **params) -> None **Parameters:** * **method** (*str*) - Vectorization method name * **params** - Method-specific parameters **Example:** :: extractor = FeatureExtractor() extractor.enable_vectorization_methods(['BettiCurve', 'PersImage']) # Configure individual method parameters extractor.set_vectorization_params('BettiCurve', resolution=200) extractor.set_vectorization_params('PersImage', resolution=30) Complete Example ================ Advanced Usage with All Options -------------------------------- :: from medtda import FeatureExtractor import numpy as np # Initialize with comprehensive configuration extractor = FeatureExtractor( # Preprocessing spacing=(1.0, 1.0, 1.0), window=(40, 400), # CT abdomen window 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='PersImage', return_barcodes=True ) # Extract features features, barcodes = extractor.execute( image='path/to/ct_scan.nii.gz', mask='path/to/liver_mask.nii.gz' ) # Access results # features is a flat dict: {'PersImage_H0_f0': 0.12, 'PersImage_H0_f1': 0.45, ...} h0_barcode = barcodes['H0'] # Connected components h1_barcode = barcodes['H1'] # Loops/tunnels h2_barcode = barcodes['H2'] # Voids/cavities print(f"Feature vector shape: {pi_features.shape}") print(f"H1 features: {len(h1_barcode)} persistence pairs") Multi-Method Extraction ----------------------- :: from medtda import FeatureExtractor # Create extractor extractor = FeatureExtractor(normalize=True) # Configure multiple methods extractor.enable_vectorization_methods([ 'PersStats', 'BettiCurve', 'PersImage', 'PersLandscape' ]) # Customize parameters for each extractor.set_vectorization_params('BettiCurve', resolution=150) extractor.set_vectorization_params('PersImage', resolution=25, bandwidth=0.15) extractor.set_vectorization_params('PersLandscape', num_landscapes=10) # Extract all features — returns flat dict of individual feature values features = extractor.execute('image.nii.gz') # Use in machine learning import numpy as np feature_vector = np.array(list(features.values())) See Also ======== * :doc:`preprocessor` - Preprocessing details * :doc:`barcodeextractor` - Raw barcode extraction * :doc:`vectorizers` - Vectorization methods * :doc:`../user_guide` - User guide and tutorials * :doc:`../quickstart` - Quick start examples