Skip to content

490 bug index mismatch in the plotting of fns tof#501

Merged
dodu94 merged 5 commits into
developingfrom
490-bug---index-mismatch-in-the-plotting-of-fns-tof
May 19, 2026
Merged

490 bug index mismatch in the plotting of fns tof#501
dodu94 merged 5 commits into
developingfrom
490-bug---index-mismatch-in-the-plotting-of-fns-tof

Conversation

@dodu94
Copy link
Copy Markdown
Member

@dodu94 dodu94 commented Mar 24, 2026

fix #490 together with IAEA-NDS/open-benchmarks#19

The C/E plot now can accept missing subcases from one of the libraries. The missing subcase will not be plotted and a warning will be printed out.

Summary by CodeRabbit

  • Bug Fixes

    • Plot generation now tolerates mismatched data indices when subcases are enabled by automatically filtering missing subcases instead of failing.
    • When mismatches are not resolvable, plotting now raises a specific index-mismatch error with clearer messaging.
  • Tests

    • Added tests for missing-subcase handling and for the new index-mismatch error when data ranges do not overlap.

Review Change Stack

@dodu94 dodu94 linked an issue Mar 24, 2026 that may be closed by this pull request
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 08bae0d3-ebcf-438d-896c-d6319d7745ad

📥 Commits

Reviewing files that changed from the base of the PR and between 5e63b17 and 0f1921a.

📒 Files selected for processing (1)
  • src/jade/post/plotter.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/jade/post/plotter.py

Walkthrough

A new PlotIndexMismatchError exception is added and CEPlot._get_figure is modified to detect index mismatches: when subcases is enabled it attempts to compute and drop missing subcases to align indices; otherwise (or if unresolved) it raises PlotIndexMismatchError.

Changes

Error Handling

Layer / File(s) Summary
PlotIndexMismatchError addition
src/jade/helper/errors.py
Added PlotIndexMismatchError with __init__(self, index1, index2, codelib) that formats a message describing mismatched dataframe indices.
Index mismatch logic
src/jade/post/plotter.py
Imported PlotIndexMismatchError. In CEPlot._get_figure replaced generic RuntimeError on index mismatch with conditional logic: compute missing_subcases, filter out missing subcases when subcases enabled, reindex val2/err2 to val1/err1, and raise PlotIndexMismatchError when mismatch cannot be resolved or subcases disabled.
Tests
tests/post/test_plotter.py
Added tests: test_missing_subcase verifies plotting proceeds when a library omits a subcase result (output rows reduced to matching indices); test_trigger_index_match_error asserts PlotIndexMismatchError is raised for non-overlapping indices.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 I nibbled at indices, found one gone astray,
I stitched the subcases so plots could play,
If gaps remain and cannot be paired,
I raise my flag—an error declared,
Hooray for tidy plots at the end of the day!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title references issue #490 and the specific bug (index mismatch in FNS-TOF plotting), accurately representing the primary change.
Linked Issues check ✅ Passed The PR addresses the core requirement from issue #490 by implementing missing subcase handling in plotting when subcases are enabled, filtering data to skip missing subcases with warnings.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the index mismatch bug: new exception class, enhanced mismatch handling in plotter, and corresponding tests for both missing subcase and unresolvable mismatch scenarios.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 490-bug---index-mismatch-in-the-plotting-of-fns-tof

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@dodu94 dodu94 requested a review from alexvalentine94 March 24, 2026 16:37
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/jade/helper/errors.py (1)

19-31: Consider storing exception attributes for programmatic access.

The exception class correctly builds an informative error message. However, unlike the existing pattern where self.message is stored, the raw index1, index2, and codelib values are not retained as instance attributes. This could be useful if callers want to programmatically inspect the mismatched indices (e.g., for logging or recovery logic).

💡 Optional: Store attributes for programmatic access
     def __init__(
         self,
         index1,
         index2,
         codelib,
     ):
+        self.index1 = index1
+        self.index2 = index2
+        self.codelib = codelib
         self.message = (
             f"Indices do not match between reference and {codelib}: {index1}, {index2}"
         )
         super().__init__(self.message)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/jade/helper/errors.py` around lines 19 - 31, PlotIndexMismatchError
builds a message but does not retain the raw values; modify the __init__ of
PlotIndexMismatchError to assign self.index1 = index1, self.index2 = index2, and
self.codelib = codelib (in addition to keeping self.message and calling
super().__init__(self.message)) so callers can programmatically access the
mismatched indices and source.
src/jade/post/plotter.py (1)

579-580: Clarify: Index assignment happens unconditionally.

These lines execute regardless of whether same_index returned True or False. While this handles numerical tolerance issues (which is the intended behavior per the comment on lines 546-548), it might be clearer to add a brief inline comment explaining this is intentional for handling floating-point rounding in index values.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/jade/post/plotter.py` around lines 579 - 580, The unconditional
assignments to val2.index = val1.index and err2.index = err1.index should be
explicitly documented: add a brief inline comment next to these lines (where
same_index is used) stating that the assignment is intentional even when
same_index returns False to normalize minor floating-point/index rounding
differences and ensure consistent indexing for downstream comparisons/plotting;
reference the same_index check and these four symbols (val1.index, val2.index,
err1.index, err2.index) so future readers understand this tolerance-based
normalization is deliberate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/jade/post/plotter.py`:
- Around line 562-573: The bug is that val1 and err1 (the reference series) are
reassigned inside the loop over self.data[1:], causing subsequent library
comparisons to use an already-filtered reference; fix this by creating local
copies (e.g., v1 = val1.copy(); e1 = err1.copy()) before applying the
missing_subcases filtering and use v1/e1 for the per-library filters (leaving
the original val1/err1 untouched) when computing val2/err2 comparisons inside
the loop that iterates self.data[1:].
- Around line 549-577: The loop inside _get_figure mutates val1/err1 in-place
when removing missing subcases, which causes earlier modifications to leak into
subsequent library comparisons; fix by making per-iteration copies of the
reference data (e.g., assign local_temp_val1 = val1.copy() and local_temp_err1 =
err1.copy() or otherwise clone the DataFrame/Series) and perform filtering on
those locals before comparing to val2/err2, ensuring val1/err1 remain unchanged
for the next iteration; also add the suggested 3-library test (lib0: a,b,c;
lib1: a,c; lib2: a,b) to validate that different missing subcases are handled
independently across iterations.

---

Nitpick comments:
In `@src/jade/helper/errors.py`:
- Around line 19-31: PlotIndexMismatchError builds a message but does not retain
the raw values; modify the __init__ of PlotIndexMismatchError to assign
self.index1 = index1, self.index2 = index2, and self.codelib = codelib (in
addition to keeping self.message and calling super().__init__(self.message)) so
callers can programmatically access the mismatched indices and source.

In `@src/jade/post/plotter.py`:
- Around line 579-580: The unconditional assignments to val2.index = val1.index
and err2.index = err1.index should be explicitly documented: add a brief inline
comment next to these lines (where same_index is used) stating that the
assignment is intentional even when same_index returns False to normalize minor
floating-point/index rounding differences and ensure consistent indexing for
downstream comparisons/plotting; reference the same_index check and these four
symbols (val1.index, val2.index, err1.index, err2.index) so future readers
understand this tolerance-based normalization is deliberate.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a07099da-e1a4-4f90-98ac-734986bac859

📥 Commits

Reviewing files that changed from the base of the PR and between a581978 and 2774f92.

📒 Files selected for processing (3)
  • src/jade/helper/errors.py
  • src/jade/post/plotter.py
  • tests/post/test_plotter.py

Comment thread src/jade/post/plotter.py
Comment thread src/jade/post/plotter.py
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 24, 2026

Codecov Report

❌ Patch coverage is 94.11765% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/jade/post/plotter.py 92.30% 1 Missing ⚠️
Files with missing lines Coverage Δ
src/jade/helper/errors.py 83.33% <100.00%> (+8.33%) ⬆️
src/jade/post/plotter.py 94.11% <92.30%> (+0.26%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
tests/post/test_plotter.py (2)

170-174: Also assert the warning side-effect in test_missing_subcase.

At Line 170-174, the test validates filtered output size, but not the warning message that this PR explicitly promises. Please capture logs (e.g., caplog) and assert the warning text appears.

💡 Suggested test hardening
-    def test_missing_subcase(self, tmpdir):
+    def test_missing_subcase(self, tmpdir, caplog):
@@
-        plot = CEPlot(cfg, data)
-        output = plot.plot()
+        plot = CEPlot(cfg, data)
+        with caplog.at_level("WARNING"):
+            output = plot.plot()
         # check only two rows in plot
         assert len(output[0][1]) == 2
+        assert "will be removed from the plot" in caplog.text
         output[0][0].savefig(tmpdir.join("test.png"))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/post/test_plotter.py` around lines 170 - 174, The test_missing_subcase
currently only asserts filtered output size but not the promised warning; modify
the test to capture logs (use caplog fixture) around creating and calling
CEPlot(cfg, data) and assert that the expected warning message is present in
caplog.records or caplog.text after calling plot.plot(); locate the assertions
around CEPlot, plot.plot, and tmpdir in test_missing_subcase to add the caplog
usage and the assertion that the specific warning string appears.

151-157: Optional: align fixture direction with CEPlot reference semantics.

At Line 151-157, you drop subcase "b" from i == 1. If this test is meant to mirror production data conventions, consider dropping from the reference dataset instead (or rename libs to make intent explicit).

🔧 Possible alignment tweak
-                if result == "b" and i == 1:
+                if result == "b" and i == 0:
                     continue
Based on learnings: In `src/jade/post/plotter.py` `CEPlot._get_figure`, `val1`/`err1` are experimental reference data and subcase absence is expected there.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/post/test_plotter.py` around lines 151 - 157, The test currently skips
subcase "b" by checking the library index (for i in range(n_libs) ... if result
== "b" and i == 1: continue); instead, align with CEPlot reference semantics by
removing the subcase from the reference dataset (the experimental/reference side
used to populate val1/err1 in CEPlot._get_figure) rather than from a specific
lib index, or alternatively rename the lib fixtures to make the intention
explicit; update the loop to conditionally skip "b" when iterating over the
reference/results source used as the expected experimental data (cfg.reference
or whichever fixture supplies val1/err1) so the missing subcase reflects
reference-only absence, not a particular lib index.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/post/test_plotter.py`:
- Around line 170-174: The test_missing_subcase currently only asserts filtered
output size but not the promised warning; modify the test to capture logs (use
caplog fixture) around creating and calling CEPlot(cfg, data) and assert that
the expected warning message is present in caplog.records or caplog.text after
calling plot.plot(); locate the assertions around CEPlot, plot.plot, and tmpdir
in test_missing_subcase to add the caplog usage and the assertion that the
specific warning string appears.
- Around line 151-157: The test currently skips subcase "b" by checking the
library index (for i in range(n_libs) ... if result == "b" and i == 1:
continue); instead, align with CEPlot reference semantics by removing the
subcase from the reference dataset (the experimental/reference side used to
populate val1/err1 in CEPlot._get_figure) rather than from a specific lib index,
or alternatively rename the lib fixtures to make the intention explicit; update
the loop to conditionally skip "b" when iterating over the reference/results
source used as the expected experimental data (cfg.reference or whichever
fixture supplies val1/err1) so the missing subcase reflects reference-only
absence, not a particular lib index.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 80bebc8c-5b54-4278-9606-1dbe5f5b6ae7

📥 Commits

Reviewing files that changed from the base of the PR and between 2774f92 and 5e63b17.

📒 Files selected for processing (1)
  • tests/post/test_plotter.py

@dodu94 dodu94 merged commit 98b3667 into developing May 19, 2026
13 checks passed
@dodu94 dodu94 deleted the 490-bug---index-mismatch-in-the-plotting-of-fns-tof branch May 19, 2026 15:53
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.

[BUG] - index mismatch in the plotting of FNS-TOF

2 participants