Skip to content

fix(forecasting): resolve regressor source collisions deterministically#2354

Open
Flix6x wants to merge 1 commit into
feat/forecast-source-filteringfrom
fix/forecast-source-precedence
Open

fix(forecasting): resolve regressor source collisions deterministically#2354
Flix6x wants to merge 1 commit into
feat/forecast-source-filteringfrom
fix/forecast-source-precedence

Conversation

@Flix6x

@Flix6x Flix6x commented Jul 23, 2026

Copy link
Copy Markdown
Member

Description

Follow-up to #2347, addressing the source-collision question raised in this comment thread: when several selected sources record a belief about the same event at the same belief time, the pipeline kept whichever row it happened to see first (idxmax returns the first occurrence of the max belief time), so forecasts depended on row order.

This PR makes the resolution deterministic:

  • Explicit sources list order decides precedence — the first listed source wins on collisions, giving sources: [1212, 868] the natural reading "prefer 1212, fall back to 868" (the fallback part already works via the outer join for events the preferred source doesn't cover).
  • Without an explicit list, the source ranked highest by the existing source_priorities helper wins (latest source version, then highest ID) — the same rule the platform uses elsewhere.
  • Deduplication happens right after search_beliefs, while the source column is still available. This also fixes a subtle correctness issue: duplicated (event_start, belief_time) keys used to multiply rows through the chained outer join over regressors in load_data_all_beliefs.
  • Documented the precedence rule in the sources field description (schema + OpenAPI spec) and added a changelog entry.
  • Added pipeline tests covering both precedence rules (including that reversing the list reverses the winner).

No warning is logged on collisions. Since the rule is now deterministic and documented, a warning adds little — and for API-created jobs we have no good channel to surface it, so it would only add log volume on hosts.

@BelhsanHmida please review — and if you approve, feel free to merge this into your branch so it lands as part of #2347.

How to test

uv run pytest -q flexmeasures/data/tests/test_forecasting_pipeline.py -k collision

Full test_forecasting_pipeline.py + data/schemas/tests/test_forecasting.py pass locally (83 passed).

Related Items

Follow-up to #2347. Note for the remaining canonicalization item listed under Further Improvements there: with this change the order of sources is semantically significant, so it should not be sorted when generating forecast data-source identities (the other filter lists are still fair game).


Sign-off

  • I agree to contribute to the project under Apache 2 License.
  • To the best of my knowledge, the proposed patch is not based on code under GPL or another license incompatible with FlexMeasures.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WF4PYUDxbBQyPf37PAUKBC

When several selected sources record a belief about the same event at the
same belief time, the pipeline used to keep whichever row it happened to
see first, making forecasts dependent on row order. Now the collision is
resolved deterministically: the order of an explicit sources list decides
precedence (first listed wins), and otherwise the source ranked highest
by source_priorities wins (latest version, then highest ID).

Deduplicating right after loading also prevents duplicated
(event_start, belief_time) keys from multiplying rows through the outer
join over regressors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WF4PYUDxbBQyPf37PAUKBC
Signed-off-by: F.N. Claessen <felix@seita.nl>
@Flix6x
Flix6x requested a review from BelhsanHmida July 23, 2026 22:12
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.

1 participant