Skip to content

Commit 9aa7d44

Browse files
authored
Merge pull request #95 from staadecker/hydro_scenario
Add hydro scenarios to database
2 parents 805641b + ad656fe commit 9aa7d44

File tree

3 files changed

+277
-0
lines changed

3 files changed

+277
-0
lines changed
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""
2+
####################
3+
Create a low hydro scenario
4+
5+
Date applied: 2021-07-29
6+
Description:
7+
This script adds a scenario to the database for low hydro power.
8+
The worst year for hydro is 2015. As such we use those values for every year unless a plant is missing
9+
in 2015 in which case we use the lowest value in the other years for that plant.
10+
#################
11+
"""
12+
import time
13+
14+
from switch_model.utilities import query_yes_no, format_seconds
15+
from switch_model.wecc.utilities import connect
16+
import pandas as pd
17+
18+
raw_data_scenario = 21
19+
all_plants_scenario = 23
20+
worst_year = 2015
21+
22+
new_start_year = 2020
23+
new_end_year = 2050
24+
new_scenario_id = 24
25+
new_scenario_name = "Lowest year (2015) repeated. Using EIA and AMPL Canada and Mex data."
26+
new_scenario_description = "Lowest year (2015) repeated from 2020 to 2050, based on data from id 21 (EIA + AMPL Canada & Mex)."
27+
28+
29+
def main():
30+
db_conn = connect()
31+
db_cursor = db_conn.cursor()
32+
33+
# 1. Get all the hydro plants
34+
db_cursor.execute(
35+
f"""
36+
SELECT DISTINCT generation_plant_id FROM hydro_historical_monthly_capacity_factors
37+
WHERE hydro_simple_scenario_id={all_plants_scenario};
38+
""")
39+
hydro_plants = pd.DataFrame(db_cursor.fetchall(), columns=["generation_plant_id"])["generation_plant_id"]
40+
41+
# 2. Get all the hydro flow data for the worst year
42+
db_cursor.execute(
43+
f"""
44+
SELECT generation_plant_id, month, hydro_min_flow_mw, hydro_avg_flow_mw FROM hydro_historical_monthly_capacity_factors
45+
WHERE hydro_simple_scenario_id={raw_data_scenario} and year={worst_year};
46+
""")
47+
worst_year_data = pd.DataFrame(db_cursor.fetchall(),
48+
columns=["generation_plant_id", "month", "hydro_min_flow_mw", "hydro_avg_flow_mw"])
49+
50+
# 3. Identify plants where data is missing
51+
missing_hydro_plants = hydro_plants[~hydro_plants.isin(worst_year_data["generation_plant_id"])].values
52+
53+
# 4. For each missing plant get the data for all the years
54+
db_cursor.execute(
55+
f"""
56+
SELECT generation_plant_id, year, month, hydro_min_flow_mw, hydro_avg_flow_mw FROM hydro_historical_monthly_capacity_factors
57+
WHERE hydro_simple_scenario_id={raw_data_scenario} and generation_plant_id in ({",".join(missing_hydro_plants.astype(str))});
58+
""")
59+
missing_plants_data = pd.DataFrame(db_cursor.fetchall(),
60+
columns=["generation_plant_id", "year", "month", "hydro_min_flow_mw",
61+
"hydro_avg_flow_mw"])
62+
63+
# 5. Pick the year with the least flow
64+
# Aggregate by year
65+
missing_data_by_year = missing_plants_data.groupby(["generation_plant_id", "year"], as_index=False)[
66+
"hydro_avg_flow_mw"].mean()
67+
# Select years where the flow is at its lowest
68+
year_to_use = \
69+
missing_data_by_year.loc[missing_data_by_year.groupby("generation_plant_id")["hydro_avg_flow_mw"].idxmin()][
70+
["generation_plant_id", "year"]]
71+
# Essentially filter missing_plants_data to only include keys from the right table, aka plants and years that are lowest
72+
missing_plants_data = missing_plants_data.merge(
73+
year_to_use,
74+
on=["generation_plant_id", "year"],
75+
how="right"
76+
).drop("year", axis=1)
77+
78+
# 6. Add the missing data to our worst year data and verify we have data for all the plants
79+
worst_year_data = pd.concat([worst_year_data, missing_plants_data])
80+
assert all(hydro_plants.isin(worst_year_data["generation_plant_id"]))
81+
82+
# 7. Cross join the series with all the years from 2020 to 2050
83+
years = pd.Series(range(new_start_year, new_end_year + 1), name="year")
84+
worst_year_data = worst_year_data.merge(
85+
years,
86+
how="cross"
87+
)
88+
worst_year_data["hydro_simple_scenario_id"] = new_scenario_id
89+
90+
# 8. Complete some data checks
91+
assert len(worst_year_data) == 12 * (new_end_year - new_start_year + 1) * len(hydro_plants)
92+
93+
# 9. Add data to database
94+
print(f"hydro_simple_scenario: {new_scenario_id}")
95+
print(f"name: {new_scenario_name}")
96+
print(f"description: {new_scenario_description}")
97+
print(f"Num hydro plants: {worst_year_data.generation_plant_id.nunique()}")
98+
print(f"From year: {new_start_year}")
99+
print(f"To year: {new_end_year}")
100+
print(f"Example data:\n{worst_year_data.head()}")
101+
102+
if not query_yes_no("\nAre you sure you want to add this data to the database?", default="no"):
103+
raise SystemExit
104+
105+
db_cursor.execute(
106+
"INSERT INTO hydro_simple_scenario(hydro_simple_scenario_id, name, description) "
107+
f"VALUES ('{new_scenario_id}','{new_scenario_name}','{new_scenario_description}')"
108+
)
109+
110+
n = len(worst_year_data)
111+
start_time = time.time()
112+
for i, r in enumerate(worst_year_data.itertuples(index=False)):
113+
if i !=0 and i % 1000 == 0:
114+
print(
115+
f"{i}/{n} inserts completed. Estimated time remaining {format_seconds((n - i) * (time.time() - start_time) / i)}")
116+
db_cursor.execute(
117+
f"INSERT INTO hydro_historical_monthly_capacity_factors(hydro_simple_scenario_id, generation_plant_id, year, month, hydro_min_flow_mw, hydro_avg_flow_mw) "
118+
f"VALUES ({r.hydro_simple_scenario_id},{r.generation_plant_id},{r.year},{r.month},{r.hydro_min_flow_mw},{r.hydro_avg_flow_mw})"
119+
)
120+
121+
db_conn.commit()
122+
db_cursor.close()
123+
db_conn.close()
124+
print("Done.")
125+
126+
127+
if __name__ == "__main__":
128+
main()
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
"""
2+
####################
3+
Create a no hydro scenario
4+
5+
Date applied: 2021-07-30
6+
Description:
7+
This script adds a scenario to the database that effectively removes all hydro generation from the model.
8+
#################
9+
"""
10+
import time
11+
12+
from switch_model.utilities import query_yes_no, format_seconds
13+
from switch_model.wecc.utilities import connect
14+
import pandas as pd
15+
16+
all_plants_scenario = 23
17+
18+
new_scenario_id = 25
19+
new_scenario_name = "No Hydro"
20+
new_scenario_description = "All average flows are zero effectively removing all hydro generation from the model." \
21+
" Represents as an extreme edge case of no hydro generation."
22+
23+
24+
def main():
25+
db_conn = connect()
26+
db_cursor = db_conn.cursor()
27+
28+
# 1. Get all the hydro plants
29+
db_cursor.execute(
30+
f"""
31+
SELECT DISTINCT generation_plant_id, year, month, hydro_min_flow_mw, hydro_avg_flow_mw FROM hydro_historical_monthly_capacity_factors
32+
WHERE hydro_simple_scenario_id={all_plants_scenario};
33+
""")
34+
df = pd.DataFrame(db_cursor.fetchall(),
35+
columns=["generation_plant_id", "year", "month", "hydro_min_flow_mw", "hydro_avg_flow_mw"])
36+
37+
# 2. Set all the flows to zero and set the scenario id
38+
df["hydro_min_flow_mw"] = 0
39+
df["hydro_avg_flow_mw"] = 0
40+
df["hydro_simple_scenario_id"] = new_scenario_id
41+
42+
# 3. Add data to database
43+
print(f"hydro_simple_scenario: {new_scenario_id}")
44+
print(f"name: {new_scenario_name}")
45+
print(f"description: {new_scenario_description}")
46+
print(f"Num hydro plants: {df.generation_plant_id.nunique()}")
47+
print(f"Example data:\n{df.head()}")
48+
49+
if not query_yes_no("\nAre you sure you want to add this data to the database?", default="no"):
50+
raise SystemExit
51+
52+
db_cursor.execute(
53+
"INSERT INTO hydro_simple_scenario(hydro_simple_scenario_id, name, description) "
54+
f"VALUES ('{new_scenario_id}','{new_scenario_name}','{new_scenario_description}')"
55+
)
56+
57+
n = len(df)
58+
start_time = time.time()
59+
for i, r in enumerate(df.itertuples(index=False)):
60+
if i != 0 and i % 1000 == 0:
61+
print(
62+
f"{i}/{n} inserts completed. Estimated time remaining {format_seconds((n - i) * (time.time() - start_time) / i)}")
63+
db_cursor.execute(
64+
f"INSERT INTO hydro_historical_monthly_capacity_factors(hydro_simple_scenario_id, generation_plant_id, year, month, hydro_min_flow_mw, hydro_avg_flow_mw) "
65+
f"VALUES ({r.hydro_simple_scenario_id},{r.generation_plant_id},{r.year},{r.month},{r.hydro_min_flow_mw},{r.hydro_avg_flow_mw})"
66+
)
67+
68+
db_conn.commit()
69+
db_cursor.close()
70+
db_conn.close()
71+
print("Done.")
72+
73+
74+
if __name__ == "__main__":
75+
main()
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
"""
2+
####################
3+
Create a hydro scenario with only half the flow of the baseline
4+
5+
Date applied: 2021-08-02
6+
Description:
7+
This script adds a scenario to the database that makes all hydro flows half of the expected hydro flow.
8+
#################
9+
"""
10+
import time
11+
12+
from switch_model.utilities import query_yes_no, format_seconds
13+
from switch_model.wecc.utilities import connect
14+
import pandas as pd
15+
16+
all_plants_scenario = 23
17+
18+
new_scenario_id = 26
19+
new_scenario_name = "50% of scenario 23"
20+
new_scenario_description = "All average flows are halved to represent a scenario where hydro generation is low."
21+
22+
23+
def main():
24+
db_conn = connect()
25+
db_cursor = db_conn.cursor()
26+
27+
# 1. Get all the hydro plants
28+
db_cursor.execute(
29+
f"""
30+
SELECT DISTINCT generation_plant_id, year, month, hydro_min_flow_mw, hydro_avg_flow_mw FROM hydro_historical_monthly_capacity_factors
31+
WHERE hydro_simple_scenario_id={all_plants_scenario};
32+
""")
33+
df = pd.DataFrame(db_cursor.fetchall(),
34+
columns=["generation_plant_id", "year", "month", "hydro_min_flow_mw", "hydro_avg_flow_mw"])
35+
36+
# 2. Set all the flows to zero and set the scenario id
37+
df["hydro_avg_flow_mw"] /= 2
38+
df["hydro_min_flow_mw"] = df[["hydro_min_flow_mw", "hydro_avg_flow_mw"]].min(axis=1)
39+
df["hydro_simple_scenario_id"] = new_scenario_id
40+
41+
# 3. Add data to database
42+
print(f"hydro_simple_scenario: {new_scenario_id}")
43+
print(f"name: {new_scenario_name}")
44+
print(f"description: {new_scenario_description}")
45+
print(f"Num hydro plants: {df.generation_plant_id.nunique()}")
46+
print(f"Example data:\n{df.head()}")
47+
48+
if not query_yes_no("\nAre you sure you want to add this data to the database?", default="no"):
49+
raise SystemExit
50+
51+
db_cursor.execute(
52+
"INSERT INTO hydro_simple_scenario(hydro_simple_scenario_id, name, description) "
53+
f"VALUES ('{new_scenario_id}','{new_scenario_name}','{new_scenario_description}')"
54+
)
55+
56+
n = len(df)
57+
start_time = time.time()
58+
for i, r in enumerate(df.itertuples(index=False)):
59+
if i != 0 and i % 1000 == 0:
60+
print(
61+
f"{i}/{n} inserts completed. Estimated time remaining {format_seconds((n - i) * (time.time() - start_time) / i)}")
62+
db_cursor.execute(
63+
f"INSERT INTO hydro_historical_monthly_capacity_factors(hydro_simple_scenario_id, generation_plant_id, year, month, hydro_min_flow_mw, hydro_avg_flow_mw) "
64+
f"VALUES ({r.hydro_simple_scenario_id},{r.generation_plant_id},{r.year},{r.month},{r.hydro_min_flow_mw},{r.hydro_avg_flow_mw})"
65+
)
66+
67+
db_conn.commit()
68+
db_cursor.close()
69+
db_conn.close()
70+
print("Done.")
71+
72+
73+
if __name__ == "__main__":
74+
main()

0 commit comments

Comments
 (0)