coco_pipe.descriptors.extractors.complexity =========================================== .. py:module:: coco_pipe.descriptors.extractors.complexity .. autoapi-nested-parse:: Complexity descriptor extraction backend. This module implements the built-in complexity family for `coco_pipe.descriptors`. The extractor operates on already segmented NumPy inputs with shape ``(n_obs, n_channels, n_times)`` and computes one or more complexity measures per sensor, per observation. .. rubric:: Notes The complexity family prefers batched backend calls when the selected library supports them. In the current implementation: - `spectral_entropy`, `hjorth_mobility`, and `hjorth_complexity` use batched `antropy` calls over flattened observation-channel units - `sample_entropy`, `perm_entropy`, `approx_entropy`, `svd_entropy`, `petrosian_fd`, `katz_fd`, `higuchi_fd`, and `lziv_complexity` are still evaluated one 1D signal at a time - `shannon_entropy`, `fuzzy_entropy`, `dispersion_entropy`, and `hurst_exponent` use scalar `neurokit2` calls - `zero_crossings`, `kurtosis`, and `rms` are computed as simple scalar channelwise signal descriptors Author: Hamza Abdelhedi (hamza.abdelhedi@umontreal.ca) Attributes ---------- .. autoapisummary:: coco_pipe.descriptors.extractors.complexity._ANTROPY_BATCHED_MEASURES coco_pipe.descriptors.extractors.complexity._ANTROPY_SCALAR_MEASURES coco_pipe.descriptors.extractors.complexity._NEUROKIT_SCALAR_MEASURES coco_pipe.descriptors.extractors.complexity._CUSTOM_SCALAR_MEASURES Classes ------- .. autoapisummary:: coco_pipe.descriptors.extractors.complexity.ComplexityDescriptorExtractor Functions --------- .. autoapisummary:: coco_pipe.descriptors.extractors.complexity._normalize_scalar_output Module Contents --------------- .. py:data:: _ANTROPY_BATCHED_MEASURES .. py:data:: _ANTROPY_SCALAR_MEASURES .. py:data:: _NEUROKIT_SCALAR_MEASURES .. py:data:: _CUSTOM_SCALAR_MEASURES .. py:function:: _normalize_scalar_output(value: Any) -> float Normalize backend scalar outputs to one plain float. .. py:class:: ComplexityDescriptorExtractor(config: coco_pipe.descriptors.configs.ComplexityDescriptorConfig) Bases: :py:obj:`coco_pipe.descriptors.extractors.base.BaseDescriptorExtractor` Complexity descriptor extractor. This extractor computes scalar complexity measures for each observation and sensor in a validated descriptor input array. It is intended for signals that are already segmented upstream, such as epochs, windows, or trial blocks. :param config: Parsed family configuration controlling the selected measures, backend, and any per-measure keyword arguments. :type config: ComplexityDescriptorConfig .. attribute:: config Stored typed configuration for the complexity family. :type: ComplexityDescriptorConfig .. attribute:: family_name Stable family identifier used in metadata and failure records. :type: str .. rubric:: Notes The extractor always computes descriptor values per sensor first. Public deterministic sensor-level naming is applied afterward through :meth:`BaseDescriptorExtractor._finalize_descriptor`. When `backend="auto"` is selected, the extractor resolves each measure to the preferred available implementation: - `antropy` for the existing antropy-backed measures - `neurokit2` for measures that are only supported there - built-in NumPy/SciPy implementations for simple scalar signal summaries .. py:attribute:: family_name :value: 'complexity' .. py:attribute:: config .. py:property:: capabilities :type: dict[str, Any] Return static complexity extractor capability metadata. :returns: Capability metadata describing sampling-rate requirements and the optional backends used by the complexity family. :rtype: dict[str, Any] .. rubric:: Notes `spectral_entropy` requires an explicit sampling rate, while the other currently supported measures do not. .. py:method:: _load_antropy() Import `antropy` lazily when the configured backend needs it. :returns: Imported `antropy` module. :rtype: module :raises ImportError: If `antropy` is not installed. .. py:method:: _load_neurokit() Import `neurokit2` lazily when the configured backend needs it. :returns: Imported `neurokit2` module. :rtype: module :raises ImportError: If `neurokit2` is not installed. .. py:method:: extract(X: numpy.ndarray, sfreq: float | None, channel_names: list[str] | None, ids: numpy.ndarray | None, runtime, obs_offset: int = 0) -> coco_pipe.descriptors.extractors.base._DescriptorBlock Extract complexity descriptors from segmented multi-channel data. :param X: Input array with shape ``(n_obs, n_channels, n_times)``. Each row already represents one observation segment produced upstream. :type X: np.ndarray :param sfreq: Sampling frequency in Hertz. Required when `spectral_entropy` is requested. :type sfreq: float, optional :param channel_names: Explicit channel labels aligned with axis 1 of ``X``. If omitted, fallback names ``"ch-0"``, ``"ch-1"``, ... are used internally. :type channel_names: list of str, optional :param ids: Observation identifiers aligned with axis 0 of ``X``. :type ids: np.ndarray, optional :param runtime: Runtime execution controls shared across descriptor families. :type runtime: DescriptorRuntimeConfig :param obs_offset: Global observation offset added to any collected failure records when this extractor is called on one observation batch. :type obs_offset: int, default=0 :returns: Complexity-family descriptor block aligned with the input observation axis. :rtype: _DescriptorBlock :raises ImportError: If the configured optional backend is unavailable. :raises ValueError: If a requested measure is unsupported by the selected backend, or if runtime error handling is configured to raise on a numerical or backend failure. .. rubric:: Notes The extractor uses a mixed execution strategy: - batched `antropy` calls for `spectral_entropy`, `hjorth_mobility`, and `hjorth_complexity` - scalar `antropy` calls for the remaining antropy-backed measures - scalar `neurokit2` calls for `shannon_entropy`, `fuzzy_entropy`, `dispersion_entropy`, and `hurst_exponent` Non-finite outputs are converted to `NaN` and recorded under ``failures`` unless `runtime.on_error == "raise"`, in which case the extractor fails immediately. .. rubric:: Example With ``channel_names=["Fz", "Cz"]``, a requested measure such as ``perm_entropy`` yields channel-resolved names like ``complexity_perm_entropy_ch-Fz`` and ``complexity_perm_entropy_ch-Cz``.