impulse_reporting.channels.calculated_channel
CalculatedChannel
class CalculatedChannel()
A reporting-layer calculated (derived) channel.
Orchestration counterpart to a query-engine CalculatedChannel: it wraps a
:class:TimeSeriesExpression built from the operator DSL (e.g.
q.channel(channel_name="raw_speed") * 3.6) plus an identity dict, and
is driven by :class:Report to compute the channel across containers, persist
the narrow result to a gold fact table, and update it incrementally.
Structurally parallels :class:BasicEvent (holds an aliased expression,
name-derived id, SHA-256 definition hash) but — like ContainerEvent — it
drives its own solve via QueryBuilder.solve_calculated_channels rather than
riding the centralized wide solved_df. Accordingly :meth:get_expression
returns None so it is excluded from the batch solve.
Arguments:
name(str): Name of the calculated channel (used as the entity id seed's fallback and stored on the dimension row).expr(TimeSeriesExpression): The wrapped expression; must evaluate to aSampleSeries.identity(Mapping[str, str]): Channel identity. Any non-empty set of keys; seeds the deterministicchannel_idand is stored once oncalculated_channel_dimensionas aMapType(string, string)column (joined to the fact viachannel_id, not repeated on fact rows).desc(str): Human-readable description (stored on the dimension row, excluded from the definition hash).attributes(Mapping[str, str]): Key-value metadata stored on the dimension row.
canonical_identity
def canonical_identity() -> str
Public, order-independent identity key.
Two channels with the same identity (regardless of key insertion
order) share this value and therefore the same channel_id. Used by
get_name
def get_name() -> str
Return the channel name.
set_report_id
def set_report_id(report_id: int)
Set the owning report id.
get_id
def get_id() -> int
Return the deterministic entity id (also the fact/dimension channel_id).
get_expression
def get_expression() -> TimeSeriesExpression | None
Return None — calculated channels drive their own narrow solve.
Returning None keeps this channel out of the centralized wide batch
solve (collect_solvable_expressions), mirroring ContainerEvent.
get_expression_str
def get_expression_str() -> str
String form of the wrapped expression (identity + expr, no name/desc).
get_channel_type_str
def get_channel_type_str() -> str
Channel type string, matching the ChannelType enum member name.
determine_definition_hash
def determine_definition_hash() -> int
Hash of the computation-affecting definition (expression + identity).
as_dict
def as_dict() -> dict
Dictionary representation of the dimension metadata.
identity is a plain dict, persisted on the dimension as a
MapType(string, string) column (no fixed per-key columns).
as_spark_row
def as_spark_row() -> Row
Spark Row representation of the dimension metadata.
determine_calculated_channels
def determine_calculated_channels(
cls,
spark: SparkSession,
channels: list[CalculatedChannel],
*,
query: QueryBuilder = None,
solver: QuerySolver = None,
pre_filtered_containers_df: DataFrame = None) -> DataFrame | None
Solve the given channels and shape the result into fact rows.
Drives QueryBuilder.solve_calculated_channels (the narrow, many-rows-
per-container endpoint) with the report's query + solver, then
projects to :data:CALCULATED_CHANNEL_FACT_SCHEMA. Because each channel's
channel_id was fixed to its entity id at construction, no id-join is
needed.
Arguments:
spark(SparkSession): Spark session, forwarded toQueryBuilder.solve_calculated_channels.channels(list of CalculatedChannel): Channels to solve; identity keys may differ across channels.query(QueryBuilder): Query builder used to select and solve the channels.solver(QuerySolver): Solver implementingsolve_calculated_channels(aDefaultSolver).pre_filtered_containers_df(DataFrame): Incremental container subset;Noneprocesses all containers.
Returns:
DataFrame or None: Narrow fact DataFrame, or None when there are no channels.
determine_metadata_df
def determine_metadata_df(cls, spark: SparkSession,
channels: list[CalculatedChannel])
Create the dimension DataFrame for the given channels.
identity is a self-describing MapType(string, string) column,
which createDataFrame builds directly from the plain dict returned by