Skip to content

Feature/poi support - #79

Open
adefabian wants to merge 16 commits into
mainfrom
feature/poi_support
Open

Feature/poi support#79
adefabian wants to merge 16 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 requested a review from tombonfert August 13, 2026 13:09
@adefabian
adefabian force-pushed the feature/poi_support branch 2 times, most recently 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.

@adefabian
adefabian force-pushed the feature/poi_support branch from 59d09ca to a4fd1d6 Compare August 17, 2026 05:59
Moved POI data check to PointsInTimeSeries
Added missing csv for testing
Removed dtype column from csvs
@codecov

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.24324% with 10 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.06%. Comparing base (c4ac5fa) to head (cafff8a).

Files with missing lines Patch % Lines
...ery_engine/analyze/query/solvers/default_solver.py 79.16% 3 Missing and 2 partials ⚠️
..._engine/analyze/metadata/time_series_expression.py 94.28% 1 Missing and 1 partial ⚠️
...mpulse_query_engine/analyze/query/query_builder.py 75.00% 1 Missing and 1 partial ⚠️
...query_engine/model/series/points_in_time_series.py 98.30% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #79      +/-   ##
==========================================
+ Coverage   88.89%   89.06%   +0.17%     
==========================================
  Files          61       61              
  Lines        5194     5330     +136     
  Branches      625      647      +22     
==========================================
+ Hits         4617     4747     +130     
- Misses        466      468       +2     
- Partials      111      115       +4     
Flag Coverage Δ
query_engine 85.06% <93.19%> (+0.49%) ⬆️
reporting 94.23% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
..._query_engine/analyze/query/solvers/blob_solver.py 49.09% <100.00%> (ø)
..._query_engine/analyze/query/solvers/empty_cache.py 88.88% <100.00%> (ø)
...query_engine/analyze/query/solvers/series_cache.py 80.00% <100.00%> (ø)
...uery_engine/analyze/query/solvers/solver_config.py 100.00% <100.00%> (ø)
src/impulse_query_engine/measurement_db.py 79.26% <100.00%> (+3.26%) ⬆️
src/impulse_query_engine/schema.py 100.00% <100.00%> (ø)
src/impulse_reporting/config/config_parser.py 97.19% <100.00%> (+0.01%) ⬆️
...query_engine/model/series/points_in_time_series.py 93.48% <98.30%> (+2.34%) ⬆️
..._engine/analyze/metadata/time_series_expression.py 79.25% <94.28%> (+1.79%) ⬆️
...mpulse_query_engine/analyze/query/query_builder.py 86.08% <75.00%> (-0.83%) ⬇️
... and 1 more
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@adefabian
adefabian marked this pull request as ready for review August 17, 2026 12:47
@adefabian
adefabian requested a review from a team as a code owner August 17, 2026 12:47
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