climate_ref.results
#
Data access layer for REF results.
This package is the single source of truth for how result data is filtered and queried.
It serves notebooks / local users (via pandas-friendly, detached value objects) and,
in future, the ref-app API (which can reuse the shared Select builders directly).
Layers:
- _query --
MetricValueFilter+select_*builders (return aSelect; the source of truth for filter/join logic) +count_values+latest_execution_for_group. - frames --
*_to_frame+collect_facets. - outliers -- source-id-aware IQR outlier detection.
- values -- typed DTOs + collections + the
Readerfacade. - executions -- execution-group / execution DTOs + collection +
the
ExecutionsReaderfacade. - datasets -- dataset DTOs + collection + the
DatasetsReaderfacade, querying the polymorphicDatasethierarchy directly. - diagnostics -- diagnostic DTOs + collection + the
DiagnosticsReaderfacade, queryingDiagnostic -> Providerdirectly. - artifacts -- the
ArtifactsReaderfacade, resolving execution output fragments into filesystem paths under a results root.
The typical notebook entry point::
from climate_ref.config import Config
from climate_ref.database import Database
from climate_ref.results import Reader
with Database.from_config(Config.default(), read_only=True) as db:
df = Reader(db).values.scalar_values().to_pandas()
Public surface convention
The top level exports only what a caller names to make a call, so the namespace stays small as domains are added:
- the
Readerentry point, - filter objects you construct and pass in (
MetricValueFilter,ExecutionGroupFilter,DatasetFilter,DiagnosticFilter), - value objects you pass in (
OutlierPolicy).
Everything the package returns -- DTOs, collections, views -- and the sub-reader classes reached
via reader.values etc. live in their domain submodule (climate_ref.results.values, ...).
Import them from there on the rare occasion you need to name one, e.g.
from climate_ref.results.values import ScalarValue.
The Select builders and other plumbing stay in climate_ref.results._query
and are not part of the public surface.
DatasetFilter
#
Declarative filter over datasets.
source_type is required.
It selects which which facet columns the query can target.
This limits our filtering to a single source type at a time to ensure that the files can be
collapsed into a dataframe.
Every other field is optional with None meaning "do not constrain on this axis".
Source code in packages/climate-ref/src/climate_ref/models/dataset_query.py
DiagnosticFilter
#
Declarative filter over diagnostics.
Every field is optional; None means "do not constrain on this axis".
diagnostic_contains/provider_contains are case-insensitive substring matches
(OR-combined within each field), matching the semantics used by
ExecutionGroupFilter.
Source code in packages/climate-ref/src/climate_ref/results/diagnostics.py
diagnostic_contains = attrs.field(default=None, converter=_as_str_tuple)
class-attribute
instance-attribute
#
Case-insensitive substring matches on diagnostic slug (OR-combined).
provider_contains = attrs.field(default=None, converter=_as_str_tuple)
class-attribute
instance-attribute
#
Case-insensitive substring matches on provider slug (OR-combined).
ExecutionGroupFilter
#
Declarative filter over execution groups.
Every field is optional; None means "do not constrain on this axis".
This mirrors exactly what get_execution_group_and_latest_filtered supports --
diagnostic_contains/provider_contains are case-insensitive substring matches (OR-combined),
facets is the selector-facet map consumed by the helper's Python-side matching,
and successful vs latest_successful expose the helper's post-rank / pre-rank success filters.
Exact-match diagnostic_slug/provider_slug are a documented follow-up,
as the underlying helper only does substring matching today,
so adding exact match means extending the helper first.
Source code in packages/climate-ref/src/climate_ref/results/executions.py
diagnostic_contains = attrs.field(default=None, converter=_as_str_tuple)
class-attribute
instance-attribute
#
Case-insensitive substring matches on diagnostic slug (OR-combined).
dirty = None
class-attribute
instance-attribute
#
Constrain on the group's dirty flag.
facets = attrs.field(default=None, converter=_as_facets)
class-attribute
instance-attribute
#
Selector-facet map matched against each group's selectors.
include_superseded = False
class-attribute
instance-attribute
#
Include execution groups whose diagnostic_version is not the diagnostic's promoted version.
latest_successful = None
class-attribute
instance-attribute
#
Pre-rank population filter: change which execution is chosen as "latest" before ranking.
True ranks only over successful executions,
so a group's latest becomes its most recent successful run
(surfacing an earlier success even when a later run failed).
False ranks only over unsuccessful / in-progress runs.
None (default) ranks over all executions.
Composes with successful but answers a different question.
provider_contains = attrs.field(default=None, converter=_as_str_tuple)
class-attribute
instance-attribute
#
Case-insensitive substring matches on provider slug (OR-combined).
successful = None
class-attribute
instance-attribute
#
Post-rank filter on the winning execution: keep a group only if its latest execution matches.
True keeps groups whose latest execution succeeded.
False keeps groups whose latest execution failed, is in progress, or does not exist yet.
This does not change which execution is considered latest -- contrast latest_successful.
MetricValueFilter
#
Declarative filter over metric values.
Every field is optional; None/empty means "do not constrain on this axis". The same
object drives scalar and series queries, frame conversion and facet collection, so a filter
is written once and reused across output shapes.
Two styles of diagnostic/provider filtering are offered deliberately:
diagnostic_slug/provider_slugare exact matches, for API path-scoped queries (/diagnostics/{provider_slug}/{diagnostic_slug}/values).diagnostic_contains/provider_containsare case-insensitive substring matches (OR-combined), for CLI-style search.
Keeping them separate avoids the Diagnostic.slug vs Diagnostic.name divergence that
exists today between the CLI and the ref-app API.
Source code in packages/climate-ref/src/climate_ref/results/_query.py
diagnostic_contains = attrs.field(default=None, converter=_as_str_tuple)
class-attribute
instance-attribute
#
Case-insensitive substring matches on diagnostic slug (OR-combined), for CLI-style search.
diagnostic_slug = None
class-attribute
instance-attribute
#
Exact-match diagnostic slug, for API path-scoped queries.
dimensions = None
class-attribute
instance-attribute
#
CV dimension filters keyed by registered dimension name; a string is equality, a sequence is IN.
exclude_ids = None
class-attribute
instance-attribute
#
Exclude these value ids; ignored when isolate_ids is set.
execution_group_ids = None
class-attribute
instance-attribute
#
Restrict to values produced by executions belonging to these groups.
execution_ids = None
class-attribute
instance-attribute
#
Restrict to values produced by these executions.
include_retracted = False
class-attribute
instance-attribute
#
Include values produced by retracted executions.
isolate_ids = None
class-attribute
instance-attribute
#
Restrict to exactly these value ids; takes precedence over exclude_ids, matching the API.
promoted_only = True
class-attribute
instance-attribute
#
Restrict to execution groups at the diagnostic's currently promoted version.
provider_contains = attrs.field(default=None, converter=_as_str_tuple)
class-attribute
instance-attribute
#
Case-insensitive substring matches on provider slug (OR-combined), for CLI-style search.
provider_slug = None
class-attribute
instance-attribute
#
Exact-match provider slug, for API path-scoped queries.
reference_only = None
class-attribute
instance-attribute
#
Series-only: True for observation/reference series, False for model series.
dimension_clauses(entity)
#
Build validated SQLAlchemy clauses for the dynamic CV dimension columns.
Raises:
| Type | Description |
|---|---|
KeyError
|
If a key is not a registered CV dimension on |
Source code in packages/climate-ref/src/climate_ref/results/_query.py
OutlierPolicy
#
Configuration for scalar outlier detection.
The defaults reproduce the behaviour users currently see through the ref-app API
(factor=10.0, source-id-aware IQR grouped by ("statistic", "metric")).
Source code in packages/climate-ref/src/climate_ref/results/outliers.py
enabled
property
#
Whether detection should run.
factor = 10.0
class-attribute
instance-attribute
#
Multiplier on the IQR to set the outlier bounds (Q1 - factor*IQR, Q3 + factor*IQR).
group_by = ('statistic', 'metric')
class-attribute
instance-attribute
#
CV dimensions to group by before computing bounds. Missing dimensions are ignored.
method = attrs.field(default='iqr', validator=(attrs.validators.in_(_SUPPORTED_METHODS)))
class-attribute
instance-attribute
#
Detection method. "off" disables detection; "iqr" enables it.
min_n = attrs.field(default=4, validator=(attrs.validators.ge(2)))
class-attribute
instance-attribute
#
Minimum sample size required to run detection.
On the source-id-aware path this counts distinct non-reference source_id with a finite mean.
On the fallback path it counts finite values.
Non-finite values (NaN/inf) are excluded from the count
and are flagged unconditionally regardless of whether detection runs.
Reader
#
Typed entry point to REF query results.
Constructed from a Database, which owns the session and the
read-only story. This is a thin entry point: it exposes per-domain sub-readers as properties,
values for metric-value reads,
executions for execution-group reads,
datasets for dataset reads,
diagnostics for diagnostic reads, and
artifacts for output path resolution
(only available when a results root is supplied).
Source code in packages/climate-ref/src/climate_ref/results/values.py
artifacts
cached
property
#
Output path resolution.
Raises ValueError when no results root was supplied to the constructor.
datasets
cached
property
#
Dataset reads.
diagnostics
cached
property
#
Diagnostic reads.
executions
cached
property
#
Execution-group and execution reads.
session
property
#
The underlying database session.
values
cached
property
#
Metric-value reads (scalar/series/facets).
sub-packages#
| Sub-package | Description |
|---|---|
| _converters | Shared attrs field converters for the results filter DTOs. |
| _query | Filter and Select builders for metric-value queries. |
| _stats | Shared execution-statistics mapping for the results read layer. |
| artifacts | Path resolution for execution output artifacts. |
| datasets | Typed, detached read surface for datasets. |
| diagnostics | Typed, detached read surface for diagnostic metadata. |
| executions | Typed, ORM-free surface for execution-group and execution results. |
| frames | DataFrame conversion and facet collection for metric values. |
| outliers | Outlier detection for scalar metric values. |
| values | Typed, ORM-free surface for metric-value results. |