Validation Health Status Workflow - #61
Conversation
…, and installed capacity
…ance comparison scripts for demand, capacity, and generation statistics
…ion MAE as percentages of total reference values
…in health status CSV
|
That is great @GbotemiB ! Give me a few days for the review. Looks amazing! |
davide-f
left a comment
There was a problem hiding this comment.
Thanks Emmanuel, nice introductions! Ember and Health status! :D
| optimal_capacity.drop(columns="bus", inplace=True, errors="ignore") | ||
| to_csv_nafix(optimal_capacity, outputs["optimal_capacity"]) | ||
|
|
||
| # 4. Extract generation mix (from both generators and storage units) |
There was a problem hiding this comment.
I see you have worked in parallel to Daniele on the generation mix. Please @danielelerede-oet and @GbotemiB , look at each other PRs and feel free to propose a common strategy.
Emmanuel used a different data source (Ember) and Daniele IRENA, so both are highly relevant features
There was a problem hiding this comment.
Thanks @davide-f, @danielelerede-oet, here's what I'm seeing comparing #61 and #63:
- We both independently fixed the same thing: accounting for storage-unit capacity in installed/optimal capacity stats, and computing network-side generation from generators_t.p + storage_units_t.p. These will conflict directly if merged separately.
- Different generation reference sources: I used Ember, you used IRENA. My
build_reference_statistics.pyalready treats each dataset type (demand, installed_capacity, generation) as a configurable list of sources (datasets.generation: [...]), so IRENA could slot in as a second source alongside Ember using the same pattern, once I address Davide's ask to harmonize columns instead of branching per-source. - Add electricity generation validation based on IRENA data #63 adds the downstream wiring (make_comparison.py, visualize_data.py) to actually compare/plot generation, which Validation Health Status Workflow #61 doesn't have yet. Add electricity generation validation based on IRENA data #63 also carries Store validation outputs per configuration #62's config-specific output directories, which my multi-network support will need anyway.
Proposal: land #62 first (output dirs), then converge on one generation-mix implementation, my multi-source datasets.generation config as the interface (supporting both ember and irena), your IRENA cleaning script + comparison/plotting wiring, and a single shared fix for the storage-capacity accounting.
Happy to hop on a call to divide up the remaining work if that's easier than doing it over PR comments.
There was a problem hiding this comment.
Works for me. We focus on #62 first. What about #63? Can we merge that and revisit here?
Please @GbotemiB and @danielelerede-oet share your view, given your possibilities
| # 1. Process demand data | ||
| if demand_source == "ourworldindata": | ||
| df_demand = read_csv_nafix(inputs["demand_owid"]) | ||
| df_demand = filter_data_by_config(df_demand, "region", countries) | ||
| df_demand = df_demand[df_demand["year"] == year] | ||
| df_demand = ( | ||
| df_demand[["region", "electricity_demand"]] | ||
| .rename(columns={"electricity_demand": "demand"}) | ||
| .set_index("region") | ||
| ) | ||
| elif demand_source == "ember": | ||
| df_demand = read_csv_nafix(inputs["demand_ember"]) | ||
| df_demand = filter_data_by_config(df_demand, "region", countries) | ||
| df_demand = df_demand[df_demand["Year"] == year] | ||
| df_demand = df_demand[["region", "demand"]].set_index("region") | ||
| else: | ||
| df_demand = pd.DataFrame(columns=["demand"]) |
There was a problem hiding this comment.
At this stage, I wouldn't expect to have different behaviour depending on the source, that would mean that the prior rules do have different data format. Can we harmonize the column names of the new sections to keep the common format?
In the else case, please add a warning highglighting empty demand
| @@ -70,12 +119,14 @@ rule build_network_geojson: | |||
| rule build_reference_statistics: | |||
| input: | |||
| demand_owid="resources/clean/owid_demand_data.csv", | |||
There was a problem hiding this comment.
In the future, here we could have
demand = [....], where the list is populated dynamically depending on the config option, then the code can be modularized even further.
I'm adding an issue on this, no action
Co-authored-by: Davide Fioriti <67809479+davide-f@users.noreply.github.com>
Closes # (if applicable).
The validation workflow in pypsa-earth-status evaluates solved PyPSA-Earth networks against real-world reference datasets (IRENA, and Our World in Data) to assess model accuracy and data quality.
Originally, the status check script was limited to validating a single network at a time.
This PR refactors the validation status workflow to support multi-scenario network validation, configurable reference sources with inclusion of Ember dataset covering demand, generation & installed capacity, and a
health_status.csvthat can help to collect validation results.Changes proposed in this Pull Request
config.networks) with auto-detected or explicit country scopes.pypsa-earthversion directly from network metadata (n.meta) with a configurable config fallback.health_status.csvdata will be used to collect validation results.README.md.Verification & Testing
To test this implementation:
Configure solved network paths in
config_copy.yaml:Add paths to your solved PyPSA network files (
.nc) under thenetworks:block inconfig.yaml. You can use the simple string format (for auto-detecting countries) or the dictionary format (to specify explicit countries):Configure multiple sources in
config_copy.yaml:Configure multiple sources for demand to verify that the long-format scales cleanly:
Run the Snakemake workflow:
Inspect the output (
results/health_status.csv):Checklist
envs/environment.yaml.config.yaml.doc/release-notes.mdis amended in the format of previous release notes, including reference to the requested PR.