From f06e1d6f30ab12629c04bfaec7079c2d705716f3 Mon Sep 17 00:00:00 2001 From: "j.aschauer" <38501948+joAschauer@users.noreply.github.com> Date: Tue, 7 May 2024 11:37:25 +0200 Subject: [PATCH 1/7] correctly deduplicate hash values and add records to index --- flh_opt/collect_cached_optimization_results.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/flh_opt/collect_cached_optimization_results.py b/flh_opt/collect_cached_optimization_results.py index 6aa6f2a1..b0e8b395 100644 --- a/flh_opt/collect_cached_optimization_results.py +++ b/flh_opt/collect_cached_optimization_results.py @@ -56,11 +56,13 @@ def main( hash_set = set() index = [] for row in index_w_hash_duplicates: + if row.get("error"): + continue hashsum = row["result"]["hash_md5"] if hashsum in hash_set: continue hash_set.add(hashsum) - index.append(row) + index.append(row) for row in tqdm(index): params = row["params"] @@ -101,6 +103,9 @@ def main( results.append(result) + # test comment + # blablabla + # blabla # extract record in "main_process_chain" main_process_chain = extract_main_process_chain_data(results) From 6849057f788d8a5dd251aede1812c1605e64ea37 Mon Sep 17 00:00:00 2001 From: "j.aschauer" <38501948+joAschauer@users.noreply.github.com> Date: Tue, 7 May 2024 11:53:54 +0200 Subject: [PATCH 2/7] remove test comments --- flh_opt/collect_cached_optimization_results.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/flh_opt/collect_cached_optimization_results.py b/flh_opt/collect_cached_optimization_results.py index b0e8b395..843dce96 100644 --- a/flh_opt/collect_cached_optimization_results.py +++ b/flh_opt/collect_cached_optimization_results.py @@ -103,9 +103,6 @@ def main( results.append(result) - # test comment - # blablabla - # blabla # extract record in "main_process_chain" main_process_chain = extract_main_process_chain_data(results) From ea009862d1174ccf7de05ba4e21fc4f2995dd0d3 Mon Sep 17 00:00:00 2001 From: "j.aschauer" <38501948+joAschauer@users.noreply.github.com> Date: Tue, 7 May 2024 16:50:26 +0200 Subject: [PATCH 3/7] WIP: draft comparison script --- scripts/compare_optimized_vs_old.py | 149 ++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 scripts/compare_optimized_vs_old.py diff --git a/scripts/compare_optimized_vs_old.py b/scripts/compare_optimized_vs_old.py new file mode 100644 index 00000000..054fdf3e --- /dev/null +++ b/scripts/compare_optimized_vs_old.py @@ -0,0 +1,149 @@ +# -*- coding: utf-8 -*- +"""Compare cost results and flh from optimized vs non-optimized FLH.""" +import itertools +import logging +import random +import sys +from pathlib import Path +from typing import Literal + +import numpy as np +import pandas as pd + +sys.path.append(str(Path(__file__).parent.parent)) +from ptxboa import DEFAULT_CACHE_DIR, DEFAULT_DATA_DIR +from ptxboa.api import PtxboaAPI + +loglevel = "info" + +fmt = "[%(asctime)s %(levelname)7s] %(message)s" +datefmt = "%Y-%m-%d %H:%M:%S" +logging.basicConfig( + level=loglevel.upper(), + format=fmt, + datefmt=datefmt, +) +CACHE_DIR = Path("/home/ptxboa/ptx-boa_offline_optimization/optimization_cache") + + +def product_dict(**kwargs): + """Yield the cartesian product of a dictionary of lists. + + https://stackoverflow.com/a/5228294 + """ + keys = kwargs.keys() + for instance in itertools.product(*kwargs.values()): + yield dict(zip(keys, instance)) + + +def random_sample(param_arrays): + return {k: random.choice(v) for k, v in param_arrays.items()} # noqa S311 + + +def main( + cache_dir: Path = CACHE_DIR, + out_dir: Path = None, + loglevel: Literal["debug", "info", "warning", "error"] = "warning", +): + + cache_dir = Path(cache_dir) + if not cache_dir.exists(): + raise FileNotFoundError(f"cache_dir doe not exists {cache_dir}") + + out_dir = Path(out_dir).resolve() if out_dir else cache_dir + out_dir.mkdir(parents=True, exist_ok=True) + + +api = PtxboaAPI(data_dir=DEFAULT_DATA_DIR, cache_dir=DEFAULT_CACHE_DIR) + +param_arrays = { + "transport": api.get_dimension("transport").index.tolist(), + "ship_own_fuel": [True, False], + "secproc_water": api.get_dimension("secproc_water").index.tolist(), + "secproc_co2": api.get_dimension("secproc_co2").index.tolist(), + "scenario": api.get_dimension("scenario").index.tolist(), + "country": api.get_dimension("country").index.tolist(), + "res_gen": api.get_dimension("res_gen").index.tolist(), + "region": api.get_dimension("region")["region_name"].tolist(), + "chain": api.get_dimension("chain").index.tolist(), +} +# remove tracking PV (not implemented) +try: + param_arrays["res_gen"].remove("PV tracking") +except ValueError: + pass + +index_cols = [ + "process_type", + "process_subtype", + "cost_type", + "scenario", + "secproc_co2", + "secproc_water", + "chain", + "res_gen", + "region", + "country", + "transport", +] + +optimized_col = "optimized_flh" +no_optimized_col = "no_optimized_flh" + +results = [] +# for i, param_set in enumerate(product_dict(**param_arrays)): +for i in range(10): + + param_set = random_sample(param_arrays) + try: + + df_no_opt = ( + api.calculate(optimize_flh=False, **param_set)[0] + .rename(columns={"values": no_optimized_col}) + .set_index(index_cols) + ) + try: + df_opt = ( + api.calculate(optimize_flh=True, **param_set)[0] + .rename(columns={"values": optimized_col}) + .set_index(index_cols) + ) + df = pd.concat( + [df_no_opt, df_opt], + axis=1, + ) + except KeyError as e: + logging.error( + f"Not possible to caluclate optimization for param_set {param_set}" + ) + logging.error(f"KeyError: {e}") + df = df_no_opt.copy() + df[optimized_col] = np.nan + + results.append(df.reset_index()) + + except KeyError as e: + logging.error(f"Not possible to caluclate param_set {param_set}") + logging.error(f"KeyError: {e}") + pass + + if i > 10: + break + +results = pd.concat(results, axis=0, ignore_index=True) + + +######## +""" +Error for the following param set: +{'transport': 'Ship', + 'ship_own_fuel': True, + 'secproc_water': 'Specific costs', + 'secproc_co2': 'Direct Air Capture', + 'scenario': '2040 (low)', + 'country': 'India', + 'res_gen': 'PV tilted', + 'region': 'Indonesia', + 'chain': 'Green Iron (SEOC)'} + +""" From 6492f33210c224f101a2c78e7409f4510af772c8 Mon Sep 17 00:00:00 2001 From: "j.aschauer" <38501948+joAschauer@users.noreply.github.com> Date: Tue, 7 May 2024 18:19:52 +0200 Subject: [PATCH 4/7] WIP: cost comparison calculation --- scripts/compare_optimized_vs_old.py | 108 +++++++++++++++++----------- 1 file changed, 65 insertions(+), 43 deletions(-) diff --git a/scripts/compare_optimized_vs_old.py b/scripts/compare_optimized_vs_old.py index 054fdf3e..cb8968e8 100644 --- a/scripts/compare_optimized_vs_old.py +++ b/scripts/compare_optimized_vs_old.py @@ -14,16 +14,7 @@ from ptxboa import DEFAULT_CACHE_DIR, DEFAULT_DATA_DIR from ptxboa.api import PtxboaAPI -loglevel = "info" - -fmt = "[%(asctime)s %(levelname)7s] %(message)s" -datefmt = "%Y-%m-%d %H:%M:%S" -logging.basicConfig( - level=loglevel.upper(), - format=fmt, - datefmt=datefmt, -) -CACHE_DIR = Path("/home/ptxboa/ptx-boa_offline_optimization/optimization_cache") +SERVER_CACHE_DIR = Path("/home/ptxboa/ptx-boa_offline_optimization/optimization_cache") def product_dict(**kwargs): @@ -41,22 +32,45 @@ def random_sample(param_arrays): def main( - cache_dir: Path = CACHE_DIR, + cache_dir: Path = DEFAULT_CACHE_DIR, out_dir: Path = None, loglevel: Literal["debug", "info", "warning", "error"] = "warning", ): + pass + + +cache_dir = SERVER_CACHE_DIR +out_dir = None +transport = "all" +ship_own_fuel = "all" +secproc_water = "all" +secproc_co2 = "all" +scenario = ["2030 (medium)"] +country = "all" +res_gen = "all" +region = ["Morocco", "Argentina"] +chain = "all" + +loglevel = "warning" - cache_dir = Path(cache_dir) - if not cache_dir.exists(): - raise FileNotFoundError(f"cache_dir doe not exists {cache_dir}") +fmt = "[%(asctime)s %(levelname)7s] %(message)s" +datefmt = "%Y-%m-%d %H:%M:%S" +logging.basicConfig( + level=loglevel.upper(), + format=fmt, + datefmt=datefmt, +) +cache_dir = Path(cache_dir) +if not cache_dir.exists(): + raise FileNotFoundError(f"cache_dir doe not exists {cache_dir}") - out_dir = Path(out_dir).resolve() if out_dir else cache_dir - out_dir.mkdir(parents=True, exist_ok=True) +out_dir = Path(out_dir).resolve() if out_dir else cache_dir +out_dir.mkdir(parents=True, exist_ok=True) -api = PtxboaAPI(data_dir=DEFAULT_DATA_DIR, cache_dir=DEFAULT_CACHE_DIR) +api = PtxboaAPI(data_dir=DEFAULT_DATA_DIR, cache_dir=cache_dir) -param_arrays = { +param_arrays_complete = { "transport": api.get_dimension("transport").index.tolist(), "ship_own_fuel": [True, False], "secproc_water": api.get_dimension("secproc_water").index.tolist(), @@ -69,10 +83,32 @@ def main( } # remove tracking PV (not implemented) try: - param_arrays["res_gen"].remove("PV tracking") + param_arrays_complete["res_gen"].remove("PV tracking") except ValueError: pass +passed_dims = { + "transport": transport, + "ship_own_fuel": ship_own_fuel, + "secproc_water": secproc_water, + "secproc_co2": secproc_co2, + "scenario": scenario, + "country": country, + "res_gen": res_gen, + "region": region, + "chain": chain, +} + +param_arrays = {} +for dim, dv in passed_dims.items(): + if dv == "all": + param_arrays[dim] = param_arrays_complete[dim] + else: + assert isinstance(dv, list) + assert all(x in param_arrays_complete[dim] for x in dv) + param_arrays[dim] = dv + + index_cols = [ "process_type", "process_subtype", @@ -86,17 +122,16 @@ def main( "country", "transport", ] - +n_total = len(list(product_dict(**param_arrays))) +logging.info(f"calculating costs for {n_total} parameter sets") optimized_col = "optimized_flh" no_optimized_col = "no_optimized_flh" results = [] -# for i, param_set in enumerate(product_dict(**param_arrays)): -for i in range(10): - - param_set = random_sample(param_arrays) +for i, param_set in enumerate(product_dict(**param_arrays)): + if i % 1000 == 0: + logging.info(f"{i} of {n_total} parameter combinations") try: - df_no_opt = ( api.calculate(optimize_flh=False, **param_set)[0] .rename(columns={"values": no_optimized_col}) @@ -127,23 +162,10 @@ def main( logging.error(f"KeyError: {e}") pass - if i > 10: - break - -results = pd.concat(results, axis=0, ignore_index=True) + except AssertionError: + logging.error("AssertionError: invalid parameter combination") + pass -######## -""" -Error for the following param set: -{'transport': 'Ship', - 'ship_own_fuel': True, - 'secproc_water': 'Specific costs', - 'secproc_co2': 'Direct Air Capture', - 'scenario': '2040 (low)', - 'country': 'India', - 'res_gen': 'PV tilted', - 'region': 'Indonesia', - 'chain': 'Green Iron (SEOC)'} - -""" +results = pd.concat(results, axis=0, ignore_index=True) +results.to_csv("/home/j.aschauer/ptxboa_result_comparison/cost_comparison_output.csv") From afafdc69963d06d8cd0f1cca179d55b32d7754b7 Mon Sep 17 00:00:00 2001 From: "j.aschauer" <38501948+joAschauer@users.noreply.github.com> Date: Wed, 8 May 2024 12:33:48 +0200 Subject: [PATCH 5/7] update cost comparison script --- scripts/compare_optimized_vs_old.py | 327 +++++++++++++++++----------- 1 file changed, 198 insertions(+), 129 deletions(-) diff --git a/scripts/compare_optimized_vs_old.py b/scripts/compare_optimized_vs_old.py index cb8968e8..1a64a6e0 100644 --- a/scripts/compare_optimized_vs_old.py +++ b/scripts/compare_optimized_vs_old.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 -*- """Compare cost results and flh from optimized vs non-optimized FLH.""" import itertools +import json import logging -import random import sys from pathlib import Path from typing import Literal +import click import numpy as np import pandas as pd @@ -27,145 +28,213 @@ def product_dict(**kwargs): yield dict(zip(keys, instance)) -def random_sample(param_arrays): - return {k: random.choice(v) for k, v in param_arrays.items()} # noqa S311 - - def main( + out_file: str | Path, cache_dir: Path = DEFAULT_CACHE_DIR, - out_dir: Path = None, - loglevel: Literal["debug", "info", "warning", "error"] = "warning", + transport: Literal["all"] | list = "all", + ship_own_fuel: Literal["all"] | list = "all", + secproc_water: Literal["all"] | list = "all", + secproc_co2: Literal["all"] | list = "all", + scenario: Literal["all"] | list = "all", + country: Literal["all"] | list = "all", + res_gen: Literal["all"] | list = "all", + region: Literal["all"] | list = "all", + chain: Literal["all"] | list = "all", + process_type_filter: None | list = None, + loglevel: Literal["debug", "info", "warning", "error"] = "info", ): - pass - - -cache_dir = SERVER_CACHE_DIR -out_dir = None -transport = "all" -ship_own_fuel = "all" -secproc_water = "all" -secproc_co2 = "all" -scenario = ["2030 (medium)"] -country = "all" -res_gen = "all" -region = ["Morocco", "Argentina"] -chain = "all" - -loglevel = "warning" - -fmt = "[%(asctime)s %(levelname)7s] %(message)s" -datefmt = "%Y-%m-%d %H:%M:%S" -logging.basicConfig( - level=loglevel.upper(), - format=fmt, - datefmt=datefmt, -) -cache_dir = Path(cache_dir) -if not cache_dir.exists(): - raise FileNotFoundError(f"cache_dir doe not exists {cache_dir}") - -out_dir = Path(out_dir).resolve() if out_dir else cache_dir -out_dir.mkdir(parents=True, exist_ok=True) - - -api = PtxboaAPI(data_dir=DEFAULT_DATA_DIR, cache_dir=cache_dir) - -param_arrays_complete = { - "transport": api.get_dimension("transport").index.tolist(), - "ship_own_fuel": [True, False], - "secproc_water": api.get_dimension("secproc_water").index.tolist(), - "secproc_co2": api.get_dimension("secproc_co2").index.tolist(), - "scenario": api.get_dimension("scenario").index.tolist(), - "country": api.get_dimension("country").index.tolist(), - "res_gen": api.get_dimension("res_gen").index.tolist(), - "region": api.get_dimension("region")["region_name"].tolist(), - "chain": api.get_dimension("chain").index.tolist(), -} -# remove tracking PV (not implemented) -try: - param_arrays_complete["res_gen"].remove("PV tracking") -except ValueError: - pass - -passed_dims = { - "transport": transport, - "ship_own_fuel": ship_own_fuel, - "secproc_water": secproc_water, - "secproc_co2": secproc_co2, - "scenario": scenario, - "country": country, - "res_gen": res_gen, - "region": region, - "chain": chain, -} - -param_arrays = {} -for dim, dv in passed_dims.items(): - if dv == "all": - param_arrays[dim] = param_arrays_complete[dim] - else: - assert isinstance(dv, list) - assert all(x in param_arrays_complete[dim] for x in dv) - param_arrays[dim] = dv - - -index_cols = [ - "process_type", - "process_subtype", - "cost_type", - "scenario", - "secproc_co2", - "secproc_water", - "chain", - "res_gen", - "region", - "country", - "transport", -] -n_total = len(list(product_dict(**param_arrays))) -logging.info(f"calculating costs for {n_total} parameter sets") -optimized_col = "optimized_flh" -no_optimized_col = "no_optimized_flh" - -results = [] -for i, param_set in enumerate(product_dict(**param_arrays)): - if i % 1000 == 0: - logging.info(f"{i} of {n_total} parameter combinations") + fmt = "[%(asctime)s %(levelname)7s] %(message)s" + datefmt = "%Y-%m-%d %H:%M:%S" + logging.basicConfig( + level=loglevel.upper(), + format=fmt, + datefmt=datefmt, + ) + out_file = Path(out_file).resolve() + cache_dir = Path(cache_dir) + if not cache_dir.exists(): + raise FileNotFoundError(f"cache_dir does not exists {cache_dir}") + + logging.info(f"using cache_dir: {cache_dir}") + + api = PtxboaAPI(data_dir=DEFAULT_DATA_DIR, cache_dir=cache_dir) + + param_arrays_complete = { + "transport": api.get_dimension("transport").index.tolist(), + "ship_own_fuel": [True, False], + "secproc_water": api.get_dimension("secproc_water").index.tolist(), + "secproc_co2": api.get_dimension("secproc_co2").index.tolist(), + "scenario": api.get_dimension("scenario").index.tolist(), + "country": api.get_dimension("country").index.tolist(), + "res_gen": api.get_dimension("res_gen").index.tolist(), + "region": api.get_dimension("region")["region_name"].tolist(), + "chain": api.get_dimension("chain").index.tolist(), + } + # remove tracking PV (not implemented) try: - df_no_opt = ( - api.calculate(optimize_flh=False, **param_set)[0] - .rename(columns={"values": no_optimized_col}) - .set_index(index_cols) - ) + param_arrays_complete["res_gen"].remove("PV tracking") + except ValueError: + pass + + passed_dims = { + "transport": transport, + "ship_own_fuel": ship_own_fuel, + "secproc_water": secproc_water, + "secproc_co2": secproc_co2, + "scenario": scenario, + "country": country, + "res_gen": res_gen, + "region": region, + "chain": chain, + } + + param_arrays = {} + for dim, dv in passed_dims.items(): + if dv == "all": + param_arrays[dim] = param_arrays_complete[dim] + else: + if not isinstance(dv, list): + raise TypeError(f"{dim} must be of type list") + if not all(x in param_arrays_complete[dim] for x in dv): + raise ValueError( + f"entries of {dim} must be in {param_arrays_complete[dim]}" + ) + param_arrays[dim] = dv + + index_cols = [ + "process_type", + "process_subtype", + "cost_type", + "scenario", + "secproc_co2", + "secproc_water", + "chain", + "res_gen", + "region", + "country", + "transport", + ] + + n_total = np.prod([len(x) for x in param_arrays.values()]) + logging.warning(f"calculating costs for {n_total} parameter sets") + optimized_col = "value_optimized" + no_optimized_col = "value_not_optimized" + + results = [] + for i, param_set in enumerate(product_dict(**param_arrays)): + if i % 1000 == 0: + logging.warning(f"{i} of {n_total} parameter combinations") try: - df_opt = ( - api.calculate(optimize_flh=True, **param_set)[0] - .rename(columns={"values": optimized_col}) + df_no_opt = ( + api.calculate(optimize_flh=False, **param_set)[0] + .rename(columns={"values": no_optimized_col}) .set_index(index_cols) ) - df = pd.concat( - [df_no_opt, df_opt], - axis=1, - ) + try: + df_opt = ( + api.calculate(optimize_flh=True, **param_set)[0] + .rename(columns={"values": optimized_col}) + .set_index(index_cols) + ) + df = pd.concat( + [df_no_opt, df_opt], + axis=1, + ) + except KeyError as e: + logging.error( + f"Not possible to caluclate optimization for param_set {param_set}" + ) + logging.error(f"KeyError: {e}") + df = df_no_opt.copy() + df[optimized_col] = np.nan + + if process_type_filter is not None: + df = df.loc[df.index.isin(process_type_filter, level="process_type"), :] + + results.append(df.reset_index()) + except KeyError as e: - logging.error( - f"Not possible to caluclate optimization for param_set {param_set}" - ) + logging.error(f"Not possible to caluclate param_set {param_set}") logging.error(f"KeyError: {e}") - df = df_no_opt.copy() - df[optimized_col] = np.nan + pass - results.append(df.reset_index()) + except AssertionError: + logging.error("AssertionError: invalid parameter combination") + pass - except KeyError as e: - logging.error(f"Not possible to caluclate param_set {param_set}") - logging.error(f"KeyError: {e}") - pass + results = pd.concat(results, axis=0, ignore_index=True) + results.to_csv( + out_file, + index=False, + ) + metadata_file = str(out_file) + "metadata.json" + metadata = param_arrays | {"process_type_filter": process_type_filter} + with open(metadata_file, mode="r", encoding="utf-8") as f: + json.dump(metadata, f, indent=2) - except AssertionError: - logging.error("AssertionError: invalid parameter combination") - pass + return results -results = pd.concat(results, axis=0, ignore_index=True) -results.to_csv("/home/j.aschauer/ptxboa_result_comparison/cost_comparison_output.csv") +@click.command() +@click.argument( + "out_file", + type=click.Path(file_okay=True, dir_okay=False, resolve_path=True, path_type=Path), +) +@click.option( + "--cache-dir", + "-c", + type=click.Path( + file_okay=False, + dir_okay=True, + exists=True, + readable=True, + resolve_path=True, + path_type=Path, + ), + default=DEFAULT_CACHE_DIR, +) +@click.option( + "--loglevel", + "-l", + type=click.Choice(["debug", "info", "warning", "error"], case_sensitive=False), + default="info", + show_default=True, +) +def cli(out_file: Path, cache_dir: Path, loglevel) -> None: + if out_file.exists(): + warn_msg = f"out_file exists:{out_file}" + confirm_msg = "Do you want to continue and overwrite the content in out_file?" + logging.warning(warn_msg) + if not click.confirm( + confirm_msg, + default=False, + ): + logging.info("stopping execution based on user input") + return None + + main( + out_file=out_file, + cache_dir=cache_dir, + loglevel=loglevel, + # settings we agreed on which make the results file small and give us + # relevant results only: + transport=["Ship"], + ship_own_fuel=[False], + secproc_water=["Specific costs"], + secproc_co2=["Specific costs"], + scenario="all", + country=["Germany"], + res_gen="all", + region="all", + chain="all", + process_type_filter=[ + "Derivate production", + "Electricity and H2 storage", + "Electricity generation", + "Electrolysis", + ], + ) + + +if __name__ == "__main__": + cli() From f8147909d17a1f6a2d365bcd400ad11a301c692d Mon Sep 17 00:00:00 2001 From: "j.aschauer" <38501948+joAschauer@users.noreply.github.com> Date: Wed, 8 May 2024 13:44:10 +0200 Subject: [PATCH 6/7] fix metadata write error --- scripts/compare_optimized_vs_old.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/compare_optimized_vs_old.py b/scripts/compare_optimized_vs_old.py index 1a64a6e0..baf05593 100644 --- a/scripts/compare_optimized_vs_old.py +++ b/scripts/compare_optimized_vs_old.py @@ -167,9 +167,9 @@ def main( out_file, index=False, ) - metadata_file = str(out_file) + "metadata.json" + metadata_file = str(out_file) + ".metadata.json" metadata = param_arrays | {"process_type_filter": process_type_filter} - with open(metadata_file, mode="r", encoding="utf-8") as f: + with open(metadata_file, mode="w", encoding="utf-8") as f: json.dump(metadata, f, indent=2) return results From f242fdb2ff3a5ef2a27e8743d36b953ab7b82f2d Mon Sep 17 00:00:00 2001 From: "j.aschauer" <38501948+joAschauer@users.noreply.github.com> Date: Wed, 8 May 2024 13:50:11 +0200 Subject: [PATCH 7/7] rename script --- ...re_optimized_vs_old.py => costs_optimized_vs_not_optimized.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{compare_optimized_vs_old.py => costs_optimized_vs_not_optimized.py} (100%) diff --git a/scripts/compare_optimized_vs_old.py b/scripts/costs_optimized_vs_not_optimized.py similarity index 100% rename from scripts/compare_optimized_vs_old.py rename to scripts/costs_optimized_vs_not_optimized.py