coco_pipe.descriptors.extractors.base¶
Base interfaces for descriptor extraction backends.
This module defines the internal contracts shared by built-in descriptor extractors. The module exposes:
BaseDescriptorExtractor for families that consume validated raw signal batches
BasePSDDescriptorExtractor for families that consume shared PSD batches
_DescriptorBlock as the private family output payload
make_failure_record as the shared normalized failure-record helper
The surrounding descriptors stack uses these interfaces to provide:
explicit runtime dispatch from DescriptorPipeline
deterministic sensor-level descriptor naming
family-wise metadata and failure collection
safe merging of family outputs into one stable result dictionary
Notes
BaseDescriptorExtractor is an internal extension point for descriptor families. Unlike dim-reduction reducers, descriptor extractors are stateless at runtime and do not expose fit, persistence, or model objects.
Author: Hamza Abdelhedi (hamza.abdelhedi@umontreal.ca)
Classes¶
Abstract base class for descriptor extraction families. |
|
Abstract base class for descriptor families that consume PSD batches. |
Functions¶
|
Create one normalized extractor failure record. |
Module Contents¶
- coco_pipe.descriptors.extractors.base.make_failure_record(family: str, obs_index: int, obs_id: Any = None, channel_index: int | None = None, channel_name: str | None = None, exception_type: str | None = None, message: str | None = None) dict[str, Any][source]¶
Create one normalized extractor failure record.
- class coco_pipe.descriptors.extractors.base.BaseDescriptorExtractor(config: Any)[source]¶
Bases:
abc.ABCAbstract base class for descriptor extraction families.
Subclasses receive already validated NumPy inputs and must return one _DescriptorBlock aligned on the observation axis. The base class keeps the extractor API narrow and provides a shared helper for sensor-level finalization and deterministic descriptor naming.
- Parameters:
config (Any) – Typed family configuration parsed by DescriptorConfig.
- config¶
Stored family-specific configuration object.
- Type:
Any
- family_name¶
Stable family identifier used in failure records and merged metadata.
- Type:
str
Notes
Extractors are stateless at runtime. They do not learn parameters across calls; all runtime state is provided explicitly through extract().
Concrete extractors are expected to:
compute family-specific values with shape
(n_obs, n_channels)for each metricpass those values through
_finalize_descriptor()return one _DescriptorBlock with aligned names, metadata, and failures
Examples
A minimal concrete extractor typically looks like:
>>> class MeanOverTimeExtractor(BaseDescriptorExtractor): ... family_name = "toy" ... ... def extract( ... self, ... X, ... sfreq, ... channel_names, ... ids, ... runtime, ... ): ... values = X.mean(axis=-1) ... X_out, names = self._finalize_descriptor( ... values, ... family_prefix="toy", ... metric_name="mean", ... channel_names=channel_names, ... ) ... return _DescriptorBlock( ... family=self.family_name, ... X=X_out, ... descriptor_names=names, ... )
- family_name = 'base'¶
- config¶
- property capabilities: dict[str, Any]¶
Return static extractor capability metadata.
- Returns:
Static metadata describing optional dependencies and general execution properties for the extractor.
- Return type:
dict[str, Any]
Notes
The descriptors pipeline currently uses this mapping only as lightweight backend metadata. It is intentionally much smaller than the reducer capability surface in dim_reduction.
- abstract extract(X: numpy.ndarray, sfreq: float | None, channel_names: list[str] | None, ids: numpy.ndarray | None, runtime: coco_pipe.descriptors.configs.DescriptorRuntimeConfig, obs_offset: int = 0) _DescriptorBlock[source]¶
Extract descriptors from a validated input array.
- Parameters:
X (np.ndarray) – Input array with shape
(n_obs, n_channels, n_times).sfreq (float, optional) – Sampling frequency in Hertz.
channel_names (list of str, optional) – Explicit channel labels aligned with axis 1 of
X.ids (np.ndarray, optional) – Observation identifiers aligned with axis 0 of
X.runtime (DescriptorRuntimeConfig) – Runtime execution controls shared across extractors.
obs_offset (int, default=0) – Global observation offset applied to any collected failure records.
- Returns:
Family-specific descriptor matrix plus metadata and failures.
- Return type:
_DescriptorBlock
- Raises:
ImportError – If an optional backend required by the extractor is unavailable.
ValueError – If the extractor encounters an invalid runtime condition and the configured error policy requires raising.
Notes
The recommended pattern is to keep family-specific computation local to the extractor and delegate sensor-level naming behavior to
_finalize_descriptor().
- _finalize_descriptor(values: numpy.ndarray, family_prefix: str, metric_name: str, channel_names: list[str] | None) tuple[numpy.ndarray, list[str]][source]¶
Build deterministic sensor-level descriptor names.
- Parameters:
values (np.ndarray) – Family metric values with shape
(n_obs, n_channels)or(n_obs,).family_prefix (str) – Stable family prefix, for example
"band"or"param".metric_name (str) – Family-local metric identifier used in the descriptor name.
channel_names (list of str, optional) – Channel labels used when building channel-resolved descriptor names.
- Returns:
(X_metric, names)whereX_metricis the finalized metric matrix andnamesis the aligned list of descriptor names.- Return type:
tuple
Notes
This helper assumes
valuesalready represents descriptor values, not raw signals. It therefore only handles the stable sensor-level naming convention used by the public extract result.Examples
Given
channel_names=["Fz", "Cz", "Pz"]andmetric_name="abs_alpha":yields
["band_abs_alpha_ch-Fz", "band_abs_alpha_ch-Cz", "band_abs_alpha_ch-Pz"]
- class coco_pipe.descriptors.extractors.base.BasePSDDescriptorExtractor(config: Any)[source]¶
Bases:
BaseDescriptorExtractorAbstract base class for descriptor families that consume PSD batches.
PSD-consuming families still participate in the shared descriptor contract, but they expose one additional explicit entry point:
extract_psd(…) consumes precomputed psds, freqs
psd_request() tells the planner which PSD range and method is needed
This keeps the generic raw-signal interface narrow while still giving the planner one formal PSD-consumer contract shared by spectral and parametric families.
Notes
PSD consumers may still expose extract() to satisfy the generic family interface, but the shared planner uses psd_request() and extract_psd() exclusively once PSD intermediates have been materialized.
- abstract psd_request() dict[str, Any][source]¶
Describe the PSD requirements for the shared planner.
- Returns:
Minimal request payload containing the PSD method and the required frequency range for this family.
- Return type:
dict[str, Any]
- parametric_fit_requirements() dict[str, Any][source]¶
Describe whether this PSD consumer needs a shared parametric fit.
- Returns:
Shared-fit requirements with the keys:
needed
metrics
periodic_psds
config
- Return type:
dict[str, Any]
- abstract extract_psd(psds: numpy.ndarray, freqs: numpy.ndarray, channel_names: list[str] | None, ids: numpy.ndarray | None, runtime: coco_pipe.descriptors.configs.DescriptorRuntimeConfig, obs_offset: int = 0, fit_batch: Any | None = None) _DescriptorBlock[source]¶
Extract descriptors from explicit PSD intermediates.
- Parameters:
psds (np.ndarray) – PSD batch with shape
(n_obs, n_channels, n_freqs).freqs (np.ndarray) – Frequency grid aligned with the last axis of
psds.channel_names (list of str, optional) – Explicit channel labels aligned with the channel axis.
ids (np.ndarray, optional) – Observation identifiers aligned with the observation axis.
runtime (DescriptorRuntimeConfig) – Runtime execution controls shared across extractors.
obs_offset (int, default=0) – Global observation offset applied to collected failure records.
fit_batch (Any, optional) – Additional shared fit payload required by some PSD consumers.
- Returns:
Family-specific descriptor block aligned with the input PSD batch.
- Return type:
_DescriptorBlock