Skip to content

Commit

Permalink
costs updated
Browse files Browse the repository at this point in the history
  • Loading branch information
trevorb1 committed Feb 14, 2025
1 parent bd50081 commit af44fd9
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 75 deletions.
11 changes: 7 additions & 4 deletions workflow/rules/postprocess.smk
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ rule calculate_carbon_intensity:
rule calculate_costs:
message:
"Calculating Costs..."
params:
otoole_input = "resources/otoole.yaml",
input_dir = "results/{scenario}/data/",
result_dir = "results/{scenario}/results/"
input:
discounted_cost_by_technology = "results/{scenario}/results/DiscountedCostByTechnology.csv",
demand = "results/{scenario}/results/Demand.csv",
Expand Down Expand Up @@ -177,10 +181,9 @@ rule calcualte_headline_metrics:
"Calculating Headline Metrics..."
params:
storage = config['storage_parameters'],
otoole_input = "resources/otoole.yaml"
otoole_results = "resources/otoole.yaml"
input_dir = "results/{scenario}/data/"
result_dir = "results/{scenario}/results/"
otoole_input = "resources/otoole.yaml",
input_dir = "results/{scenario}/data/",
result_dir = "results/{scenario}/results/",
input:
annual_emissions = "results/{scenario}/results/AnnualEmissions.csv",
production_by_technology = "results/{scenario}/results/ProductionByTechnologyAnnual.csv",
Expand Down
125 changes: 71 additions & 54 deletions workflow/scripts/osemosys_global/summary/costs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import pandas as pd
from pathlib import Path
from otoole import read
from utils import _read_result_data, get_discount_factor


def get_tech_cost(discounted_cost_tech: pd.DataFrame, country: bool) -> pd.DataFrame:
Expand Down Expand Up @@ -47,35 +49,34 @@ def get_storage_cost(
.sum()
)

def get_transmission_cost(discounted_cost_tech: pd.DataFrame, country: bool) -> pd.DataFrame:

def get_transmission_cost(
discounted_cost_tech: pd.DataFrame, country: bool
) -> pd.DataFrame:

df = discounted_cost_tech.copy()

df1 = df[
(df.index.get_level_values("TECHNOLOGY").str.startswith("TRN"))
].copy()
df1 = df[(df.index.get_level_values("TECHNOLOGY").str.startswith("TRN"))].copy()

if country:
r = "COUNTRY"
df1[r] = df1.index.get_level_values("TECHNOLOGY").str[3:6]
else:
r = "NODE"
df1[r] = df1.index.get_level_values("TECHNOLOGY").str[3:8]

df2 = df.copy()[
(df.index.get_level_values("TECHNOLOGY").str.startswith("TRN"))
]

df2 = df.copy()[(df.index.get_level_values("TECHNOLOGY").str.startswith("TRN"))]

if country:
r = "COUNTRY"
df2[r] = df2.index.get_level_values("TECHNOLOGY").str[8:11]
else:
r = "NODE"
df2[r] = df2.index.get_level_values("TECHNOLOGY").str[8:13]

for df in [df1, df2]:
df['VALUE'] = df['VALUE'] / 2
df["VALUE"] = df["VALUE"] / 2

df = pd.concat([df1, df2])

return (
Expand All @@ -84,6 +85,7 @@ def get_transmission_cost(discounted_cost_tech: pd.DataFrame, country: bool) ->
.sum()
)


def get_demand(demand: pd.DataFrame, country: bool) -> pd.DataFrame:

df = demand.copy()
Expand Down Expand Up @@ -114,44 +116,50 @@ def get_pwr_cost(demand: pd.DataFrame, cost: pd.DataFrame) -> pd.DataFrame:

if __name__ == "__main__":
if "snakemake" in globals():
discounted_cost_by_technology_csv = (
snakemake.input.discounted_cost_by_technology
)
demand_csv = snakemake.input.demand
input_data_dir = snakemake.params.input_dir
result_data_dir = snakemake.params.result_dir
otoole_config = snakemake.params.otoole_input
power_cost_node_csv = snakemake.output.node_pwr_cost
power_cost_country_csv = snakemake.output.country_pwr_cost
power_cost_global_csv = snakemake.output.global_pwr_cost
power_cost_global_csv = snakemake.output.global_pwr_cost
total_cost_node_csv = snakemake.output.node_cost
total_cost_country_csv = snakemake.output.country_cost
total_cost_global_csv = snakemake.output.global_cost

else:
discounted_cost_by_technology_csv = (
"results/India/results/DiscountedCostByTechnology.csv"
)
demand_csv = "results/India/results/Demand.csv"
input_data_dir = "results/India/data"
result_data_dir = "results/India/results"
otoole_config = "resources/otoole.yaml"
power_cost_node_csv = "results/India/result_summaries/PowerCostNode.csv"
power_cost_country_csv = "results/India/result_summaries/PowerCostCountry.csv"
power_cost_global_csv = "results/India/result_summaries/PowerCostGlobal.csv"
total_cost_node_csv = "results/India/result_summaries/TotalCostNode.csv"
total_cost_country_csv = "results/India/result_summaries/TotalCostCountry.csv"
total_cost_global_csv = "results/India/result_summaries/TotalCostGlobal.csv"

discounted_cost_by_technology = pd.read_csv(
discounted_cost_by_technology_csv, index_col=[0, 1, 2]
)
demand_raw = pd.read_csv(demand_csv, index_col=[0, 1, 2, 3])
input_data, input_defaults = read(otoole_config, "csv", input_data_dir)
result_data = _read_result_data(result_data_dir)

if input_data["DiscountRate"].empty:
regions = input_data["REGION"].VALUE.to_list()
assert len(regions) == 1
input_data["DiscountRate"] = pd.DataFrame(
[[regions[0], input_defaults["DiscountRate"]]], columns=["REGION", "VALUE"]
).set_index("REGION")

discounted_cost_by_technology = result_data["DiscountedCostByTechnology"]
demand = result_data["Demand"]

years = input_data["YEAR"].VALUE.to_list()
discount_factor = get_discount_factor(years, input_data["DiscountRate"])
result_data["DiscountedDemand"] = result_data["Demand"].div(discount_factor)

# handle the storage discounted costs outside of snakemake
# if running a model without storage, its not guaranteed that result
# csvs will be generated with all solvers
try:
parent = Path(discounted_cost_by_technology_csv).parent
discounted_cost_by_storage_csv = Path(parent, "DiscountedCostByStorage.csv")
discounted_cost_by_storage = pd.read_csv(
discounted_cost_by_storage_csv, index_col=[0, 1, 2]
)
except FileNotFoundError:
discounted_cost_by_storage = result_data["DiscountedCostByStorage"]
except KeyError:
discounted_cost_by_storage = pd.DataFrame(
columns=["REGION", "STORAGE", "YEAR", "VALUE"]
).set_index(["REGION", "STORAGE", "YEAR"])
Expand All @@ -160,12 +168,15 @@ def get_pwr_cost(demand: pd.DataFrame, cost: pd.DataFrame) -> pd.DataFrame:

tech_cost = get_tech_cost(discounted_cost_by_technology, country=False)
storage_cost = get_storage_cost(discounted_cost_by_storage, country=False)
transmission_cost = get_transmission_cost(discounted_cost_by_technology, country=False)

cost = tech_cost.add(storage_cost, fill_value = 0
).add(transmission_cost, fill_value = 0)

demand = get_demand(demand_raw, country=False)
transmission_cost = get_transmission_cost(
discounted_cost_by_technology, country=False
)

cost = tech_cost.add(storage_cost, fill_value=0).add(
transmission_cost, fill_value=0
)

demand = get_demand(result_data["DiscountedDemand"], country=False)
pwr_cost = get_pwr_cost(demand, cost)

pwr_cost.to_csv(power_cost_node_csv, index=True)
Expand All @@ -175,29 +186,35 @@ def get_pwr_cost(demand: pd.DataFrame, cost: pd.DataFrame) -> pd.DataFrame:

tech_cost_country = get_tech_cost(discounted_cost_by_technology, country=True)
storage_cost_country = get_storage_cost(discounted_cost_by_storage, country=True)
transmission_cost_country = get_transmission_cost(discounted_cost_by_technology, country=True)

cost_country = tech_cost_country.add(storage_cost_country, fill_value = 0
).add(transmission_cost_country, fill_value = 0)

demand_country = get_demand(demand_raw, country=True)
transmission_cost_country = get_transmission_cost(
discounted_cost_by_technology, country=True
)

cost_country = tech_cost_country.add(storage_cost_country, fill_value=0).add(
transmission_cost_country, fill_value=0
)

demand_country = get_demand(result_data["DiscountedDemand"], country=True)
pwr_cost_country = get_pwr_cost(demand_country, cost_country)

pwr_cost_country.to_csv(power_cost_country_csv, index=True)
cost_country.to_csv(total_cost_country_csv, index=True)

# global level metrics

cost_global = tech_cost_country.add(storage_cost_country,
fill_value = 0
).add(transmission_cost_country, fill_value = 0
).groupby(["YEAR"]).sum()

demand_global = get_demand(demand_raw, country=True)
demand_global = demand_global.groupby([
demand_global.index.get_level_values("YEAR")]).sum()

cost_global = (
tech_cost_country.add(storage_cost_country, fill_value=0)
.add(transmission_cost_country, fill_value=0)
.groupby(["YEAR"])
.sum()
)

demand_global = get_demand(result_data["DiscountedDemand"], country=True)
demand_global = demand_global.groupby(
[demand_global.index.get_level_values("YEAR")]
).sum()

pwr_cost_global = get_pwr_cost(demand_global, cost_global)

pwr_cost_global.to_csv(power_cost_global_csv, index=True)
cost_global.to_csv(total_cost_global_csv, index=True)
cost_global.to_csv(total_cost_global_csv, index=True)
17 changes: 1 addition & 16 deletions workflow/scripts/osemosys_global/summary/headline.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
from typing import Optional
from constants import RENEWABLES, FOSSIL, CLEAN
from otoole import read
from utils import get_discount_factor
from pathlib import Path
from utils import get_discount_factor, _read_result_data


def get_emissions(annual_emissions: pd.DataFrame) -> pd.DataFrame:
Expand Down Expand Up @@ -108,20 +107,6 @@ def get_gen_shares(
return pd.DataFrame(data, columns=["Metric", "Unit", "Value"])


def _read_result_data(result_dir: str) -> dict[str, pd.DataFrame]:
"""Reads in result CSVs
Issue with otoole config
"""
data = {}
files = [Path(x) for x in Path(result_dir).iterdir()]
for f in files:
df = pd.read_csv(f)
df = df.set_index(df.columns[:-1].tolist())
data[f.stem] = df
return data


if __name__ == "__main__":
if "snakemake" in globals():
storage = snakemake.params.storage
Expand Down
15 changes: 15 additions & 0 deletions workflow/scripts/osemosys_global/summary/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pandas as pd
from pathlib import Path


def get_discount_factor(
Expand Down Expand Up @@ -36,3 +37,17 @@ def get_discount_factor(
return discount_factor.reset_index()[["REGION", "YEAR", "VALUE"]].set_index(
["REGION", "YEAR"]
)


def _read_result_data(result_dir: str) -> dict[str, pd.DataFrame]:
"""Reads in result CSVs
Issue with otoole config
"""
data = {}
files = [Path(x) for x in Path(result_dir).iterdir()]
for f in files:
df = pd.read_csv(f)
df = df.set_index(df.columns[:-1].tolist())
data[f.stem] = df
return data
2 changes: 1 addition & 1 deletion workflow/scripts/osemosys_global/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import pandas as pd
from typing import Optional
from .constants import SET_DTYPES
from constants import SET_DTYPES

import logging

Expand Down

0 comments on commit af44fd9

Please sign in to comment.