Scenario export compatible with csv loader - #832
Conversation
…o rolling_horizon_dsm
…o rolling_horizon_dsm Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <copilot@github.com>
…o rolling_horizon_dsm
…o rolling_horizon_dsm
This is still very different from other units and includes many workarounds.
…o rolling_horizon_dsm
…Python versions other than 3.14
…o rolling_horizon_dsm
…forge3-latest RTD build was failing on `asdf install python mambaforge-4.10.3-10` since mambaforge is deprecated in favor of miniforge3. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…o rolling_horizon_dsm
…o rolling_horizon_dsm
…o rolling_horizon_dsm
PR Reviewer Guide 🔍(Review updated until commit 5666f76)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 5666f76 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit ecc4c48
Suggestions up to commit db6c85a
Suggestions up to commit ff4854d
Suggestions up to commit 6033a24
|
|
Persistent review updated to latest commit 0493bbd |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #832 +/- ##
==========================================
- Coverage 82.12% 81.57% -0.55%
==========================================
Files 56 58 +2
Lines 9078 9521 +443
==========================================
+ Hits 7455 7767 +312
- Misses 1623 1754 +131
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
I would rather have from scenario.exporter_csv import export_to_folder
def export(self, scenario_save_path, study_case):
export_to_folder(self, scenario_save_path, study_case)This way, we keep the world.py from handling IO |
There was a problem hiding this comment.
Edit: forecasts_df is actually temporarily saved in World which I missed in my first review.
Regarding forecasts:
One correct approach would be to save the forecast algorithm names on a per unit basis (as already in the PR addressed) and copy the forecasts_df.csv file to the exported files which is stored in the World.scenario_data
Following this, _get_forecast_algorithms can be safely removed.
_export_forecasts_df should thenbe adjusted to save the temporarily stored forecasts_df from world
Below I will try to explain the reasoning behind it as best as I can for those that are interested. Sorry if it is quite long, but at least its documented.
Currently, the PR deals with all three regular ways of selecting forecasts algorithms in the input (config.yaml, unit specific, forecasts_df). From my current understanding, this results in some problems in the proposed exporter. I will explain the differences and problems starting with the forecasts_df.csv as it will supersede the otheres by default.
- (_export_forecasts_df) Per default, if in forecasts_df there exists a forecast for any forecast type (e.g. "price_EOM") this will supersede all other forecast algorithms for "price" on EOM. The proposed Exporter will naively choose the first price forecasts it gets (even if it was not from the forecasts_df.csv in the first place). Thus each unit will automatically have the same forecast for "price_EOM" after exporting (even if before they had different ones). Same applies for residual_load.
- specifying forecasts in the individual units csv (powerplant_units.csv, ...) is the most versatile option, that will give each unit the opportunity to have its own forecasting algorithm. The Exporter currently will infer all used (and unused) forecast algorithms per unit and save them. While this might lead to a different looking csv file in the exported csv then in the input / imported one, this should give the correct behaviour as long this forecast algorithm was not superseded by forecasts_df in the scenario loading. Using forecasts_df.csv saving and this per unit forecast_algorithms will thus restore functionality
- (_get_forecast_algorithms) For the config.yaml variation, this will currently naively take the first algorithm for a specific type (e.g. "price") and select it as default in the config. While in theory the input version of the config.yaml forecast algorithms could be found in
World.scenario_data, it would be overwritten by 1. and 2. in the current exporter. It further does not support unit specific forecasts and thus is not suitable in general case. - There is a fourth possibility to add a forecast to a forecaster that is ignored by this exporter currently. A forecaster can get a specific forecast in the init which will be kept. As this functionality is not used in the regular loaders and mostly for testing, development and very customized usage, this case should be fine to ignore. This is especially the case, as it was "manually" added to the simulation in the first place, so it should be possible to add it "manually" again for the next usage after exporting.
|
Another point: |
|
Persistent review updated to latest commit 6033a24 |
|
Persistent review updated to latest commit ff4854d |
Rolling-horizon operation strategy selection now reads normalized_load_profile and steel_demand_per_timestep from the unit instead of injecting ID-prefixed attributes during forecaster initialization.
Steel plant forecast loading now uses get_unit_forecast_column, matching the ID-prefixed column convention with a generic fallback in one place.
Remove the duplicate price update override from SteelplantForecaster so runtime forecast refresh uses the standard update lifecycle once and pushes EOM prices to the unit when update is called with unit=unit.
|
Persistent review updated to latest commit db6c85a |
|
@mthede I traced the DSM export path (_dsm_unit_to_rows) against what the CSV loader actually reads back (load_dsm_units). The two example fixtures (example_01h building, example_03 steel plant) round trip works fine, but a few unit level attributes are silently dropped and reset to defaults on reload. e.g. Building is_prosumer, set is_prosumer = Yes on building A360 in example_01h -> export -> reload comes back as No (the default). The building loses its prosumer/PV feed-in behavior.
for attr in ["objective", "flexibility_measure", "cost_tolerance", question: DSM forecaster profiles (building inflexible load, heat demand, PV, EV availability, hydrogen demand series) don't seem to be written by _export_time_series. If those came from input CSVs, will a re-run of the exported folder reconstruct them, or is DSM profile input out of scope for this PR? |
|
Persistent review updated to latest commit ecc4c48 |
DSM units build Pyomo params from forecaster.electricity_price via _values_for_model, which slices to the rolling window without mutating forecaster state. Remove unit-side copies and forecaster-to-unit sync.
…requirements" This reverts commit ae32acd.
…ion for Python versions other than 3.14" This reverts commit 6ed0de6.
…rter
- Use reverse registry lookup (self.bidding_strategies) to write the
registered string key (e.g. 'powerplant_energy_naive') instead of
the raw Python class name ('EnergyNaiveStrategy'). Uses unit-type
prefix and market-name heuristics to pick the best match.
- Convert demand min_power/max_power and storage max_power_charge/
min_power_charge back to positive values on export, matching the
sign convention expected by loader_csv.py on re-import.
Assisted-by: gemini-3.5-flash
…er_csv.py - Moved all CSV-export helper methods and file IO operations out of world.py into a new dedicated module assume/scenario/exporter_csv.py - Replaced the inline exporting logic in World.export with a delegation to assume.scenario.exporter_csv.export_to_folder - Cleaned up unused imports (yaml, timedelta) in world.py Assisted-by: gemini-3.5-flash
- Added a test case 'test_world_export' in tests/test_world.py to verify World.export() dumps scenario correctly and it can be re-loaded matching the original. - Added a test case 'test_world_pypsa_export' in tests/test_world.py that verifies PyPSA loader integrations with the CSV exporter by loading, exporting, and reloading a PyPSA AC/DC meshed example network. Assisted-by: gemini-3.5-flash
ecc4c48 to
5666f76
Compare
|
Persistent review updated to latest commit 5666f76 |
User description
Related Issue
Closes #831
Description
WIP!
To try it out, just call ´world.export()´ after setting up a simulation with whatever tool you did.
Open issues:
Checklist
docsfolder updates, etc.)Additional Notes (optional)
This PR still needs work and through testing, in particular on:
PR Type
Enhancement, Bug fix, Tests, Documentation
Description
Add CSV-compatible scenario export
Serialize units, forecasts, grid data
Fix PyPSA and cost export conventions
Add round-trip export tests and docs
Diagram Walkthrough
File Walkthrough
2 files
Add CSV scenario export implementationAdd `World.export()` scenario method2 files
Align PyPSA scenario timing setupNormalize startup costs in unit export2 files
Add scenario export round-trip testsAdd forecast export test scenario6 files
Clarify forecast keep-given behaviorAdd demand fixture license metadataAdd demand units fixture licenseAdd forecasts fixture license metadataAdd fuel prices fixture licenseAdd powerplant fixture license metadata