Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 43 additions & 37 deletions prereise/gather/griddata/hifld/const.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
s_base = 100 # MVA
Comment thread
danielolsen marked this conversation as resolved.

mile_to_meter = 1609.34
meter_to_mile = 1.0 / mile_to_meter

Expand Down Expand Up @@ -125,43 +127,6 @@
"500": 500,
}

line_reactance_per_mile = { # per-unit
69: 0.0096,
100: 0.0063,
115: 0.0039,
138: 0.0026,
161: 0.0021,
230: 0.0011,
345: 0.0005,
500: 0.0002,
765: 0.0001,
}
line_rating_short = { # MVA
69: 86,
100: 181,
115: 239,
138: 382,
161: 446,
230: 797,
345: 1793,
500: 2598,
765: 5300,
}
line_rating_short_threshold = 50 # miles
line_rating_surge_impedance_loading = { # MVA
69: 13,
100: 30,
115: 35,
138: 50,
161: 69,
230: 140,
345: 375,
500: 1000,
765: 2250,
}
line_rating_surge_impedance_coefficient = 43.261
line_rating_surge_impedance_exponent = -0.6678

transformer_reactance = { # per-unit
(69, 115): 0.14242,
(69, 138): 0.10895,
Expand Down Expand Up @@ -629,6 +594,47 @@
"ERCOT": {305330},
}

line_voltage_assumptions = {
128842: 230,
}

line_design_assumptions = {
# branch index: (voltage, circuits, bundle count)
101536: (161, 2, 4), # TVA Cumberland (between substations)
103726: (161, 2, 4), # TVA Cumberland (plant to substation)
110220: (115, 1, 2), # Riverside Generating Station
112166: (230, 1, 2), # Waterford 3 Nuclear Generating Station
116493: (230, 1, 2), # Herbert A. Wagner Generating Station
132671: (230, 1, 3), # Florida Power & Light St. Lucie
130105: (161, 1, 3), # TVA Cumberland (downstream)
132804: (230, 1, 2), # Waterford 3 Nuclear Generating Station
139216: (230, 4, 3), # Catawba Nuclear Station
140651: (230, 1, 3), # Florida Power & Light St. Lucie
147054: (115, 1, 2), # RE Ginna Nuclear Power Plant
158263: (100, 1, 4), # G. G. Allen Steam Station
160723: (230, 1, 3), # Florida Power & Light St. Lucie
203381: (230, 1, 2), # Midpoint to Boise Bench
203382: (230, 1, 2), # Midpoint to Boise Bench
203383: (230, 1, 2), # Midpoint to Boise Bench
300029: (69, 2, 1), # Ormat Brawley geothermal
301320: (138, 2, 2), # Collin/Frisco substation connection
301847: (115, 1, 2), # Coso Power Station
303557: (138, 2, 2), # West Levee substations connection (Dallas)
304908: (69, 2, 1), # Heber geothermal
305018: (138, 2, 2), # TH Wharton Generating Station
305464: (230, 2, 2), # The Geysers
305990: (100, 2, 1), # southeast Salton Sea geothermal plants (several)
306949: (230, 2, 2), # The Geysers
307569: (230, 2, 2), # The Geysers
308434: (230, 2, 2), # The Geysers
309268: (69, 2, 1), # Ormat Brawley geothermal
309441: (69, 2, 2), # substation connection near Lake Creek Reservoir, outside Waco
309966: (138, 2, 2), # Garfield to Pilot Knob (south of Austin)
312241: (100, 2, 1), # southeast Salton Sea geothermal plants (several)
313473: (69, 2, 2), # Holtville geothermal?
313474: (69, 2, 2), # Holtville geothermal?
}

b2b_ratings = { # MW
"BLACKWATER TIE": 200, # a.k.a. 'Clovis'/'Roosevelt County' (Eastern/Western)
"EDDY AC-DC-AC TIE": 200, # a.k.a. 'Artesia' (Eastern/Western)
Expand Down
23 changes: 23 additions & 0 deletions prereise/gather/griddata/hifld/data/line_designs.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
voltage,circuits,bundle_count,conductor,spacing,a0x,a0y,b0x,b0y,c0x,c0y,a1x,a1y,b1x,b1y,c1x,c1y,a2x,a2y,b2x,b2y,c2x,c2y,a3x,a3y,b3x,b3y,c3x,c3y,notes
69,1,1,Osprey,,-2,16.5,2,15,-2,13.5,,,,,,,,,,,,,,,,,,,single-pole design
69,2,1,Osprey,,-2,16.5,-2,15,-2,13.5,2,13.5,2,15,2,16.5,,,,,,,,,,,,,single-pole double-circuit
69,2,2,Osprey,0.5,-2,16.5,-2,15,-2,13.5,2,13.5,2,15,2,16.5,,,,,,,,,,,,,single-pole double-circuit
100,1,1,Drake,,-2,19,2,17,-2,15,,,,,,,,,,,,,,,,,,,single-pole design
100,2,1,Drake,,-2,19,-2,17,-2,15,2,15,2,17,2,19,,,,,,,,,,,,,single-pole double-circuit
100,1,4,Drake,0.5,-7,15,0,15,7,15,,,,,,,,,,,,,,,,,,,H-frame design
115,1,1,Drake,,-2,19,2,17,-2,15,,,,,,,,,,,,,,,,,,,single-pole design
115,1,2,Drake,0.5,-4,15,0,15,4,15,,,,,,,,,,,,,,,,,,,H-frame design
138,1,1,Ortolan,,-3,22.5,3,20,-3,17.5,,,,,,,,,,,,,,,,,,,single-pole design
138,2,2,Ortolan,0.5,-7.5,15,-4.5,15,-1.5,15,1.5,15,4.5,15,7.5,15,,,,,,,,,,,,,two parallel H-frames
161,1,1,Bluejay,,-5,15,0,15,5,15,,,,,,,,,,,,,,,,,,,H-frame design
161,1,3,Bluejay,0.5,-6,15,0,15,6,15,,,,,,,,,,,,,,,,,,,lattice
161,2,4,Bluejay,0.5,-5,15,-5,17,-5,19,5,19,5,17,5,15,,,,,,,,,,,,,Two parallel single-poles
230,1,1,Falcon,,-7,20,0,20,7,20,,,,,,,,,,,,,,,,,,,H-frame design
230,1,2,Drake,0.5,-7,20,0,20,7,20,,,,,,,,,,,,,,,,,,,H-frame design
230,1,3,Drake,0.5,-7,20,0,20,7,20,,,,,,,,,,,,,,,,,,,H-frame design
230,2,2,Drake,0.5,-3,19,-3,17,-3,15,3,15,3,17,3,19,,,,,,,,,,,,,Double-circuit lattice
230,4,3,Drake,0.5,-7,20,0,20,7,20,18,20,25,20,32,20,43,20,50,20,57,20,68,20,75,20,82,20,Four parallel H-frames
345,1,2,Falcon,0.5,-8,25,0,25,8,25,,,,,,,,,,,,,,,,,,,H-frame design
500,1,3,Rail,0.5,-10,30,0,30,10,30,,,,,,,,,,,,,,,,,,,lattice
500,2,3,Drake,0.5,-5,40,-8,30,-5,20,5,20,8,30,5,40,,,,,,,,,,,,,lattice
765,1,4,Martin,0.5,-15,40,0,40,15,40,,,,,,,,,,,,,,,,,,,H-frame design
Comment on lines +1 to +23
Copy link
Copy Markdown
Collaborator

@BainanXia BainanXia Apr 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we mention the data source somewhere and/or do we need to do data-intake for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are self-created, based on compiling a variety of sources and rough assumptions, so I don't think we need to go through the data intake process. I'm going to write more about this in the paper describing our process. Do you think we need more documentation in the repo itself?

Copy link
Copy Markdown
Collaborator

@BainanXia BainanXia Apr 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. We will definitely put some paragraphs from the paper into the readme of the repo later and reference the paper for sure.

149 changes: 126 additions & 23 deletions prereise/gather/griddata/hifld/data_process/tests/test_transmission.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,87 @@
from unittest.mock import Mock

import pandas as pd
import pytest
from pandas.testing import assert_frame_equal, assert_series_equal

from prereise.gather.griddata.hifld import const
from prereise.gather.griddata.hifld.data_process.transmission import (
add_b2bs_to_dc_lines,
add_impedance_and_rating,
add_substation_info_to_buses,
assign_buses_to_lines,
augment_line_voltages,
create_buses,
create_transformers,
estimate_branch_impedance,
estimate_branch_rating,
filter_islands_and_connect_with_mst,
map_lines_to_substations_using_coords,
split_lines_to_ac_and_dc,
)


def test_add_b2bs_to_dc_lines():
dc_lines = pd.DataFrame(
{"SUB_1_ID": [1, 2], "SUB_2_ID": [3, 4], "Pmax": [5, 6]},
index=[200, 201],
)
substations = pd.DataFrame(
{"NAME": ["Wango_West", "Jango", "Wango_East", "Tango_South", "Tango_North"]}
)
b2b_ratings = {"Wango": 100, "Tango": 200}
expected_new_rows = pd.DataFrame(
{"SUB_1_ID": [0, 3], "SUB_2_ID": [2, 4], "Pmax": [100, 200]}, index=[300, 301]
)
add_b2bs_to_dc_lines(dc_lines, substations, b2b_ratings)
assert_frame_equal(dc_lines.iloc[2:], expected_new_rows)


def test_add_impedance_and_rating():
branch = pd.DataFrame(
{
"VOLTAGE": [69, 75, 75, 138],
"length": [10, 20, 100, 50],
"type": ["Line"] * 4,
}
)
expected_new_columns = pd.DataFrame(
{
"x": [0.0963365, 0.163066, 0.813330, 0.122386],
"rateA": [85.4507, 92.8812, 42.5257, 227.1693],
}
)
expected_modified_branch = pd.concat([branch, expected_new_columns], axis=1)
add_impedance_and_rating(branch, bus_voltages=None)
assert_frame_equal(branch, expected_modified_branch)


def test_add_substation_info_to_buses():
bus = pd.DataFrame({"sub_id": [0, 0, 1, 2]})
substations = pd.DataFrame(
{
"interconnect": ["Eastern", "Western", "Western", "Western", "ERCOT"],
"STATE": ["MT", "MT", "CA", "CA", "TX"],
}
)
zones = pd.DataFrame(
{
"state": ["Montana", "Montana", "California", "Texas"],
"interconnect": ["Western", "Eastern", "Western", "ERCOT"],
"zone_id": ["MT Western", "MT Eastern", "California", "TX ERCOT"],
}
)
expected_new_columns = pd.DataFrame(
{
"interconnect": ["Eastern", "Eastern", "Western", "Western"],
"zone_id": ["MT Eastern", "MT Eastern", "MT Western", "California"],
}
)
expected_bus = pd.concat([bus, expected_new_columns], axis=1)
add_substation_info_to_buses(bus, substations, zones)
assert_frame_equal(bus, expected_bus)


def test_augment_line_voltages_volt_class():
substations = pd.DataFrame({"STATE": ["CA", "OR", "NV", "WA"]})
lines_orig = pd.DataFrame(
Expand Down Expand Up @@ -125,15 +193,18 @@ def test_create_transformers():


def test_estimate_branch_impedance_lines():
resistance = 0.01
reactance = 0.1
fake_lines = [Mock(series_impedance=(resistance + 1j * reactance))] * 3
branch = pd.DataFrame(
{"VOLTAGE": [69, 70, 345], "type": ["Line"] * 3, "length": [10, 15, 20]}
{"VOLTAGE": [69, 70, 345], "type": ["Line"] * 3, "line_object": fake_lines}
)
x = estimate_branch_impedance(branch.iloc[0], pd.Series())
assert x == const.line_reactance_per_mile[69] * 10
assert x == reactance / (69**2 / const.s_base)
x = estimate_branch_impedance(branch.iloc[1], pd.Series())
assert x == const.line_reactance_per_mile[69] * 15
assert x == reactance / (70**2 / const.s_base)
x = estimate_branch_impedance(branch.iloc[2], pd.Series())
assert x == const.line_reactance_per_mile[345] * 20
assert x == reactance / (345**2 / const.s_base)


def test_estimate_branch_impedance_transformers():
Expand All @@ -150,45 +221,66 @@ def test_estimate_branch_impedance_transformers():


def test_estimate_branch_rating_lines():
fake_ratings = pd.Series([10, 20, 30, 40])
fake_thermal_ratings = pd.Series([100, 200, 300, 400])
fake_lines = [Mock(power_rating=i) for i in fake_ratings]
branch = pd.DataFrame(
{
"VOLTAGE": [69, 140, 345, 499],
"type": ["Line"] * 4,
"length": [10, 50, 100, 150],
"line_object": fake_lines,
}
)
rating = estimate_branch_rating(branch.iloc[0], pd.Series())
assert rating == const.line_rating_short[69]
rating = estimate_branch_rating(branch.iloc[1], pd.Series())
assert rating == const.line_rating_short[138]
rating = estimate_branch_rating(branch.iloc[2], pd.Series())
assert rating == (
const.line_rating_surge_impedance_loading[345]
* const.line_rating_surge_impedance_coefficient
* 100**const.line_rating_surge_impedance_exponent
)
rating = estimate_branch_rating(branch.iloc[3], pd.Series())
assert rating == (
const.line_rating_surge_impedance_loading[500]
* const.line_rating_surge_impedance_coefficient
* 150**const.line_rating_surge_impedance_exponent
assert_series_equal(
fake_ratings,
branch.apply(estimate_branch_rating, args=[None, fake_thermal_ratings], axis=1),
)


def test_estimate_branch_rating_transformers():
thermal_ratings = pd.Series([100, 550, 1655, 2585], index=[69, 230, 345, 500])
transformers = pd.DataFrame(
{"from_bus_id": [0, 1, 2], "to_bus_id": [1, 2, 3], "type": ["Transformer"] * 3}
)
bus_voltages = pd.Series([69, 230, 350, 500])

rating = estimate_branch_rating(transformers.iloc[0], bus_voltages)
rating = estimate_branch_rating(transformers.iloc[0], bus_voltages, thermal_ratings)
assert rating == const.transformer_rating
rating = estimate_branch_rating(transformers.iloc[1], bus_voltages)
rating = estimate_branch_rating(transformers.iloc[1], bus_voltages, thermal_ratings)
assert rating == const.transformer_rating * 3
rating = estimate_branch_rating(transformers.iloc[2], bus_voltages)
rating = estimate_branch_rating(transformers.iloc[2], bus_voltages, thermal_ratings)
assert rating == const.transformer_rating * 4


def test_filter_islands_and_connect_with_mst():
lines = pd.DataFrame(
{
"SUB_1_ID": ["Seattle", "Oakland", "Chicago"],
"SUB_2_ID": ["Oakland", "Las Vegas", "New York"],
}
)
substations = pd.DataFrame(
{
"LATITUDE": [47.60, 37.81, 36.17, 41.89, 40.71],
"LONGITUDE": [-122.34, -122.26, -115.14, -87.63, -74.00],
"STATE": ["WA", "CA", "NV", "IL", "NY"],
},
index=["Seattle", "Oakland", "Las Vegas", "Chicago", "New York"],
)
state_neighbor = {
"CA": ["WA", "NV"],
"IL": ["NV", "NY"],
"NV": ["CA", "IL", "NY", "WA"],
"NY": ["IL", "NV"],
"WA": ["CA", "NV"],
}
new_lines, new_substations = filter_islands_and_connect_with_mst(
lines, substations, state_neighbor=state_neighbor
)
assert len(new_lines) == len(lines) + 1
assert set(new_lines.iloc[-1][["SUB_1_ID", "SUB_2_ID"]]) == {"Chicago", "Las Vegas"}


def test_map_lines_to_substations_using_coords():
substations = pd.DataFrame(
{
Expand Down Expand Up @@ -250,3 +342,14 @@ def test_assign_buses_to_lines():
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]))


def test_split_lines_to_ac_and_dc():
lines = pd.DataFrame(
{"TYPE": ["DC; OVERHEAD", "DC; UNDERGROUND", "AC", "AC", "unknown", "unknown"]},
index=[101, 102, 103, 104, 105, 106],
)
dc_override_indices = {105}
ac_lines, dc_lines = split_lines_to_ac_and_dc(lines, dc_override_indices)
assert ac_lines.index.tolist() == [103, 104, 106]
assert dc_lines.index.tolist() == [101, 102, 105]
Loading