Skip to content

fix: correct guard order in OsemosysClass.RYE() to prevent phantom 'EmisId' key (#423)#424

Open
tejassinghbhati wants to merge 8 commits intoEAPD-DRB:mainfrom
tejassinghbhati:fix/423-rye-emisid-phantom-key
Open

fix: correct guard order in OsemosysClass.RYE() to prevent phantom 'EmisId' key (#423)#424
tejassinghbhati wants to merge 8 commits intoEAPD-DRB:mainfrom
tejassinghbhati:fix/423-rye-emisid-phantom-key

Conversation

@tejassinghbhati
Copy link
Copy Markdown
Contributor

Linked issue

Existing related work reviewed

  • Issues/PRs reviewed: Searched open and closed issues on EAPD-DRB/MUIOGO for "RYE", "EmisId", "OsemosysClass", "emission pivot" — none found addressing this method
  • If none found, write: None found after search

Overlap assessment

  • Classification: No overlap
  • Overlapping items: None
  • Why this is not duplicate/superseded: OsemosysClass.py has no prior fix commits in the upstream history. This is the first PR targeting the RYE() pivot method.

Why this PR should proceed

  • The bug silently corrupts the emission parameter index on every call to RYE(), injecting a phantom 'EmisId': {} key alongside the legitimate year-keyed entries
  • No exception is raised, making it undetectable without explicit key inspection
  • The fix is a one-line reorder (2 insertions, 2 deletions) with zero risk of regression — it aligns RYE() with the identical guard pattern used by all 10+ sibling pivot methods in the same class

Summary

  • What changed: Moved the if (year != 'EmisId'): guard before the dict initialisation in OsemosysClass.RYE() (lines 614–618 of API/Classes/Case/OsemosysClass.py)
  • Why: The previous order unconditionally inserted RYE[param][sc]['EmisId'] = {} into the output dict before the guard ran, producing a phantom key that downstream consumers (update_RYE in UpdateCaseClass.py and solver data-file writers) could silently misinterpret as a year value

Validation

  • Tests added/updated (or not applicable) — not applicable, no test suite currently exists for this method
  • Validation steps documented
  • Evidence attached (logs/screenshots/output as relevant)

Validation command (PowerShell, no case/DB needed):

@"
rye_raw = {'AnnualExogenousEmission': {'SC_0': [{'EmisId': 'CO2', '2020': 0.0, '2021': 0.5}]}}
RYE = {}
for param, obj1 in rye_raw.items():
RYE[param] = {}
for sc, array in obj1.items():
RYE[param][sc] = {}
for o in array:
for year, val in o.items():
if (year != 'EmisId'):
if year not in RYE[param][sc]:
RYE[param][sc][year] = {}
RYE[param][sc][year][o['EmisId']] = val
print('Keys found:', list(RYE['AnnualExogenousEmission']['SC_0'].keys()))
print('Bug fixed:', 'EmisId' not in RYE['AnnualExogenousEmission']['SC_0'])
"@ | python

Expected output:
Keys found: ['2020', '2021']
Bug fixed: True

Documentation

  • Docs updated in this PR (or not applicable) — not applicable, internal method fix with no API surface change
  • Any setup/workflow changes reflected in repo docs — no setup changes

Scope check

  • No unrelated refactors
  • Implemented from a feature branch (fix/423-rye-emisid-phantom-key)
  • Change is deliverable without upstream OSeMOSYS/MUIO dependency
  • Base repo/branch is EAPD-DRB/MUIOGO:main (not upstream)

Exception rationale

(left blank — this PR has a linked issue)

@github-actions github-actions bot added the needs-intake-fix PR intake structure needs maintainer follow-up label Apr 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-intake-fix PR intake structure needs maintainer follow-up

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] OsemosysClass.RYE() inserts a spurious empty dict for the 'EmisId' key, corrupting the emission parameter index

1 participant