Skip to content

Commit bc40583

Browse files
Wegatriespythonglatterf42
authored andcommitted
Refactor cooling into functions
1 parent 66f9394 commit bc40583

File tree

1 file changed

+125
-120
lines changed

1 file changed

+125
-120
lines changed

message_ix_models/model/water/report.py

Lines changed: 125 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,9 @@ def pop_water_access(sc: Scenario, reg: str, sdgs: bool = False) -> pd.DataFrame
404404
pop_sani_tot["variable"] = "Population|Sanitation Access"
405405
pop_sani_tot = pop_sani_tot[cols]
406406
# global values
407-
pop_sdg6 = pd.concat([pd.concat([pop_sdg6, pop_drink_tot]), pop_sani_tot])
407+
# pop_sdg6 already contains urban/rural drink and sani from loop above
408+
# Only need to add the totals
409+
pop_sdg6 = pd.concat([pop_sdg6, pop_drink_tot, pop_sani_tot])
408410
pop_sdg6_glb = (
409411
pop_sdg6.groupby(["variable", "unit", "year", "model", "scenario"])["value"]
410412
.sum()
@@ -449,8 +451,105 @@ def prepare_ww(ww_input: pd.DataFrame, suban: bool) -> pd.DataFrame:
449451

450452

451453
# TODO
452-
def report(sc: Scenario, reg: str, sdgs: bool = False) -> None:
453-
"""Report nexus module results"""
454+
def compute_cooling_technologies(
455+
report_iam: pyam.IamDataFrame
456+
) -> tuple[pyam.IamDataFrame, list]:
457+
"""Compute cooling technology metrics and return mapping rows.
458+
459+
Parameters
460+
----------
461+
report_iam : pyam.IamDataFrame
462+
Report in pyam format
463+
464+
Returns
465+
-------
466+
report_iam : pyam.IamDataFrame
467+
Updated report with cooling technology calculations
468+
cooling_rows : list
469+
List of [name, variables, unit] rows for cooling metrics
470+
"""
471+
# Freshwater cooling technologies water usage
472+
cooling_fresh_water = report_iam.filter(
473+
variable="in|water_supply|freshwater|*fresh|*"
474+
).variable
475+
cooling_ot_fresh_water = report_iam.filter(
476+
variable="in|water_supply|freshwater|*__ot_fresh|*"
477+
).variable
478+
cooling_cl_fresh_water = report_iam.filter(
479+
variable="in|water_supply|freshwater|*__cl_fresh|*"
480+
).variable
481+
482+
# Non-cooling technologies freshwater usage
483+
all_freshwater_tech = report_iam.filter(
484+
variable="in|water_supply|freshwater|*|*"
485+
).variable
486+
exclude_patterns = [
487+
"irrigation_", "__ot_fresh", "__cl_fresh", "__ot_saline", "__air",
488+
"industry_unconnected", "industry_untreated", "urban_t_d", "rural_t_d",
489+
"urban_unconnected", "rural_unconnected",
490+
]
491+
non_cooling_water = [
492+
v for v in all_freshwater_tech
493+
if not any(pattern in v for pattern in exclude_patterns)
494+
]
495+
496+
# Fresh water return flow emissions
497+
fresh_return_emissions = report_iam.filter(
498+
variable="emis|water_consumption|fresh_return|*|*"
499+
).variable
500+
501+
# Cooling investments
502+
cooling_saline_inv = report_iam.filter(variable="inv cost|*saline").variable
503+
cooling_air_inv = report_iam.filter(variable="inv cost|*air").variable
504+
cooling_ot_fresh = report_iam.filter(variable="inv cost|*ot_fresh").variable
505+
cooling_cl_fresh = report_iam.filter(variable="inv cost|*cl_fresh").variable
506+
507+
# Hydro electricity calculations
508+
elec_hydro_var = report_iam.filter(variable="out|secondary|electr|hydro*").variable
509+
report_iam = multiply_electricity_output_of_hydro(elec_hydro_var, report_iam)
510+
water_hydro_var = report_iam.filter(
511+
variable="Water Withdrawal|Electricity|Hydro|*"
512+
).variable
513+
514+
# Build cooling-specific mapping rows
515+
cooling_rows = [
516+
["Water Withdrawal|Electricity|Hydro", water_hydro_var, "MCM/yr"],
517+
["Water Withdrawal|Electricity|Cooling|Fresh Water", cooling_fresh_water, "MCM/yr"],
518+
["Water Withdrawal|Electricity|Cooling|Once Through|Fresh Water", cooling_ot_fresh_water, "MCM/yr"],
519+
["Water Withdrawal|Electricity|Cooling|Closed Loop|Fresh Water", cooling_cl_fresh_water, "MCM/yr"],
520+
["Water Withdrawal|Energy|Non-Cooling", non_cooling_water, "MCM/yr"],
521+
["Water Return|Electricity|Cooling", fresh_return_emissions, "MCM/yr"],
522+
["Investment|Infrastructure|Water|Cooling",
523+
cooling_ot_fresh + cooling_cl_fresh + cooling_saline_inv + cooling_air_inv,
524+
"million US$2010/yr"],
525+
["Investment|Infrastructure|Water|Cooling|Once through freshwater", cooling_ot_fresh, "million US$2010/yr"],
526+
["Investment|Infrastructure|Water|Cooling|Closed loop freshwater", cooling_cl_fresh, "million US$2010/yr"],
527+
["Investment|Infrastructure|Water|Cooling|Once through saline", cooling_saline_inv, "million US$2010/yr"],
528+
["Investment|Infrastructure|Water|Cooling|Air cooled", cooling_air_inv, "million US$2010/yr"],
529+
]
530+
531+
# Store water_hydro_var for later filtering
532+
report_iam.metadata = getattr(report_iam, 'metadata', {})
533+
report_iam.metadata['water_hydro_var'] = water_hydro_var
534+
report_iam.metadata['cooling_inv_vars'] = cooling_ot_fresh + cooling_cl_fresh + cooling_saline_inv + cooling_air_inv
535+
536+
return report_iam, cooling_rows
537+
538+
539+
def report(sc: Scenario, reg: str, sdgs: bool = False, include_cooling: bool = True) -> None:
540+
"""Report nexus module results
541+
542+
Parameters
543+
----------
544+
sc : Scenario
545+
Scenario to report
546+
reg : str
547+
Region to report
548+
sdgs : bool, optional
549+
If True, add population with access to water and sanitation for SDG6
550+
include_cooling : bool, optional
551+
If True, include cooling technology calculations in the report (default True)
552+
"""
454553
log.info(f"Regions given as {reg}; no warranty if it's not in ['R11','R12']")
455554
# Generating reporter
456555
rep = Reporter.from_scenario(sc)
@@ -729,60 +828,10 @@ def report(sc: Scenario, reg: str, sdgs: bool = False) -> None:
729828
variable="in|water_supply_basin|freshwater_basin|basin_to_reg|*"
730829
).variable
731830

732-
# Freshwater cooling technologies water usage
733-
cooling_fresh_water = report_iam.filter(
734-
variable="in|water_supply|freshwater|*fresh|*"
735-
).variable
736-
cooling_ot_fresh_water = report_iam.filter(
737-
variable="in|water_supply|freshwater|*__ot_fresh|*"
738-
).variable
739-
cooling_cl_fresh_water = report_iam.filter(
740-
variable="in|water_supply|freshwater|*__cl_fresh|*"
741-
).variable
742-
743-
# Non-cooling technologies freshwater usage
744-
# (all freshwater techs except already reported)
745-
all_freshwater_tech = report_iam.filter(
746-
variable="in|water_supply|freshwater|*|*"
747-
).variable
748-
# Remove already-reported categories: irrigation and cooling technologies
749-
exclude_patterns = [
750-
"irrigation_",
751-
"__ot_fresh",
752-
"__cl_fresh",
753-
"__ot_saline",
754-
"__air",
755-
"industry_unconnected",
756-
"industry_untreated",
757-
"urban_t_d",
758-
"rural_t_d",
759-
"urban_unconnected",
760-
"rural_unconnected",
761-
]
762-
# Exclude water demand technologies to avoid double-counting
763-
non_cooling_water = [
764-
v
765-
for v in all_freshwater_tech
766-
if not any(pattern in v for pattern in exclude_patterns)
767-
]
768-
769-
# Fresh water return flow emissions from cooling technologies
770-
fresh_return_emissions = report_iam.filter(
771-
variable="emis|water_consumption|fresh_return|*|*"
772-
).variable
773-
774-
cooling_saline_inv = report_iam.filter(variable="inv cost|*saline").variable
775-
cooling_air_inv = report_iam.filter(variable="inv cost|*air").variable
776-
cooling_ot_fresh = report_iam.filter(variable="inv cost|*ot_fresh").variable
777-
cooling_cl_fresh = report_iam.filter(variable="inv cost|*cl_fresh").variable
778-
779-
elec_hydro_var = report_iam.filter(variable="out|secondary|electr|hydro*").variable
780-
781-
report_iam = multiply_electricity_output_of_hydro(elec_hydro_var, report_iam)
782-
783-
water_hydro_var = report_iam.filter(
784-
variable="Water Withdrawal|Electricity|Hydro|*"
785-
).variable
831+
# Process cooling technologies if enabled
832+
cooling_rows = []
833+
if include_cooling:
834+
report_iam, cooling_rows = compute_cooling_technologies(report_iam)
786835

787836
# mapping for aggregation
788837
map_agg_pd = pd.DataFrame(
@@ -835,32 +884,6 @@ def report(sc: Scenario, reg: str, sdgs: bool = False) -> None:
835884
["Water Withdrawal|Irrigation|Cereal", irr_c, "MCM/yr"],
836885
["Water Withdrawal|Irrigation|Oil Crops", irr_o, "MCM/yr"],
837886
["Water Withdrawal|Irrigation|Sugar Crops", irr_s, "MCM/yr"],
838-
["Water Withdrawal|Electricity|Hydro", water_hydro_var, "MCM/yr"],
839-
[
840-
"Water Withdrawal|Electricity|Cooling|Fresh Water",
841-
cooling_fresh_water,
842-
"MCM/yr",
843-
],
844-
[
845-
"Water Withdrawal|Electricity|Cooling|Once Through|Fresh Water",
846-
cooling_ot_fresh_water,
847-
"MCM/yr",
848-
],
849-
[
850-
"Water Withdrawal|Electricity|Cooling|Closed Loop|Fresh Water",
851-
cooling_cl_fresh_water,
852-
"MCM/yr",
853-
],
854-
[
855-
"Water Withdrawal|Energy|Non-Cooling",
856-
non_cooling_water,
857-
"MCM/yr",
858-
],
859-
[
860-
"Water Return|Electricity|Cooling",
861-
fresh_return_emissions,
862-
"MCM/yr",
863-
],
864887
[
865888
"Capacity Additions|Infrastructure|Water",
866889
# Removed sub-components to avoid double-counting since:
@@ -1113,10 +1136,7 @@ def report(sc: Scenario, reg: str, sdgs: bool = False) -> None:
11131136
+ extrt_gw_inv
11141137
+ extrt_fgw_inv
11151138
+ saline_inv
1116-
+ cooling_ot_fresh
1117-
+ cooling_cl_fresh
1118-
+ cooling_saline_inv
1119-
+ cooling_air_inv
1139+
+ (getattr(report_iam, 'metadata', {}).get('cooling_inv_vars', []))
11201140
+ industry_unconnected_inv,
11211141
"million US$2010/yr",
11221142
],
@@ -1150,34 +1170,6 @@ def report(sc: Scenario, reg: str, sdgs: bool = False) -> None:
11501170
saline_inv,
11511171
"million US$2010/yr",
11521172
],
1153-
[
1154-
"Investment|Infrastructure|Water|Cooling",
1155-
cooling_ot_fresh
1156-
+ cooling_cl_fresh
1157-
+ cooling_saline_inv
1158-
+ cooling_air_inv,
1159-
"million US$2010/yr",
1160-
],
1161-
[
1162-
"Investment|Infrastructure|Water|Cooling|Once through freshwater",
1163-
cooling_ot_fresh,
1164-
"million US$2010/yr",
1165-
],
1166-
[
1167-
"Investment|Infrastructure|Water|Cooling|Closed loop freshwater",
1168-
cooling_cl_fresh,
1169-
"million US$2010/yr",
1170-
],
1171-
[
1172-
"Investment|Infrastructure|Water|Cooling|Once through saline",
1173-
cooling_saline_inv,
1174-
"million US$2010/yr",
1175-
],
1176-
[
1177-
"Investment|Infrastructure|Water|Cooling|Air cooled",
1178-
cooling_air_inv,
1179-
"million US$2010/yr",
1180-
],
11811173
# [
11821174
# "Investment|Infrastructure|Water",
11831175
# rural_infrastructure_inv + urban_infrastructure_inv,
@@ -1353,7 +1345,7 @@ def report(sc: Scenario, reg: str, sdgs: bool = False) -> None:
13531345
industry_unconnected_totalom,
13541346
"million US$2010/yr",
13551347
],
1356-
],
1348+
] + cooling_rows, # Add cooling rows here
13571349
columns=["names", "list_cat", "unit"],
13581350
)
13591351

@@ -1477,7 +1469,8 @@ def weighted_average_safe(x):
14771469
report_pd = report_pd.drop(columns=["to_keep"])
14781470

14791471
# ecluded other intermediate variables added later to report_iam
1480-
report_pd = report_pd[-report_pd.variable.isin(water_hydro_var)]
1472+
if include_cooling and hasattr(report_iam, 'metadata') and 'water_hydro_var' in report_iam.metadata:
1473+
report_pd = report_pd[-report_pd.variable.isin(report_iam.metadata['water_hydro_var'])]
14811474

14821475
# add water population
14831476
pop_sdg6 = pop_water_access(sc, reg, sdgs)
@@ -1542,8 +1535,20 @@ def weighted_average_safe(x):
15421535
sc.commit("Reporting uploaded as timeseries")
15431536

15441537

1545-
def report_full(sc: Scenario, reg: str, sdgs=False) -> None:
1546-
"""Combine old and new reporting workflows"""
1538+
def report_full(sc: Scenario, reg: str, sdgs=False, include_cooling: bool = True) -> None:
1539+
"""Combine old and new reporting workflows
1540+
1541+
Parameters
1542+
----------
1543+
sc : Scenario
1544+
Scenario to report
1545+
reg : str
1546+
Region to report
1547+
sdgs : bool, optional
1548+
If True, add population with access to water and sanitation for SDG6
1549+
include_cooling : bool, optional
1550+
If True, include cooling technology calculations in the report (default True)
1551+
"""
15471552
a = sc.timeseries()
15481553
# keep historical part, if present
15491554
a = a[a.year >= 2020]
@@ -1558,7 +1563,7 @@ def report_full(sc: Scenario, reg: str, sdgs=False) -> None:
15581563
run_old_reporting(sc)
15591564
log.info("First part of reporting completed, now procede with the water variables")
15601565

1561-
report(sc, reg, sdgs)
1566+
report(sc, reg, sdgs, include_cooling)
15621567
log.info("overall NAVIGATE reporting completed")
15631568

15641569
# add ad-hoc caplculated variables with a function

0 commit comments

Comments
 (0)