From 7c1c0a392b93f04a1a9797fb7d299d49a47f71ea Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Wed, 27 Oct 2021 10:23:31 -0700 Subject: [PATCH 01/10] chore: add default column values for PowerSimData table outputs --- prereise/gather/griddata/hifld/const.py | 83 +++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/prereise/gather/griddata/hifld/const.py b/prereise/gather/griddata/hifld/const.py index 2fb656474..3d98f146f 100644 --- a/prereise/gather/griddata/hifld/const.py +++ b/prereise/gather/griddata/hifld/const.py @@ -536,3 +536,86 @@ } interconnect_size_rank = ["Eastern", "Western", "ERCOT"] + +powersimdata_column_defaults = { + "branch": { + "r": 0, + "b": 0, + "ratio": 0, + "rateB": 0, + "rateC": 0, + "angle": 0, + "status": 1, + "angmin": 0, + "angmax": 0, + "Pf": 0, + "Qf": 0, + "Pt": 0, + "Qt": 0, + "mu_Sf": 0, + "mu_St": 0, + "mu_angmin": 0, + "mu_angmax": 0, + }, + "bus": { + "type": 1, + "Qd": 0, + "Gs": 0, + "Bs": 0, + "Vm": 1, + "Va": 0, + "loss_zone": 1, + "Vmax": 1.1, + "Vmin": 0.9, + "lam_P": 0, + "lam_Q": 0, + "mu_Vmax": 0, + "mu_Vmin": 0, + }, + "dcline": { + "status": 1, + "Pf": 0, + "Pt": 0, + "Qf": 0, + "Qt": 0, + "Vf": 1, + "Vt": 1, + "QminF": 0, + "QmaxF": 0, + "QminT": 0, + "QmaxT": 0, + "loss0": 0, + "loss1": 0, + "muPmin": 0, + "muPmax": 0, + "muQminF": 0, + "muQmaxF": 0, + "muQminT": 0, + "muQmaxT": 0, + }, + "gencost": {"type": 2, "startup": 0, "shutdown": 0, "n": 3}, + "plant": { + "Pg": 0, + "Qg": 0, + "Qmax": 0, + "Qmin": 0, + "Vg": 1, + "mBase": 1000, + "status": 1, + "Pc1": 0, + "Pc2": 0, + "Qc1min": 0, + "Qc1max": 0, + "Qc2min": 0, + "Qc2max": 0, + "ramp_agc": 0, + "ramp_10": 0, + "ramp_30": 0, + "ramp_q": 0, + "apf": 0, + "mu_Pmax": 0, + "mu_Pmin": 0, + "mu_Qmax": 0, + "mu_Qmin": 0, + }, +} From 9f875640c6ac4363371fa333c7397d45d27efd91 Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Fri, 19 Nov 2021 14:16:54 -0800 Subject: [PATCH 02/10] chore: rename ERCOT interconnect in zone.csv, condense Eastern/Texas zones --- prereise/gather/griddata/hifld/data/zone.csv | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/prereise/gather/griddata/hifld/data/zone.csv b/prereise/gather/griddata/hifld/data/zone.csv index 4eb618108..f8f9eb08f 100644 --- a/prereise/gather/griddata/hifld/data/zone.csv +++ b/prereise/gather/griddata/hifld/data/zone.csv @@ -45,13 +45,12 @@ zone_id,zone_name,state,interconnect,time_zone 44,South Dakota Western,South Dakota,Western,ETC/GMT+6 45,Tennessee,Tennessee,Eastern,ETC/GMT+6 46,Texas Eastern,Texas,Eastern,ETC/GMT+6 -47,Texas Panhandle,Texas,Eastern,ETC/GMT+6 -48,ERCOT,Texas,Texas,ETC/GMT+6 -49,El Paso,Texas,Western,ETC/GMT+7 -50,Utah,Utah,Western,ETC/GMT+7 -51,Virginia,Virginia,Eastern,ETC/GMT+5 -52,Vermont,Vermont,Eastern,ETC/GMT+5 -53,Washington,Washington,Western,ETC/GMT+8 -54,Wisconsin,Wisconsin,Eastern,ETC/GMT+6 -55,West Virginia,West Virginia,Eastern,ETC/GMT+5 -56,Wyoming,Wyoming,Western,ETC/GMT+7 +47,ERCOT,Texas,ERCOT,ETC/GMT+6 +48,El Paso,Texas,Western,ETC/GMT+7 +49,Utah,Utah,Western,ETC/GMT+7 +50,Virginia,Virginia,Eastern,ETC/GMT+5 +51,Vermont,Vermont,Eastern,ETC/GMT+5 +52,Washington,Washington,Western,ETC/GMT+8 +53,Wisconsin,Wisconsin,Eastern,ETC/GMT+6 +54,West Virginia,West Virginia,Eastern,ETC/GMT+5 +55,Wyoming,Wyoming,Western,ETC/GMT+7 From a94cb03d1b0783d29cfc66e2d7ceb31ab285aecd Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Sun, 21 Nov 2021 17:47:48 -0800 Subject: [PATCH 03/10] feat: add top-level orchestration function --- prereise/gather/griddata/hifld/__init__.py | 1 + .../hifld/data_process/transmission.py | 3 + .../gather/griddata/hifld/orchestration.py | 60 +++++++++++++++++++ 3 files changed, 64 insertions(+) create mode 100644 prereise/gather/griddata/hifld/orchestration.py diff --git a/prereise/gather/griddata/hifld/__init__.py b/prereise/gather/griddata/hifld/__init__.py index e69de29bb..1d189e74e 100644 --- a/prereise/gather/griddata/hifld/__init__.py +++ b/prereise/gather/griddata/hifld/__init__.py @@ -0,0 +1 @@ +from prereise.gather.griddata.hifld.orchestration import create_csvs # noqa: F401 diff --git a/prereise/gather/griddata/hifld/data_process/transmission.py b/prereise/gather/griddata/hifld/data_process/transmission.py index 125d8010f..c5368b524 100644 --- a/prereise/gather/griddata/hifld/data_process/transmission.py +++ b/prereise/gather/griddata/hifld/data_process/transmission.py @@ -758,4 +758,7 @@ def build_transmission(method="line2sub", **kwargs): lambda x: estimate_branch_rating(x, bus["baseKV"]), axis=1 ) + # Rename columns to match PowerSimData expectations + branch.rename({"type": "branch_device_type"}, axis=1, inplace=True) + return branch, bus, substations, dc_lines diff --git a/prereise/gather/griddata/hifld/orchestration.py b/prereise/gather/griddata/hifld/orchestration.py new file mode 100644 index 000000000..05fd47106 --- /dev/null +++ b/prereise/gather/griddata/hifld/orchestration.py @@ -0,0 +1,60 @@ +import os +import shutil + +from powersimdata.input import const as psd_const + +from prereise.gather.griddata.hifld.const import powersimdata_column_defaults +from prereise.gather.griddata.hifld.data_process.demand import assign_demand_to_buses +from prereise.gather.griddata.hifld.data_process.generators import build_plant +from prereise.gather.griddata.hifld.data_process.transmission import build_transmission + + +def create_csvs(output_folder): + """Process HIFLD source data to CSVs compatible with PowerSimData. + + :param str output_folder: directory to write CSVs to. + """ + # Process grid data from original sources + branch, bus, substation, dcline = build_transmission() + plant = build_plant(bus, substation) + assign_demand_to_buses(substation, branch, plant, bus) + + outputs = {} + outputs["branch"] = branch + outputs["dcline"] = dcline + outputs["sub"] = substation + # Separate tables as necessary to match PowerSimData format + # bus goes to bus and bus2sub + outputs["bus2sub"] = bus[["sub_id", "interconnect"]] + outputs["bus"] = bus.drop(["sub_id"], axis=1) + # plant goes to plant and gencost + outputs["gencost"] = plant[["c0", "c1", "c2", "interconnect"]].copy() + outputs["plant"] = plant.drop(["c0", "c1", "c2"], axis=1) + + # Fill in missing column values + for name, defaults in powersimdata_column_defaults.items(): + outputs[name] = outputs[name].assign(**defaults) + + # Filter to only the columns expected by PowerSimData, in the expected order + for name, df in outputs.items(): + col_names = getattr(psd_const, f"col_name_{name}") + if name == "bus": + # The bus column names in PowerSimData include the index for legacy reasons + col_names = col_names[1:] + if name == "branch": + col_names += ["branch_device_type"] + if name == "plant": + col_names += ["type", "GenFuelCost", "GenIOB", "GenIOC", "GenIOD"] + if name == "dcline": + col_names += ["from_interconnect", "to_interconnect"] + else: + col_names += ["interconnect"] + outputs[name] = outputs[name][col_names] + + # Save files + os.makedirs(output_folder, exist_ok=True) + for name, df in outputs.items(): + df.to_csv(os.path.join(output_folder, f"{name}.csv")) + # The zone file gets copied directly + zone_path = os.path.join(os.path.dirname(__file__), "data", "zone.csv") + shutil.copyfile(zone_path, os.path.join(output_folder, "zone.csv")) From 3807fb4c2e8fadbef6247358503bc66930bbfa2a Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Fri, 19 Nov 2021 12:00:24 -0800 Subject: [PATCH 04/10] feat: add function to translate substation mapping to bus mapping --- .../data_process/tests/test_transmission.py | 25 ++++++++++++++++ .../hifld/data_process/transmission.py | 30 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/prereise/gather/griddata/hifld/data_process/tests/test_transmission.py b/prereise/gather/griddata/hifld/data_process/tests/test_transmission.py index c23520743..23b2782d0 100644 --- a/prereise/gather/griddata/hifld/data_process/tests/test_transmission.py +++ b/prereise/gather/griddata/hifld/data_process/tests/test_transmission.py @@ -4,6 +4,7 @@ from prereise.gather.griddata.hifld import const from prereise.gather.griddata.hifld.data_process.transmission import ( + assign_buses_to_lines, augment_line_voltages, create_buses, create_transformers, @@ -102,6 +103,7 @@ def test_create_buses(): "baseKV": [69, 345, 69, 115, 115, 230, 345, 230], }, ) + expected_return.index.name = "bus_id" expected_return["baseKV"] = expected_return["baseKV"].astype(float) bus = create_buses(lines) assert_frame_equal(bus, expected_return) @@ -225,3 +227,26 @@ def test_map_lines_to_substations_using_coords(): assert len(new_substations) == 2 assert all(o is None for o in new_substations["OTHER_SUB"]) + + +def test_assign_buses_to_lines(): + bus = pd.DataFrame( + { + "baseKV": [115, 115, 230, 230, 345, 345], + "sub_id": [30, 31, 31, 32, 40, 41], + }, + index=pd.Index([300, 310, 311, 320, 400, 410], name="bus_id"), + ) + ac_lines = pd.DataFrame( + { + "SUB_1_ID": [30, 32, 40], + "SUB_2_ID": [31, 31, 41], + "VOLTAGE": [115, 230, 345], + } + ) + dc_lines = pd.DataFrame({"SUB_1_ID": [31], "SUB_2_ID": [40]}) + assign_buses_to_lines(ac_lines, dc_lines, bus) + assert ac_lines["from_bus_id"].equals(pd.Series([300, 320, 400])) + assert ac_lines["to_bus_id"].equals(pd.Series([310, 311, 410])) + assert dc_lines["from_bus_id"].equals(pd.Series([311])) + assert dc_lines["to_bus_id"].equals(pd.Series([400])) diff --git a/prereise/gather/griddata/hifld/data_process/transmission.py b/prereise/gather/griddata/hifld/data_process/transmission.py index c5368b524..075756888 100644 --- a/prereise/gather/griddata/hifld/data_process/transmission.py +++ b/prereise/gather/griddata/hifld/data_process/transmission.py @@ -502,6 +502,7 @@ def create_buses(lines): buses = buses.astype(float) buses.index.name = "sub_id" buses = buses.to_frame(name="baseKV").reset_index() + buses.index.name = "bus_id" return buses @@ -654,6 +655,34 @@ def add_b2bs_to_dc_lines(dc_lines, substations, b2b_ratings): dc_lines.loc[first_new_id + i] = pd.Series(info) +def assign_buses_to_lines(ac_lines, dc_lines, bus): + """Map substation IDs to bus IDs for AC & DC lines. Within the ``bus`` table, each + unique 'sub_id' should have one bus per connected voltage level; AC lines map + uniquely based on their 'VOLTAGE' attribute, while DC lines are mapped to the + highest-voltage bus within each substation. Both are modified inplace. + + :param pandas.DataFrame ac_lines: data frame containing at least + 'SUB_1_ID' and 'SUB_2_ID' columns. + :param pandas.DataFrame dc_lines: data frame containing at least + 'SUB_1_ID' and 'SUB_2_ID' columns. + :param pandas.DataFrame bus: data frame containing at least 'sub_id' and 'baseKV' + columns, with an index named 'bus_id'. + """ + # Create pandas Series that can be used for quick lookups + reindexed = bus.reset_index() + sub_and_voltage_to_bus = reindexed.set_index(["sub_id", "baseKV"])["bus_id"] + highest_voltage = reindexed.sort_values("baseKV").groupby("sub_id").last()["bus_id"] + # Use mappings to fill bus IDs + ac_lines["from_bus_id"] = ac_lines.apply( + lambda x: sub_and_voltage_to_bus.loc[(x["SUB_1_ID"], x["VOLTAGE"])], axis=1 + ) + ac_lines["to_bus_id"] = ac_lines.apply( + lambda x: sub_and_voltage_to_bus.loc[(x["SUB_2_ID"], x["VOLTAGE"])], axis=1 + ) + dc_lines["from_bus_id"] = dc_lines["SUB_1_ID"].map(highest_voltage) + dc_lines["to_bus_id"] = dc_lines["SUB_2_ID"].map(highest_voltage) + + def build_transmission(method="line2sub", **kwargs): """Build transmission network @@ -742,6 +771,7 @@ def build_transmission(method="line2sub", **kwargs): # Create buses from lines bus = create_buses(ac_lines) + assign_buses_to_lines(ac_lines, dc_lines, bus) # Add transformers, and calculate rating and impedance for all branches transformers = create_transformers(bus) From 307ce5ce684987cf8b0965638dc62f8530bee46e Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Fri, 19 Nov 2021 14:17:15 -0800 Subject: [PATCH 05/10] feat: add function to add zone IDs, interconnects to buses --- .../hifld/data_process/transmission.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/prereise/gather/griddata/hifld/data_process/transmission.py b/prereise/gather/griddata/hifld/data_process/transmission.py index 075756888..5b7949e2e 100644 --- a/prereise/gather/griddata/hifld/data_process/transmission.py +++ b/prereise/gather/griddata/hifld/data_process/transmission.py @@ -683,6 +683,26 @@ def assign_buses_to_lines(ac_lines, dc_lines, bus): dc_lines["to_bus_id"] = dc_lines["SUB_2_ID"].map(highest_voltage) +def add_substation_info_to_buses(bus, substations, zones): + """Using information looked up from substations and defined zones, add 'zone_id' and + 'interconnect' columns to the ``bus`` table (modified in-place). + + :param pandas.DataFrame bus: table of bus data, including 'sub_id' column. + :param pandas.DataFrame substations: table of substation data, including 'STATE' and + 'interconnect' columns. + :param pandas.DataFrame zones: table of zone data, including 'state' and + 'interconnect' columns, with an index named 'zone_id'. + """ + zone_lookup = zones.reset_index().set_index(["state", "interconnect"])["zone_id"] + zone_lookup.sort_index(inplace=True) # unsorted MultiIndices have poor performance + states = bus["sub_id"].map(substations["STATE"]).map(const.abv2state) + bus["interconnect"] = bus["sub_id"].map(substations["interconnect"]) + bus["zone_id"] = bus.apply( + lambda x: zone_lookup.loc[(states.loc[x.name], x.interconnect)], + axis=1, + ) + + def build_transmission(method="line2sub", **kwargs): """Build transmission network @@ -772,6 +792,7 @@ def build_transmission(method="line2sub", **kwargs): # Create buses from lines bus = create_buses(ac_lines) assign_buses_to_lines(ac_lines, dc_lines, bus) + add_substation_info_to_buses(bus, substations, hifld_zones) # Add transformers, and calculate rating and impedance for all branches transformers = create_transformers(bus) From e80a9cf11138512f8c773fd396e1f9b83d632d68 Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Sun, 21 Nov 2021 17:47:31 -0800 Subject: [PATCH 06/10] feat: use substation interconnect info to label DC lines and transformers --- prereise/gather/griddata/hifld/data_process/transmission.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prereise/gather/griddata/hifld/data_process/transmission.py b/prereise/gather/griddata/hifld/data_process/transmission.py index 5b7949e2e..d30b3521e 100644 --- a/prereise/gather/griddata/hifld/data_process/transmission.py +++ b/prereise/gather/griddata/hifld/data_process/transmission.py @@ -783,6 +783,9 @@ def build_transmission(method="line2sub", **kwargs): const.line_interconnect_assumptions, const.interconnect_size_rank, ) + # use substation interconnects to label DC lines + dc_lines["from_interconnect"] = dc_lines.SUB_1_ID.map(substations.interconnect) + dc_lines["to_interconnect"] = dc_lines.SUB_2_ID.map(substations.interconnect) # Now that substations are split across interconnects, we can add B2B facilities add_b2bs_to_dc_lines(dc_lines, substations, const.b2b_ratings) @@ -797,6 +800,7 @@ def build_transmission(method="line2sub", **kwargs): # Add transformers, and calculate rating and impedance for all branches transformers = create_transformers(bus) transformers["type"] = "Transformer" + transformers["interconnect"] = transformers["from_bus_id"].map(bus["interconnect"]) first_new_id = ac_lines.index.max() + 1 transformers.index = pd.RangeIndex(first_new_id, first_new_id + len(transformers)) ac_lines["type"] = "Line" From 22edb9c99fa001dbd82fabc76f3e2e1710840168 Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Fri, 19 Nov 2021 15:28:35 -0800 Subject: [PATCH 07/10] refactor: rename substation columns to PowerSimData expectations --- prereise/gather/griddata/hifld/data_process/generators.py | 2 +- prereise/gather/griddata/hifld/data_process/transmission.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/prereise/gather/griddata/hifld/data_process/generators.py b/prereise/gather/griddata/hifld/data_process/generators.py index 8fecb9161..2559a72e1 100644 --- a/prereise/gather/griddata/hifld/data_process/generators.py +++ b/prereise/gather/griddata/hifld/data_process/generators.py @@ -66,7 +66,7 @@ def map_generator_to_sub_by_location(generator, substation_groupby): # If no matching subs within the given interconnection and ZIPs, give up return pd.NA distance_to_subs = matching_subs.apply( - lambda x: haversine((x.LATITUDE, x.LONGITUDE), (generator.lat, generator.lon)), + lambda x: haversine((x.lat, x.lon), (generator.lat, generator.lon)), axis=1, ) return distance_to_subs.idxmin() diff --git a/prereise/gather/griddata/hifld/data_process/transmission.py b/prereise/gather/griddata/hifld/data_process/transmission.py index d30b3521e..8a7da6ed3 100644 --- a/prereise/gather/griddata/hifld/data_process/transmission.py +++ b/prereise/gather/griddata/hifld/data_process/transmission.py @@ -815,5 +815,10 @@ def build_transmission(method="line2sub", **kwargs): # Rename columns to match PowerSimData expectations branch.rename({"type": "branch_device_type"}, axis=1, inplace=True) + substations.rename( + {"NAME": "name", "LATITUDE": "lat", "LONGITUDE": "lon"}, axis=1, inplace=True + ) + substations["interconnect_sub_id"] = substations.groupby("interconnect").cumcount() + substations.index.name = "sub_id" return branch, bus, substations, dc_lines From 4ce230269798e18788e933cceac2b847baa32f3f Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Fri, 19 Nov 2021 16:48:12 -0800 Subject: [PATCH 08/10] refactor: drop generators whose substations can't be found --- prereise/gather/griddata/hifld/data_process/generators.py | 1 + 1 file changed, 1 insertion(+) diff --git a/prereise/gather/griddata/hifld/data_process/generators.py b/prereise/gather/griddata/hifld/data_process/generators.py index 2559a72e1..d4609db8d 100644 --- a/prereise/gather/griddata/hifld/data_process/generators.py +++ b/prereise/gather/griddata/hifld/data_process/generators.py @@ -334,4 +334,5 @@ def build_plant(bus, substations, kwargs={}): for i in range(3): generators[f"c{i}"] = generators[f"h{i}"] * generators["GenFuelCost"].fillna(0) + generators = generators.loc[~generators["bus_id"].isna()] return generators From 4f4cffaf238ac12f9fe56dcd95aaca16c190d230 Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Mon, 22 Nov 2021 14:35:25 -0800 Subject: [PATCH 09/10] refactor: rename generator columns to match PowerSimData expectations --- .../gather/griddata/hifld/data_process/generators.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/prereise/gather/griddata/hifld/data_process/generators.py b/prereise/gather/griddata/hifld/data_process/generators.py index d4609db8d..280898e18 100644 --- a/prereise/gather/griddata/hifld/data_process/generators.py +++ b/prereise/gather/griddata/hifld/data_process/generators.py @@ -334,5 +334,13 @@ def build_plant(bus, substations, kwargs={}): for i in range(3): generators[f"c{i}"] = generators[f"h{i}"] * generators["GenFuelCost"].fillna(0) - generators = generators.loc[~generators["bus_id"].isna()] + generators = generators.loc[~generators["bus_id"].isna()].copy() + # Rename columns (or add as necessary) to match PowerSimData expectations + generators.rename( + {"Energy Source 1": "type", "h1": "GenIOB", "h2": "GenIOC"}, + axis=1, + inplace=True, + ) + generators["GenIOD"] = 0 + return generators From 13e9e6cdced9a7ee9d1cccadcc7f5ca658511f6e Mon Sep 17 00:00:00 2001 From: Daniel Olsen Date: Mon, 22 Nov 2021 16:16:34 -0800 Subject: [PATCH 10/10] refactor: rename generator types to match PowerSimData expectations --- prereise/gather/griddata/hifld/const.py | 20 +++++++++++++++++++ .../griddata/hifld/data_process/generators.py | 1 + 2 files changed, 21 insertions(+) diff --git a/prereise/gather/griddata/hifld/const.py b/prereise/gather/griddata/hifld/const.py index 3d98f146f..55e802cbe 100644 --- a/prereise/gather/griddata/hifld/const.py +++ b/prereise/gather/griddata/hifld/const.py @@ -349,6 +349,26 @@ "WC": 2.02, # Waste Coal } +fuel_translations = { + "BIT": "coal", + "DFO": "dfo", + "GEO": "geothermal", + "JF": "dfo", + "KER": "dfo", + "LIG": "coal", + "NG": "ng", + "NUC": "nuclear", + "PC": "coal", + "PG": "ng", + "RC": "coal", + "RFO": "dfo", + "SUB": "coal", + "SUN": "solar", + "WAT": "hydro", + "WC": "coal", + "WND": "wind", +} + # Values from EPA's Power Sector Modeling Platform v6 - Summer 2021 Reference Case reasonable_heat_rates_size_cutoffs = { ("Natural Gas Fired Combustion Turbine", "GT"): 80, diff --git a/prereise/gather/griddata/hifld/data_process/generators.py b/prereise/gather/griddata/hifld/data_process/generators.py index 280898e18..c181c801f 100644 --- a/prereise/gather/griddata/hifld/data_process/generators.py +++ b/prereise/gather/griddata/hifld/data_process/generators.py @@ -341,6 +341,7 @@ def build_plant(bus, substations, kwargs={}): axis=1, inplace=True, ) + generators["type"] = generators["type"].replace(const.fuel_translations) generators["GenIOD"] = 0 return generators