Coverage for packages/dqm-ml-core/src/dqm_ml_core/api/gap_processor.py: 100%
25 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-21 08:27 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-07-21 08:27 +0000
1"""Gap processor base class.
3This module contains the GapProcessor base class that all
4domain gap processors must inherit from.
5"""
7import logging
8from typing import Any
10import pyarrow as pa
12from dqm_ml_core.api.processor import Processor
13from dqm_ml_core.utils.matching import resolve_include_exclude
15logger = logging.getLogger(__name__)
18class GapProcessor(Processor):
19 """
20 Base class for all domain gap processors.
22 Gap processors compute distribution shift between two datasets
23 (e.g., MMD, FID, KL divergence). The primary lifecycle methods are
24 ``select_features`` (per-batch column selection aware of previous features),
25 ``compute_batch_metric`` (batch aggregation), ``compute`` (final dataset-level
26 statistics), and ``compute_delta`` (pairwise comparison).
27 """
29 def select_features(self, batch: pa.RecordBatch, prev_features: dict[str, pa.Array]) -> dict[str, pa.Array]:
30 """
31 Extract relevant columns from a batch, resolving patterns against
32 both batch columns and previously computed upstream features.
34 Args:
35 batch: The input pyarrow RecordBatch.
36 prev_features: Features already computed by preceding processors.
38 Returns:
39 A dictionary mapping column names to pyarrow Arrays.
40 """
41 available = list(prev_features.keys()) + batch.schema.names
42 cols = resolve_include_exclude(
43 self.input_columns,
44 self.exclude_columns,
45 available,
46 )
48 features: dict[str, pa.Array] = {}
49 for col in cols:
50 if col in prev_features:
51 continue
52 if col not in batch.schema.names:
53 logger.warning(f"[{self.name}] column '{col}' not found in batch")
54 continue
55 features[col] = batch.column(col)
57 return features
59 def compute_batch_metric(self, features: dict[str, pa.Array]) -> dict[str, pa.Array]:
60 """
61 Aggregate features into intermediate statistics for the current batch.
63 Args:
64 features: Dictionary of feature arrays computed on the batch.
66 Returns:
67 A dictionary of aggregated statistics.
68 """
69 return {}
71 def compute(self, batch_metrics: dict[str, pa.Array]) -> dict[str, Any]: # NOSONAR
72 """
73 Perform the final dataset-level aggregation of batch statistics.
75 Args:
76 batch_metrics: The aggregated intermediate statistics from all batches.
78 Returns:
79 A dictionary containing the final dataset-level statistics.
80 """
81 # SonarQube raises a warning because batch_metrics is not used.
82 # It is irrelevant because compute is implemented in child classes which use batch_metrics.
83 return {}
85 def compute_delta(self, source: dict[str, Any], target: dict[str, Any]) -> dict[str, Any]:
86 """
87 Compare metrics between two different dataselections.
89 Args:
90 source: Final metrics from the source dataselection.
91 target: Final metrics from the target dataselection.
93 Returns:
94 A dictionary containing distance or difference scores.
95 """
96 return {}