factrix.inspect_data ¶
inspect_data(data: Any, factor_cols: Sequence[str] | None = None) -> DataInspection
Inspect data and return typed dispatch-axis + per-metric verdict.
Pre-flight introspection: typed detection plus, for every
role=SpecRole.METRIC :class:MetricSpec in the registry, a
:class:MetricApplicability verdict combining (a) cell-match
against the detected (scope, density, structure) and (b) the
spec's optional :class:SampleThreshold against the data's
n_periods / n_assets / n_pairs / n_events.
The n_events floor is pre-flighted against the non-zero factor
count for event-driven metrics; a metric with a dynamic event floor
(caar) is pre-flighted at its default config, and its in-body
short-circuit on the actual run-time params stays authoritative.
A third, content-based gate beyond cell and sample shape: a metric
declaring requires_continuous_magnitude (e.g. event_ic) is
blocked on a discrete ±k signal (|factor| constant across events,
such as a ternary {-1, 0, +1} indicator), matching its run-time
not_applicable_discrete_signal short-circuit.
Multi-factor input: the inspected :class:DataProperties and every
per-metric verdict are computed from the first factor column only
(deterministic first-detected). When columns disagree on
FactorDensity or FactorScope a CROSS_FACTOR_*_MISMATCH
data-level warning is emitted directing the caller to re-run
inspect_data(data, factor_cols=[col]) for a column-specific verdict.
Other per-column properties (e.g. signal magnitude, n_events) are
likewise first-column-based; for a heterogeneous panel prefer the
per-column call.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Any
|
Long-format factor data with the canonical columns.
The baseline columns |
required |
factor_cols
|
Sequence[str] | None
|
Optional list of factor columns to check. When
|
None
|
Returns:
| Type | Description |
|---|---|
DataInspection
|
class: |
Examples:
Usability Tiers¶
inspect_data partitions public metrics into three distinct groups based on the inspected data shape and the metric's declarative sample_threshold:
- Usable: The metric is fully applicable and the data shape satisfies all warning thresholds (
warn_*). This is the safest set to run out-of-the-box. - Degraded: The metric is applicable but runs with a warning because the sample size is borderline (falls between the hard
min_*floor and the softwarn_*threshold). - Unusable: The metric cannot be run on this data, either because of a cell mismatch or because a hard sample floor (
min_*) is violated.
Scalar-input helpers such as breakeven_cost and net_spread are also listed
as unusable for panel data. They consume already computed scalar values
(quantile_spread.value, notional_turnover.value) rather than a panel, so run
the upstream diagnostics first and call the helper directly.
Result structure¶
inspect_data returns a DataInspection carrying the detected data
properties (properties), the per-metric applicability verdicts
(metrics, plus the usable / degraded / unusable partitions), and
any data-level warnings. Each entry in the metrics group is a
MetricApplicability.
The tier groups are MetricApplicabilityGroup objects: they expose .names
and .to_metrics_dict(), and slicing or concatenating them with + preserves
those helpers.
factrix.DataInspection
dataclass
¶
DataInspection(properties: DataProperties, metrics: list[MetricApplicability], warnings: list[Warning] = list())
Result of :func:inspect_data.
Pure data — no execution methods.
Attributes:
| Name | Type | Description |
|---|---|---|
properties |
DataProperties
|
:class: |
metrics |
list[MetricApplicability]
|
Flat |
warnings |
list[Warning]
|
Data-level sample-shape diagnostics (NW HAC SE
unreliable, cross-asset df low). |
degraded
property
¶
degraded: MetricApplicabilityGroup
Applicable metrics that run but with degraded inference.
usable=True yet at least one warn_*-tier
:class:Warning attached (e.g. NW HAC SE unreliable at short
n_periods). They produce a value, but the caller should
read the warnings before trusting the inference. Disjoint from
:attr:usable and :attr:unusable.
unusable
property
¶
unusable: MetricApplicabilityGroup
Metrics that cannot run on this data.
usable=False — blocked by cell mismatch or a min_*
floor violation; :attr:MetricApplicability.blockers carries
the concrete reasons. Disjoint from :attr:usable and
:attr:degraded.
usable
property
¶
usable: MetricApplicabilityGroup
Metrics that are applicable AND carry no degraded warning.
The production-safe set: every verdict here passed cell match
and every min_* floor with zero warn_* violations.
usable / :attr:degraded / :attr:unusable form a
mutually exclusive partition of :attr:metrics — a
verdict appears in exactly one. usable deliberately
excludes degraded verdicts so it can be the single safe set
a bulk discovery flow runs without re-filtering. The
"usable but warned" verdicts live in :attr:degraded.
Returns a :class:MetricApplicabilityGroup (a list subclass);
.to_metrics_dict() normalises it straight into the
metrics= argument of :func:factrix.evaluate.
to_dict ¶
JSON-friendly nested dict view.
Layout (top-level keys, stable order):
properties:{scope, density, structure, n_assets, n_periods, n_pairs, sparse_ratio}— enum fields rendered as their.valuestring;sparse_ratioNaNemitted asNone.reasoning:{scope, density, structure}.metrics: list of per-spec dicts{name, cell, usable, warnings, blockers}— same row shape suitspl.from_dictsfor cross-data audit.warnings: data-level[{code, source, message}, ...].
Mirrors :meth:factrix.EvaluationResult.to_dict shape — single
to_dict convention across the public result-type group so
log / parquet sinks treat them uniformly.
factrix.DataProperties
dataclass
¶
DataProperties(scope: FactorScope, scope_reason: str, density: FactorDensity, density_reason: str, structure: DataStructure, structure_reason: str, n_assets: int, n_periods: int, n_pairs: int, n_events: int, sparse_ratio: float)
Inspected data properties driving cell dispatch.
Carries the dispatch axes (scope / density / structure
as typed enums), the human-readable rationale for each axis decision
(scope_reason / density_reason / structure_reason), and
the data-shape numerics the user typically wants next to them
(n_assets / n_periods / n_pairs / sparse_ratio).
Named Properties rather than Axes because the numeric fields
are not axes — they are observations supporting the axis decisions.
Each *_reason sits next to the enum it explains so detection
verdict and rationale travel together as one value.
Attributes:
| Name | Type | Description |
|---|---|---|
scope |
FactorScope
|
Detected :class: |
scope_reason |
str
|
Human-readable rationale for |
density |
FactorDensity
|
Detected :class: |
density_reason |
str
|
Human-readable rationale for |
structure |
DataStructure
|
Detected :class: |
structure_reason |
str
|
Human-readable rationale for |
n_assets |
int
|
Unique |
n_periods |
int
|
Unique |
n_pairs |
int
|
Non-null |
n_events |
int
|
Non-zero |
sparse_ratio |
float
|
Zero-ratio in the |
factrix.MetricApplicabilityGroup ¶
Bases: list['MetricApplicability']
A tier partition of :class:MetricApplicability verdicts.
A list subclass — every list operation works — with discovery
helpers layered on. Returned by :attr:DataInspection.usable /
degraded / unusable.
to_metrics_dict ¶
Normalise the group into {name: metric_instance} for evaluate.
The canonical discovery bridge: pick a tier (usually usable) and
feed its default-constructed instances straight to
:func:factrix.evaluate::
info = fx.inspect_data(data)
results = fx.evaluate(data, metrics=info.usable.to_metrics_dict(),
factor_cols=[...], forward_periods=5)
Scalar-input utilities are kept out of usable and therefore out
of this bridge: compute their upstream values first, then call the
helper directly.
factrix.MetricApplicability
dataclass
¶
MetricApplicability(metric: type[MetricBase], name: str, spec: MetricSpec, usable: bool, warnings: list[Warning] = list(), blockers: list[str] = list())
Per-metric pre-flight verdict against one data's properties.
Attributes:
| Name | Type | Description |
|---|---|---|
metric |
type[MetricBase]
|
The :class: |
name |
str
|
The metric's registry name ( |
spec |
MetricSpec
|
The :class: |
usable |
bool
|
|
warnings |
list[Warning]
|
|
blockers |
list[str]
|
Concrete reasons the metric is unusable
(cell mismatch, |