Skip to content

Feature/poi support - #79

Draft
adefabian wants to merge 18 commits into
mainfrom
feature/poi_support
Draft

Feature/poi support#79
adefabian wants to merge 18 commits into
mainfrom
feature/poi_support

Conversation

@adefabian

Copy link
Copy Markdown
Collaborator

Summary

Adds Points-in-Time (POI) series as a first-class silver-layer channel type:
a value defined only at its timestamp (no between-point validity), backed by
PointsInTimeSeries, sitting alongside the existing interval-valued SampleSeries.
The motivating case is ECU Diagnostic Trouble Codes (DTCs) — string-valued fault
events analyzed together with continuous signals ("RPM at the instant DTC == P0301").

Changes

  • Storage: new poi_channels silver table (POI_CHANNELS_SCHEMA); series type is
    determined by table membership (channels ⇒ SAMPLE, poi_channels ⇒ POI) — no
    series_type column needed.
  • Model: PointsInTimeSeries gains string-value support — == / != and sampling
    for strings; arithmetic/ordering/reductions raise for strings via a @_numeric_only
    guard; value-type-aware dtype().
  • Query API: QueryBuilder.poi_channel(dtype=...) (accepts the enum or the plain
    string "double"/"string"); the selector carries series_type + value_type and
    is the plan-time source of truth for series-type dispatch.
  • Solve stage: _prepare_channels_join unions poi_channels after RLE encoding
    (zero-duration points aren't merged); TimeSeriesCache.load_blob builds the right
    series from the selector; a solve-time assertion rejects a declared-vs-actual mismatch.
  • Config/DB: poi_channels_uri wired through MeasurementDBConfig,
    MeasurementDB.poi_channels(), and the reporting Source config.
  • Tests: POI integration suite (freeze-frame, string equality + op gating,
    mix-and-match, declared-vs-actual, backward-compat), PointsInTimeSeries string
    units, poi_channel(dtype=...) coercion units, and a config-passthrough regression.
  • Demo: reporting_pipeline.ipynb gains a DTC section — freeze-frame (RPM at each
    P0301 misfire), per-recording fault counts, and a ±10 s window histogram around faults.
  • Docs: API reference regenerated; make update-api-docs target added.

Test Plan

  • Unit tests added/updated
  • Manual testing completed
  • Documentation updated (if applicable)

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • No new linter warnings introduced

@adefabian
adefabian force-pushed the feature/poi_support branch from 7b92d30 to 328c266 Compare August 13, 2026 13:21

---

## calculated_channels (optional)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we deleting the documentation of calculated channels? Please keep it :)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to modify this file

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to modify this file

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it seems that your coding agent deleted everything related to calculated channels. I would like to keep the calculated channels example in the demo notebook. Is there a specific reason why this got deleted?

def __init__(expr,
uses_alias: bool = False,
series_type: SeriesType = SeriesType.SAMPLE,
value_type: PoiValueType = PoiValueType.DOUBLE)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would generalize the value type, maybe we will support in the future also SampleSeries of string type. Therefore, rather than naming the class PoiValueType, lets name it SeriesValueType

Comment on lines +184 to +189
if pd.notna(s[self._te_col].iloc[0]):
raise ValueError(
"POI channel series-type mismatch: poi_channel(...) resolved to a SAMPLE "
"channel (its rows carry a validity interval). Use channel(...) for SAMPLE "
"channels and poi_channel(...) for POINTS_IN_TIME channels."
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumption is too strong and I would remove this check (I thought already of having POI channels in the normal channels table with tstart == tend, which would then raise a ValueError here).

values = values * factor
return SampleSeries(s[self._ts_col], s[self._te_col], values)

def _assert_poi_data(self, s, value_type) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets move this function into PointsInTimeSeries class and call it from the constructor of POISeries.

F.col(cfg.poi_timestamp_col).alias(cfg.tstart_col),
F.lit(None).cast(T.LongType()).alias(cfg.tend_col),
F.col(cfg.poi_value_double_col).alias(cfg.value_col),
F.col(cfg.poi_value_string_col).alias(cfg.poi_value_string_col),

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the alias is not req.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants