Skip to content

Commit

Permalink
fix how t&d are matched against consumption mix; addresses USEPA#237
Browse files Browse the repository at this point in the history
  • Loading branch information
dt-woods committed Mar 21, 2024
1 parent eccaa85 commit 1a160b6
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 40 deletions.
42 changes: 24 additions & 18 deletions electricitylci/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ def run_net_trade(generation_mix_dict):
end user within the named region with a 1 MWh of electricity as
its product flow.
"""
# Run ba_io_trading.
logging.info("using alt gen method for consumption mix")
regions_to_keep = list(generation_mix_dict.keys())
cons_mix_df_dict = get_consumption_mix_df(regions_to_keep=regions_to_keep)
Expand All @@ -564,17 +565,18 @@ def run_net_trade(generation_mix_dict):
cons_mix_dicts[subreg]
)

logging.info("get distribution mix")
logging.info("get t&d losses")
dist_mix_df_dict = {}
for subreg in cons_mix_dicts.keys():
dist_mix_df_dict[subreg] = get_distribution_mix_df(subregion=subreg)

# NOTE: fails to find 'New Smyrna Beach' and 'City of Homestead'
logging.info("write dist mix to dict")
dist_mix_dicts = {}
for subreg in dist_mix_df_dict.keys():
dist_mix_dicts[subreg] = write_distribution_mix_to_dict(
dist_mix_df_dict[subreg],
cons_mix_dicts[subreg],
dist_mix_df_dict,
cons_mix_dicts,
subregion=subreg
)

Expand All @@ -588,19 +590,22 @@ def run_net_trade(generation_mix_dict):


def run_post_processes():
# There is no easy way of editing files archived in a zip and no
# easy way of remove files from a zip without just creating a new zip,
# so that's what's done here.
# 1. FIXED. There should be only one instance of each .json file;
# addressed in the new _save_to_json (olca_jsonld_writer.py)
# 2. Remove flows/*.json that are not found in a process exchange.
# See cleanup SQL queries in GitHub issue
# https://github.com/USEPA/ElectricityLCI/issues/216
# 3. Remove zero flows from quantitative reference exchanges
# https://github.com/USEPA/ElectricityLCI/issues/217
# 4. Add NETL TRACI 2.1 characterization factors (impact category)
# NOT TO BE ADDED TO BASELINES
# 5. Create product systems for select processes (@user, consumption mixes)
"""Run post processes on JSON-LD file.
There is no easy way of editing files archived in a zip and no
easy way of remove files from a zip without just creating a new zip,
so that's what's done here.
1. There should be only one instance of each .json file;
addressed in the new _save_to_json (olca_jsonld_writer.py)
2. Remove flows/*.json that are not found in a process exchange.
See cleanup SQL queries in GitHub issue
https://github.com/USEPA/ElectricityLCI/issues/216
3. Remove zero flows from quantitative reference exchanges
https://github.com/USEPA/ElectricityLCI/issues/217
4. DO NOT ADD NETL TRACI 2.1 characterization factors
5. Create product systems for select processes (user, consumption mixes)
"""
from electricitylci.olca_jsonld_writer import build_product_systems
from electricitylci.olca_jsonld_writer import clean_json

Expand Down Expand Up @@ -640,14 +645,15 @@ def write_distribution_dict():
return distribution_mix_dictionary()


def write_distribution_mix_to_dict(dist_mix_df, gen_mix_dict, subregion=None):
def write_distribution_mix_to_dict(dm_dict, gm_dict, subregion=None):
import electricitylci.eia_trans_dist_grid_loss as tnd

if subregion is None:
subregion = config.model_specs.regional_aggregation

# HOTFIX: send full dicts to method, not region-specific [2024-03-21;TWD]
dist_mix_dict = tnd.olca_schema_distribution_mix(
dist_mix_df, gen_mix_dict, subregion=subregion
dm_dict, gm_dict, subregion=subregion
)
return dist_mix_dict

Expand Down
76 changes: 54 additions & 22 deletions electricitylci/eia_trans_dist_grid_loss.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,31 +251,61 @@ def generate_regional_grid_loss(year, subregion="all"):


def olca_schema_distribution_mix(td_by_region, cons_mix_dict, subregion="BA"):
"""Create dictionaries for openLCA"""
"""Create dictionaries for openLCA
Parameters
----------
td_by_region : dict
cons_mix_dict : dict
subregion : str
Returns
-------
dict
Notes
-----
This method was incorrectly using td_regions as the primary list of
balancing authority and FERC region names. It turns out this dataset
is not 100% matching with the regions that make up the processes in
cons_mix_dict; therefore, the cons_mix_dict regions should be the
region reference. These regions are searched within the correct subregion
data frame within td_by_region and, when not found, uses the US average.
"""
distribution_mix_dict = {}
if subregion == "all":
aggregation_column = "Subregion"
region = list(pd.unique(td_by_region[aggregation_column]))
elif subregion == "NERC":
aggregation_column = "NERC"
region = list(pd.unique(td_by_region[aggregation_column]))
elif subregion == "BA":
aggregation_column = "Balancing Authority Name"
region = list(pd.unique(td_by_region[aggregation_column]))
if subregion == "BA":
td_col = "Balancing Authority Name"
region = [
x.replace(" - BA", "") for x in cons_mix_dict[subregion].keys()]
elif subregion == "FERC":
aggregation_column = "FERC_Region"
region = list(pd.unique(td_by_region[aggregation_column]))
td_col = "FERC_Region"
region = [
x.replace(" - FERC", "") for x in cons_mix_dict[subregion].keys()]
else:
aggregation_column = None
td_col = None
subregion = "US"
region = ["US"]

for reg in region:
if aggregation_column is None:
database_reg = td_by_region
# Get the T&D losses for this region.
database_reg = td_by_region[subregion].copy()
if td_col is not None:
database_reg = database_reg.loc[database_reg[td_col] == reg, :]

if database_reg.empty:
logging.warning(
"Failed to find T&D losses for '%s', using US average." % reg)
td_val = td_by_region['US']['t_d_losses'].values[0]
elif len(database_reg) == 1:
td_val = database_reg['t_d_losses'].values[0]
else:
database_reg = td_by_region.loc[
td_by_region[aggregation_column] == reg, :
]
logging.warning(
"Found too many regions in T&D table for '%s'! "
"Using first value." % reg)
td_val = database_reg['t_d_losses'].values[0]

exchanges_list = []

# Creating the reference output
exchange(
ref_exchange_creator(electricity_flow=electricity_at_user_flow),
Expand All @@ -287,15 +317,17 @@ def olca_schema_distribution_mix(td_by_region, cons_mix_dict, subregion="BA"):
)
exchanges_list[1]["input"] = True
exchanges_list[1]["quantitativeReference"] = False
exchanges_list[1]["amount"] = 1 + database_reg["t_d_losses"].values[0]
exchanges_list[1]["amount"] = 1 + td_val

matching_dict = None
for cons_mix in cons_mix_dict:
for cons_mix in cons_mix_dict[subregion]:
if (
cons_mix_dict[cons_mix]["name"]
cons_mix_dict[subregion][cons_mix]["name"]
== f"Electricity; at grid; consumption mix - {reg} - {subregion}"
):
matching_dict = cons_mix_dict[cons_mix]
matching_dict = cons_mix_dict[subregion][cons_mix]
break

if matching_dict is None:
logging.warning(
f"Trouble matching dictionary for {reg}. "
Expand Down

0 comments on commit 1a160b6

Please sign in to comment.