Skip to content

Feature/open mc sphere output#531

Merged
dodu94 merged 12 commits into
JADE-V-V:developingfrom
jude-moo:feature/OpenMCSphereOutput
May 21, 2026
Merged

Feature/open mc sphere output#531
dodu94 merged 12 commits into
JADE-V-V:developingfrom
jude-moo:feature/OpenMCSphereOutput

Conversation

@jude-moo
Copy link
Copy Markdown
Collaborator

@jude-moo jude-moo commented May 20, 2026

This pull request includes various changes with the combined effort to implement additional tallies into the OpenMC Sphere benchmarks.

To make the new tallies comparible to the MCNP results they must be normalised by the atomic density of the material. It would be impractical to implement this in the raw.yaml file for the OpenMC sphere benchmark for ever instance of the Sphere benchmark.
Instead, the atomic densities are being retrieved from the geometry.xml file and being folded into the tally results.

To facilitate this the following changes have been made:

  • I have added the new tallies to the OpenMC Sphere.yaml file
  • Implemented a new class, OpenMCSphereSimOutput, that inherits from OpenMCSimOutput.
    - self.atomic_density is retrieved in innit function
    - Differing logic in create_dataframe function that divides by atomic density
  • Bugfix that prevented any openmc score 'damage-energy' to be converted to MeV as intended
  • Some unit test have been added.

Summary by CodeRabbit

  • New Features

    • Support for OpenMC Sphere simulation outputs with automatic atomic-density normalization for specific tallies
    • Added Sphere benchmark outputs for He ppm, T production, and DPA production
  • Bug Fixes

    • Improved detection of energy-based tallies to ensure correct eV→MeV normalization
  • Tests

    • Added fixtures and tests validating Sphere output processing and atomic-density calculations

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Walkthrough

Adds OpenMC Sphere benchmark support with atomic-density-based normalization for selected tallies, refactors tally preparation into a reusable helper, fixes a heating/damage-energy normalization detection condition, wires a Sphere-specific output class into RawProcessor, and adds config and tests for Sphere outputs.

Changes

OpenMC Sphere Support

Layer / File(s) Summary
Helper normalization condition fix
src/jade/helper/openmc.py
_normalise_df detection for heating/damage-energy tallies switches from expression-based to membership-based check using isin().any().
Tally preparation refactoring
src/jade/post/sim_output.py
Adds _prep_tally to prepare OpenMC tally DataFrames (axis detection, remapping, renaming, sorting, constant-column removal). Updates OpenMCSimOutput._create_dataframes to use the helper and clarifies the class docstring.
OpenMCSphereSimOutput class
src/jade/post/sim_output.py
New OpenMCSphereSimOutput loads Sphere input files to compute total atomic density and overrides _create_dataframes to normalize Value/Error for tally IDs 14, 24, 34 before standard error/value processing.
Integration into processing pipeline
src/jade/post/raw_processor.py
Import OpenMCSphereSimOutput and instantiate it when metadata["benchmark_name"] == "Sphere", otherwise use OpenMCSimOutput.
Configuration and test support
src/jade/resources/default_cfg/benchmarks_pp/raw/openmc/Sphere.yaml, tests/dummy_structure/simulations/..., tests/post/test_sim_output.py
Sphere.yaml adds no-action concat entries for He ppm, T, and DPA tallies (columns 14, 24, 34). Adds geometry/material fixtures and tests/fixture for OpenMCSphereSimOutput, asserting tallydata DataFrames and atomic_density.

Sequence Diagram(s)

sequenceDiagram
  participant RawProcessor
  participant OpenMCSphereSimOutput
  participant SphereInput as Sphere Input
  participant TallyPrep as _prep_tally
  participant TallyDF as Tally DataFrames
  RawProcessor->>OpenMCSphereSimOutput: instantiate(sim_folder)
  OpenMCSphereSimOutput->>SphereInput: load materials.xml
  SphereInput-->>OpenMCSphereSimOutput: atomic_density
  OpenMCSphereSimOutput->>TallyPrep: _prep_tally(tally)
  TallyPrep-->>TallyDF: prepared DataFrame
  OpenMCSphereSimOutput->>TallyDF: normalize Value/Error by atomic_density (IDs 14,24,34)
  OpenMCSphereSimOutput->>TallyDF: normalize Error by Value (if present)
  TallyDF-->>RawProcessor: processed tallies dict
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • dodu94

Poem

🐰 I count atoms in a hollow sphere,
I scale tallies so the numbers are clear.
Prep each column, rename every field,
Tests and configs help the data yield—
Hooray, the rabbit made results appear!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Feature/open mc sphere output' is partially related to the changeset—it refers to OpenMC Sphere output processing, which is a real and significant aspect of the changes, but the phrasing is vague and uses a branch-naming convention rather than describing the main change (implementing atomic density normalization for Sphere tallies). Consider revising the title to be more specific about the main change, such as 'Implement OpenMC Sphere output with atomic density normalization' or 'Add OpenMCSphereSimOutput class for normalized Sphere tallies'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/jade/post/sim_output.py`:
- Around line 374-375: _in _prep_tally, the code unconditionally calls
tally.sort_values(filters) which fails when filters is empty or none of the
filter columns exist; guard the sort by checking that filters is non-empty and
that at least one element of filters exists in tally.columns (e.g., compute
valid_filters = [f for f in filters if f in tally.columns]) and only call
tally.sort_values(valid_filters) when valid_filters is non-empty, otherwise skip
sorting but still call reset_index(drop=True) on the original tally; update
references around sorted_tally, tally, and filters accordingly.
- Around line 473-476: The code currently hard-codes materials[1] to fetch
atomic densities; instead locate the single material dynamically from the dict
returned by get_all_materials() (e.g., take the first value or iterate until one
is found) and call get_nuclide_atom_densities() on that material, then sum its
values to assign self.atomic_density; update the logic around materials,
get_all_materials(), get_nuclide_atom_densities(), and self.atomic_density to
use the first/only material rather than the literal key 1.

In `@tests/post/test_sim_output.py`:
- Around line 58-67: The TestOpenMCSphereSimOutput tests need to be skipped when
OpenMC isn't installed: add a class-level skip guard so the whole
TestOpenMCSphereSimOutput is skipped if the openmc package is unavailable (e.g.,
add import pytest and import importlib.util then decorate the class with
`@pytest.mark.skipif`(importlib.util.find_spec("openmc") is None, reason="OpenMC
not installed"), which will skip test_openmc_sphere_tallydata and
test_atomic_density (and avoid running fixtures like openmc_sphere_sim_output)
in CI environments without OpenMC.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b5c6cf94-268c-4502-b8c1-28ac57cf7d32

📥 Commits

Reviewing files that changed from the base of the PR and between 314efef and bf42175.

📒 Files selected for processing (7)
  • src/jade/helper/openmc.py
  • src/jade/post/raw_processor.py
  • src/jade/post/sim_output.py
  • src/jade/resources/default_cfg/benchmarks_pp/raw/openmc/Sphere.yaml
  • tests/dummy_structure/simulations/_openmc_-_FENDL 3.2b_/Sphere/Sphere_m101/geometry.xml
  • tests/dummy_structure/simulations/_openmc_-_FENDL 3.2b_/Sphere/Sphere_m101/materials.xml
  • tests/post/test_sim_output.py

Comment on lines +374 to +375
sorted_tally = tally.sort_values(filters)
sorted_tally = sorted_tally.reset_index(drop=True)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard sorting when no filter columns are present.

_prep_tally sorts by filters unconditionally; if a tally has none of the supported axes, this path raises at runtime and drops processing for that tally.

Proposed fix
-        sorted_tally = tally.sort_values(filters)
-        sorted_tally = sorted_tally.reset_index(drop=True)
+        sorted_tally = tally
+        if filters:
+            sorted_tally = sorted_tally.sort_values(filters)
+        sorted_tally = sorted_tally.reset_index(drop=True)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sorted_tally = tally.sort_values(filters)
sorted_tally = sorted_tally.reset_index(drop=True)
sorted_tally = tally
if filters:
sorted_tally = sorted_tally.sort_values(filters)
sorted_tally = sorted_tally.reset_index(drop=True)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jade/post/sim_output.py` around lines 374 - 375, _in _prep_tally, the
code unconditionally calls tally.sort_values(filters) which fails when filters
is empty or none of the filter columns exist; guard the sort by checking that
filters is non-empty and that at least one element of filters exists in
tally.columns (e.g., compute valid_filters = [f for f in filters if f in
tally.columns]) and only call tally.sort_values(valid_filters) when
valid_filters is non-empty, otherwise skip sorting but still call
reset_index(drop=True) on the original tally; update references around
sorted_tally, tally, and filters accordingly.

Comment thread src/jade/post/sim_output.py
Comment thread tests/post/test_sim_output.py
@codecov
Copy link
Copy Markdown

codecov Bot commented May 20, 2026

Codecov Report

❌ Patch coverage is 91.83673% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/jade/post/sim_output.py 91.11% 4 Missing ⚠️
Files with missing lines Coverage Δ
src/jade/helper/openmc.py 88.51% <ø> (-0.67%) ⬇️
src/jade/post/raw_processor.py 92.30% <100.00%> (+0.24%) ⬆️
src/jade/post/sim_output.py 93.43% <91.11%> (-0.08%) ⬇️

... and 8 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link
Copy Markdown
Member

@dodu94 dodu94 left a comment

Choose a reason for hiding this comment

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

Please add a test in excel post-processor between openmc and mcnp results

Comment thread src/jade/post/sim_output.py Outdated
statepoint_found = True
return statepoint_found

def _prep_tally(self, filter_lookup, tally: pd.DataFrame) -> None:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

correct the typing, filter_lookup is missing and I think the return type is a dataframe

Returns
-------
None.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use super.init() to call the init function of the parent and add after that the extra lines needed for this class specifically

Comment thread src/jade/post/sim_output.py
Comment thread tests/post/test_sim_output.py
@dodu94
Copy link
Copy Markdown
Member

dodu94 commented May 20, 2026

Also: remember to add the new sphere input to the IAEA open benchmark repo

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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/jade/post/sim_output.py (1)

496-554: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Collapse OpenMCSphereSimOutput._create_dataframes onto the parent implementation.

This override duplicates ~95% of OpenMCSimOutput._create_dataframes (filter_lookup, unused columns, the _prep_tally loop, and the Error = Error / Value step). Mathematically the density step cancels in the relative-error conversion:

  • RR path: Value' = V/d, Error' = (E/d) / (V/d) = E/V
  • Parent path: Error' = E/V

So the only net difference for RR tallies is Value /= atomic_density. The whole override can be reduced to a post-processing pass over the parent's output, which also fixes the misleading comment ("Need to generate atomic density for a given Sphere input" — already done in __init__) and the dead else: pass.

Proposed refactor
     def _create_dataframes(
         self, tallies: dict
     ) -> tuple[dict[int, pd.DataFrame], dict[int, pd.DataFrame]]:
         """
         Function to create dataframes in JADE format from OpenMC dataframes.
-
-        Parameters
-        ----------
-        tallies : dict
-            Dictionary of OpenMC tally dataframes, indexed by tally number
-
-        Returns
-        -------
-        tallydata : dict[int, pd.DataFrame]
-            Dictionary of JADE formatted tally dataframes, indexed by tally number
-        totalbin : dict[int, None]]
-            Dictionary of JADE formatted total tally values, each are None for OpenMC
+        Sphere-specific override: normalises Value of the He/T/DPA reaction-rate
+        tallies (IDs 14, 24, 34) by total atomic density. Relative-error
+        conversion is unaffected and is handled by the parent.
         """
-        tallydata = {}
-        totalbin = {}
-        filter_lookup = {
-            "cell": "Cells",
-            "surface": "Segments",
-            "energy high [eV]": "Energy",
-            "time": "Time",
-            "mean": "Value",
-            "std. dev.": "Error",
-        }
-        columns = [ ... ]
-        for id, tally in tallies.items():
-            sorted_tally = self._prep_tally(filter_lookup, tally)
-
-            # If tally is Sphere, and is tally 14,24,34 then need to normalise by atomic density
-            # Need to generate atomic density for a given Sphere input
-            RR_tally_IDs = [14, 24, 34]
-            if id in RR_tally_IDs:
-                sorted_tally["Value"] = sorted_tally["Value"] / self.atomic_density
-                sorted_tally["Error"] = sorted_tally["Error"] / self.atomic_density
-            else:
-                pass
-            
-            if "Value" in sorted_tally.columns and "Error" in sorted_tally.columns:
-                sorted_tally["Error"] = sorted_tally["Error"] / sorted_tally["Value"]
-            
-            tallydata[id] = sorted_tally
-            totalbin[id] = None
-        return tallydata, totalbin
+        tallydata, totalbin = super()._create_dataframes(tallies)
+        # He/T/DPA reaction-rate tallies need normalisation by atomic density
+        # to be comparable to MCNP output.
+        rr_tally_ids = (14, 24, 34)
+        for tally_id in rr_tally_ids:
+            df = tallydata.get(tally_id)
+            if df is not None and "Value" in df.columns:
+                df["Value"] = df["Value"] / self.atomic_density
+        return tallydata, totalbin
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jade/post/sim_output.py` around lines 496 - 554, This override of
OpenMCSphereSimOutput._create_dataframes duplicates almost the entire parent
OpenMCSimOutput._create_dataframes; instead call the parent implementation to
get tallydata and totalbin, then apply the single Sphere-specific mutation: for
RR_tally_IDs = [14, 24, 34] divide tallydata[id]["Value"] by self.atomic_density
(leave errors as produced by the parent), remove the dead else: pass and
duplicated helpers (filter_lookup, columns, _prep_tally usage), and retain
references to self.atomic_density and RR_tally_IDs so the post-processing is
obvious.
🧹 Nitpick comments (1)
src/jade/post/sim_output.py (1)

425-437: ⚡ Quick win

Unused columns list is dead code.

The local columns list defined here is never referenced in the function. Same dead block is duplicated at lines 524-536 in the Sphere override. Either drop it, or wire it back in if it was meant to enforce a column order on the output (in which case it should also include "Cosine"-style ordering after _remove_constant_columns).

Proposed fix
         tallydata = {}
         totalbin = {}
         filter_lookup = { ... }
-        columns = [
-            "Cells",
-            "User",
-            "Segments",
-            "Cosine",
-            "Energy",
-            "Time",
-            "Cor C",
-            "Cor B",
-            "Cor A",
-            "Value",
-            "Error",
-        ]
         for id, tally in tallies.items():
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jade/post/sim_output.py` around lines 425 - 437, The local variable
"columns" in sim_output.py is dead/duplicated and should be removed or re-used:
either delete both occurrences (the one at the top-level function and the
duplicate in the Sphere override) to eliminate dead code, or if you intended to
enforce output column ordering, apply this list after calling
_remove_constant_columns (use it to reorder the resulting columns and include
the "Cosine"-style ordering) and remove the duplicate list in the Sphere
override; update the function(s) that build the output table to use that
ordering rather than leaving the list unused.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/jade/post/sim_output.py`:
- Around line 496-554: This override of OpenMCSphereSimOutput._create_dataframes
duplicates almost the entire parent OpenMCSimOutput._create_dataframes; instead
call the parent implementation to get tallydata and totalbin, then apply the
single Sphere-specific mutation: for RR_tally_IDs = [14, 24, 34] divide
tallydata[id]["Value"] by self.atomic_density (leave errors as produced by the
parent), remove the dead else: pass and duplicated helpers (filter_lookup,
columns, _prep_tally usage), and retain references to self.atomic_density and
RR_tally_IDs so the post-processing is obvious.

---

Nitpick comments:
In `@src/jade/post/sim_output.py`:
- Around line 425-437: The local variable "columns" in sim_output.py is
dead/duplicated and should be removed or re-used: either delete both occurrences
(the one at the top-level function and the duplicate in the Sphere override) to
eliminate dead code, or if you intended to enforce output column ordering, apply
this list after calling _remove_constant_columns (use it to reorder the
resulting columns and include the "Cosine"-style ordering) and remove the
duplicate list in the Sphere override; update the function(s) that build the
output table to use that ordering rather than leaving the list unused.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8d275765-b8d8-4dd2-921a-769d1d91e4a6

📥 Commits

Reviewing files that changed from the base of the PR and between bf42175 and 2dc8268.

📒 Files selected for processing (2)
  • src/jade/post/sim_output.py
  • tests/post/test_sim_output.py

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.

♻️ Duplicate comments (1)
src/jade/post/sim_output.py (1)

390-391: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard sorting when no filter columns are present.

tally.sort_values(filters) is still invoked unconditionally; for any tally whose dataframe has none of cell/surface/energy high [eV]/time, filters is empty and pandas will raise on the sort, dropping that tally from processing.

Proposed fix
-        sorted_tally = tally.sort_values(filters)
-        sorted_tally = sorted_tally.reset_index(drop=True)
+        sorted_tally = tally
+        if filters:
+            sorted_tally = sorted_tally.sort_values(filters)
+        sorted_tally = sorted_tally.reset_index(drop=True)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jade/post/sim_output.py` around lines 390 - 391, The code unconditionally
calls tally.sort_values(filters) which fails when filters is empty or none of
the filter names exist; update the block around tally, filters and sorted_tally
so you only call tally.sort_values(...) when there is at least one valid column
to sort by: compute the intersection between filters and tally.columns (or check
filters truthiness), and if the resulting list is non-empty call
tally.sort_values(valid_filters) then reset_index, otherwise skip sort and just
do tally.reset_index(drop=True) (references: variables tally, filters and the
call to sort_values producing sorted_tally).
🧹 Nitpick comments (1)
src/jade/post/sim_output.py (1)

496-554: ⚡ Quick win

Reduce duplication by delegating to the parent _create_dataframes.

The override copy-pastes the entire base implementation just to apply an extra Value/Error division by self.atomic_density for tally IDs 14/24/34. Note that dividing Error by atomic_density (line 545) has no net effect: line 550 immediately rewrites Error as Error / Value, and the atomic_density factor cancels between numerator and denominator. So the only quantity that actually needs adjustment is Value, which can be done after delegating to the base method.

This avoids re-declaring filter_lookup/columns/the loop, and keeps the two classes in sync if the base post-processing evolves.

Proposed refactor
     def _create_dataframes(
         self, tallies: dict
     ) -> tuple[dict[int, pd.DataFrame], dict[int, pd.DataFrame]]:
         """
         Function to create dataframes in JADE format from OpenMC dataframes.
         ...
         """
-        tallydata = {}
-        totalbin = {}
-        filter_lookup = {
-            "cell": "Cells",
-            "surface": "Segments",
-            "energy high [eV]": "Energy",
-            "time": "Time",
-            "mean": "Value",
-            "std. dev.": "Error",
-        }
-        columns = [
-            "Cells",
-            "User",
-            "Segments",
-            "Cosine",
-            "Energy",
-            "Time",
-            "Cor C",
-            "Cor B",
-            "Cor A",
-            "Value",
-            "Error",
-        ]
-        for id, tally in tallies.items():
-            sorted_tally = self._prep_tally(filter_lookup, tally)
-
-            # If tally is Sphere, and is tally 14,24,34 then need to normalise by atomic density
-            # Need to generate atomic density for a given Sphere input
-            RR_tally_IDs = [14, 24, 34]
-            if id in RR_tally_IDs:
-                sorted_tally["Value"] = sorted_tally["Value"] / self.atomic_density
-                sorted_tally["Error"] = sorted_tally["Error"] / self.atomic_density
-            else:
-                pass
-            
-            if "Value" in sorted_tally.columns and "Error" in sorted_tally.columns:
-                sorted_tally["Error"] = sorted_tally["Error"] / sorted_tally["Value"]
-            
-            tallydata[id] = sorted_tally
-            totalbin[id] = None
-        return tallydata, totalbin
+        # Normalize the raw `mean` (Value) by atomic density for the DPA/He/T
+        # production tallies before the base class converts Error to relative.
+        # Dividing Error here as well would be cancelled out by the subsequent
+        # Error/Value relative-error calculation, so only Value needs adjusting.
+        RR_tally_IDs = {14, 24, 34}
+        adjusted = {}
+        for tid, tally in tallies.items():
+            if tid in RR_tally_IDs and "mean" in tally.columns:
+                tally = tally.copy()
+                tally["mean"] = tally["mean"] / self.atomic_density
+            adjusted[tid] = tally
+        return super()._create_dataframes(adjusted)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/jade/post/sim_output.py` around lines 496 - 554, The overridden
_create_dataframes currently duplicates the base implementation; instead call
the parent implementation (e.g., parent_tallydata, parent_totalbin =
super()._create_dataframes(tallies)) to get tallydata and totalbin, then apply
the RR_tally_IDs = [14,24,34] adjustment by dividing only tallydata[id]["Value"]
by self.atomic_density for those ids (do not re-divide Error since the base
method already converts Error to a relative error), remove the duplicated
filter_lookup/columns/loop, and keep returning the modified tallydata and
totalbin.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@src/jade/post/sim_output.py`:
- Around line 390-391: The code unconditionally calls tally.sort_values(filters)
which fails when filters is empty or none of the filter names exist; update the
block around tally, filters and sorted_tally so you only call
tally.sort_values(...) when there is at least one valid column to sort by:
compute the intersection between filters and tally.columns (or check filters
truthiness), and if the resulting list is non-empty call
tally.sort_values(valid_filters) then reset_index, otherwise skip sort and just
do tally.reset_index(drop=True) (references: variables tally, filters and the
call to sort_values producing sorted_tally).

---

Nitpick comments:
In `@src/jade/post/sim_output.py`:
- Around line 496-554: The overridden _create_dataframes currently duplicates
the base implementation; instead call the parent implementation (e.g.,
parent_tallydata, parent_totalbin = super()._create_dataframes(tallies)) to get
tallydata and totalbin, then apply the RR_tally_IDs = [14,24,34] adjustment by
dividing only tallydata[id]["Value"] by self.atomic_density for those ids (do
not re-divide Error since the base method already converts Error to a relative
error), remove the duplicated filter_lookup/columns/loop, and keep returning the
modified tallydata and totalbin.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5b680ab4-4b91-4127-be86-ee26d819a600

📥 Commits

Reviewing files that changed from the base of the PR and between 2dc8268 and 161ebc5.

📒 Files selected for processing (1)
  • src/jade/post/sim_output.py

@dodu94 dodu94 merged commit 398d398 into JADE-V-V:developing May 21, 2026
7 checks passed
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