Skip to content

Commit ceedfd5

Browse files
authored
GridPath v2025.10.3
Merge pull request #1322 from blue-marble/develop
2 parents 8b7d81f + 77c6c71 commit ceedfd5

19 files changed

Lines changed: 361 additions & 323 deletions

db/__init__.py

Lines changed: 0 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +0,0 @@
1-
# Copyright 2016-2023 Blue Marble Analytics LLC.
2-
#
3-
# Licensed under the Apache License, Version 2.0 (the "License");
4-
# you may not use this file except in compliance with the License.
5-
# You may obtain a copy of the License at
6-
#
7-
# http://www.apache.org/licenses/LICENSE-2.0
8-
#
9-
# Unless required by applicable law or agreed to in writing, software
10-
# distributed under the License is distributed on an "AS IS" BASIS,
11-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12-
# See the License for the specific language governing permissions and
13-
# limitations under the License.
14-
15-
"""
16-
All tables names in the GridPath database start with one of seven prefixes:
17-
:code:`mod_`, :code:`subscenario_`, :code:`inputs_`, :code:`scenarios`,
18-
:code:`options_`, :code:`status_`, or :code:`ui_`. This structure is meant to
19-
organize the tables by their function. Below are descriptions of each table
20-
type and its role, and of the kind of data tables of this type contain.
21-
22-
***********************
23-
The :code:`mod_` Tables
24-
***********************
25-
The :code:`mod_` should not be modified except by developers. These contain
26-
various data used by the GridPath platform to describe available
27-
functionality, help enforce input data consistency and integrity, and aid in
28-
validation.
29-
30-
***************************************************
31-
The :code:`subscenario_` and :code:`inputs_` Tables
32-
***************************************************
33-
Most tables in the GridPath database have the :code:`subscenario_` and
34-
:code:`inputs_` prefix. With a few exceptions, for each :code:`subscenario_`
35-
table, there is a respective :code:`inputs_` table (i.e. the tables have the
36-
same name except for the prefix). This is because the :code:`subscenario_`
37-
tables contain the descriptions of the input data contained in the
38-
:code:`inputs_` tables. For example the :code:`inputs_system_load` may
39-
contain three different load profiles -- low, mid, and high; the
40-
:code:`subscenarios_system_load` will then contain three rows, one for each
41-
load profile, with its description and ID. The pairs of :code:`subscenario_`
42-
and :code:`inputs_` are linked via an ID column: in the case of the system
43-
load tables, that is the :code:`load_scenario_id` column. We call these
44-
shared table keys *subscenario IDs*, as we use them to create a full
45-
GridPath scenario in the :code:`scenarios` table.
46-
47-
***************************
48-
The :code:`scenarios` Table
49-
***************************
50-
In GridPath, we use the term 'scenario' to describe a model run with a
51-
particular set of inputs. Some of those inputs stay the same from scenario to
52-
scenario and others we vary to understand their effect on the results. For
53-
example, we could keep some input types like the zonal and transmission
54-
topography, temporal resolution, resource availability, and policy
55-
requirements the same across scenarios, but vary other input types, e.g. the
56-
load profile, the cost of solar, and the operational characteristics of coal,
57-
to create different scenarios. We call each of those inputs types a
58-
'subscenario' since they are the building blocks of a full scenario. In
59-
GridPath, you can create a scenario by populating a row of the
60-
:code:`scenarios` table. The columns of the :code:`scenarios` table are
61-
linked one of the 'building blocks' -- the data in :code:`inputs_` tables --
62-
via the respective *subscenario ID*.
63-
64-
For example, the :code:`load_scenario_id` column of the :code:`scenarios` table
65-
references the :code:`load_scenario_id` column of the
66-
:code:`subscenarios_system_load` table, which in turn determines which load
67-
profile contained in the :code:`inputs_system_load` table the scenario
68-
should use. In our example with three different load profiles, the data for
69-
which are contained in the :code:`inputs_system_load` table,
70-
:code:`subscenarios_system_load` will contain three rows with values of 1,
71-
2, and 3 respectively in the :code:`load_scenario_id` column; in the
72-
:code:`scenarios` table, the user would then be able to select a value of 1,
73-
2, or 3 in the :code:`load_scenario_id` column to determine which load
74-
profile the scenario should use. Similarly, we would select the solar costs
75-
to use in the scenario via the :code:`projects_new_cost_scenario_id` column
76-
of the :code:`scenarios` table (which is linked to the
77-
:code:`subscenarios_project_new_cost` and :code:`inputs_project_new_cost`
78-
tables) and the operational characteristics of coal to use via the
79-
:code:`project_operational_chars_scenario_id` column (which is linked to the
80-
:code:`subscenarios_project_operational_chars` and
81-
:code:`inputs_project_operational_chars` tables).
82-
83-
***************************
84-
The :code:`options_` Tables
85-
***************************
86-
Some GridPath run options can be specified via the database in the
87-
:code:`options_` tables. Currently, this includes the solver options that
88-
can be specified for a scenario run
89-
90-
**************************
91-
The :code:`status_` Tables
92-
**************************
93-
GridPath keeps track of scenario validation and run status. The scenario
94-
status is recorded in the :code:`scenarios` table (in the
95-
:code:`validation_status_id` and :code:`run_status_id` columns) and an
96-
additional detail can be found in the :code:`status_` tables. Currently,
97-
this includes a single table: the :code:`status_validation` table, which
98-
contains information about errors encountered during validation for each
99-
scenario that has been validated.
100-
101-
**********************
102-
The :code:`ui_` Tables
103-
**********************
104-
The :code:`ui_` tables are used to include and exclude components of the
105-
GridPath user interface.
106-
107-
***********************
108-
The :code:`viz_` Tables
109-
***********************
110-
The :code:`viz_` tables are used in the GridPath visualization suite, for
111-
instance when determining in which color and order to plot the technologies in
112-
the dispatch plot.
113-
114-
115-
"""

db/doc.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# Copyright 2016-2025 Blue Marble Analytics LLC.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
16+
"""
17+
All tables names in the GridPath database start with one of seven prefixes:
18+
:code:`mod_`, :code:`subscenario_`, :code:`inputs_`, :code:`scenarios`,
19+
:code:`options_`, :code:`status_`, or :code:`ui_`. This structure is meant to
20+
organize the tables by their function. Below are descriptions of each table
21+
type and its role, and of the kind of data tables of this type contain.
22+
23+
***********************
24+
The :code:`mod_` Tables
25+
***********************
26+
The :code:`mod_` should not be modified except by developers. These contain
27+
various data used by the GridPath platform to describe available
28+
functionality, help enforce input data consistency and integrity, and aid in
29+
validation.
30+
31+
***************************************************
32+
The :code:`subscenario_` and :code:`inputs_` Tables
33+
***************************************************
34+
Most tables in the GridPath database have the :code:`subscenario_` and
35+
:code:`inputs_` prefix. With a few exceptions, for each :code:`subscenario_`
36+
table, there is a respective :code:`inputs_` table (i.e. the tables have the
37+
same name except for the prefix). This is because the :code:`subscenario_`
38+
tables contain the descriptions of the input data contained in the
39+
:code:`inputs_` tables. For example the :code:`inputs_system_load` may
40+
contain three different load profiles -- low, mid, and high; the
41+
:code:`subscenarios_system_load` will then contain three rows, one for each
42+
load profile, with its description and ID. The pairs of :code:`subscenario_`
43+
and :code:`inputs_` are linked via an ID column: in the case of the system
44+
load tables, that is the :code:`load_scenario_id` column. We call these
45+
shared table keys *subscenario IDs*, as we use them to create a full
46+
GridPath scenario in the :code:`scenarios` table.
47+
48+
***************************
49+
The :code:`scenarios` Table
50+
***************************
51+
In GridPath, we use the term 'scenario' to describe a model run with a
52+
particular set of inputs. Some of those inputs stay the same from scenario to
53+
scenario and others we vary to understand their effect on the results. For
54+
example, we could keep some input types like the zonal and transmission
55+
topography, temporal resolution, resource availability, and policy
56+
requirements the same across scenarios, but vary other input types, e.g. the
57+
load profile, the cost of solar, and the operational characteristics of coal,
58+
to create different scenarios. We call each of those inputs types a
59+
'subscenario' since they are the building blocks of a full scenario. In
60+
GridPath, you can create a scenario by populating a row of the
61+
:code:`scenarios` table. The columns of the :code:`scenarios` table are
62+
linked one of the 'building blocks' -- the data in :code:`inputs_` tables --
63+
via the respective *subscenario ID*.
64+
65+
For example, the :code:`load_scenario_id` column of the :code:`scenarios` table
66+
references the :code:`load_scenario_id` column of the
67+
:code:`subscenarios_system_load` table, which in turn determines which load
68+
profile contained in the :code:`inputs_system_load` table the scenario
69+
should use. In our example with three different load profiles, the data for
70+
which are contained in the :code:`inputs_system_load` table,
71+
:code:`subscenarios_system_load` will contain three rows with values of 1,
72+
2, and 3 respectively in the :code:`load_scenario_id` column; in the
73+
:code:`scenarios` table, the user would then be able to select a value of 1,
74+
2, or 3 in the :code:`load_scenario_id` column to determine which load
75+
profile the scenario should use. Similarly, we would select the solar costs
76+
to use in the scenario via the :code:`projects_new_cost_scenario_id` column
77+
of the :code:`scenarios` table (which is linked to the
78+
:code:`subscenarios_project_new_cost` and :code:`inputs_project_new_cost`
79+
tables) and the operational characteristics of coal to use via the
80+
:code:`project_operational_chars_scenario_id` column (which is linked to the
81+
:code:`subscenarios_project_operational_chars` and
82+
:code:`inputs_project_operational_chars` tables).
83+
84+
***************************
85+
The :code:`options_` Tables
86+
***************************
87+
Some GridPath run options can be specified via the database in the
88+
:code:`options_` tables. Currently, this includes the solver options that
89+
can be specified for a scenario run
90+
91+
**************************
92+
The :code:`status_` Tables
93+
**************************
94+
GridPath keeps track of scenario validation and run status. The scenario
95+
status is recorded in the :code:`scenarios` table (in the
96+
:code:`validation_status_id` and :code:`run_status_id` columns) and an
97+
additional detail can be found in the :code:`status_` tables. Currently,
98+
this includes a single table: the :code:`status_validation` table, which
99+
contains information about errors encountered during validation for each
100+
scenario that has been validated.
101+
102+
**********************
103+
The :code:`ui_` Tables
104+
**********************
105+
The :code:`ui_` tables are used to include and exclude components of the
106+
GridPath user interface.
107+
108+
***********************
109+
The :code:`viz_` Tables
110+
***********************
111+
The :code:`viz_` tables are used in the GridPath visualization suite, for
112+
instance when determining in which color and order to plot the technologies in
113+
the dispatch plot.
114+
115+
116+
"""

db/utilities/scenario.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
1919
>>> gridpath_load_scenarios --database PATH/DO/DB --csv_path PATH/TO/SCENARIO/CSV
2020
21+
If you are using the csvs_test_examples directory included with GridPath, /PATH/TO/SCENARIO/CSV
22+
can be set to ../csvs_test_examples/scenarios.csv.
23+
2124
To load a single scenario by name, use the *--scenario* flag. To delete a scenario from
2225
the database, specify the scenario name with the *--scenario* flag and use the
2326
*--delete* flag.

doc/graphics/gridpath_workflow.png

41.8 KB
Loading
125 KB
Loading

doc/graphics/optype_opchar_matrix.svg

Lines changed: 1 addition & 0 deletions
Loading

doc/opchar_img_gen.py

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2016-2024 Blue Marble Analytics LLC.
1+
# Copyright 2016-2025 Blue Marble Analytics LLC.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@
2828
)
2929

3030
d2i_tbl_hdr_dict = dict(
31-
align="right", fill_color="blue", font_color="white", line_color="darkslategray"
31+
align="right", fill_color="#5176BF", font_color="white", line_color="darkslategray"
3232
)
3333
d2i_tbl_cel_dict = dict(align="right", line_color="darkslategray")
3434

@@ -45,24 +45,61 @@
4545
tbl_header=d2i_tbl_hdr_dict,
4646
tbl_cells=d2i_tbl_cel_dict,
4747
show_fig=False,
48-
row_fill_color=("#ffffff", "#d7d8d6"),
48+
row_fill_color=("#ffffff", "#5176BF"),
4949
print_index=False,
50-
fig_size=(1800, 500),
50+
fig_size=(3500, 1000),
5151
col_width=tuple(col_width_both),
5252
)
5353

5454
fig_table = fig.data[0]
5555
rr1, cc1 = np.where(df == "required")
56-
for validx in range(len(rr1)):
57-
ra = rr1[validx]
58-
ca = cc1[validx]
59-
fig_table.cells.fill.color[ca][ra] = "#FF0000"
60-
6156
rr2, cc2 = np.where(df == "optional")
62-
for validx in range(len(rr2)):
63-
rb = rr2[validx]
64-
cb = cc2[validx]
65-
fig_table.cells.fill.color[cb][rb] = "#FFFF00"
57+
58+
# python
59+
# prepare a mutable, normalized column-first list-of-lists for cell fill colors
60+
colors = list(fig_table.cells.fill.color)
61+
62+
# determine actual number of rows in the table (includes header row)
63+
num_rows_in_table = 0
64+
for col in colors:
65+
if isinstance(col, (tuple, list)):
66+
num_rows_in_table = max(num_rows_in_table, len(col))
67+
else:
68+
num_rows_in_table = max(num_rows_in_table, 1)
69+
if num_rows_in_table == 0:
70+
num_rows_in_table = len(df) + 1
71+
72+
# normalize each column to be a list of length num_rows_in_table
73+
normalized = []
74+
for col in colors:
75+
if not isinstance(col, list):
76+
col_list = list(col) if isinstance(col, (tuple, list)) else [col]
77+
else:
78+
col_list = col
79+
if len(col_list) < num_rows_in_table:
80+
col_list = col_list + ["#ffffff"] * (num_rows_in_table - len(col_list))
81+
elif len(col_list) > num_rows_in_table:
82+
col_list = col_list[:num_rows_in_table]
83+
normalized.append(list(col_list))
84+
colors = normalized
85+
86+
# compute offset between dataframe row indices and table row indices (header row)
87+
header_offset = num_rows_in_table - len(df)
88+
if header_offset < 0:
89+
header_offset = 0
90+
91+
# set required cells to red (apply header_offset)
92+
for r, c in zip(rr1, cc1):
93+
if 0 <= c < len(colors) and 0 <= (r + header_offset) < len(colors[c]):
94+
colors[c][r + header_offset] = "#BF5176"
95+
96+
# set optional cells to yellow (apply header_offset)
97+
for r, c in zip(rr2, cc2):
98+
if 0 <= c < len(colors) and 0 <= (r + header_offset) < len(colors[c]):
99+
colors[c][r + header_offset] = "#51BF9B"
100+
101+
# assign back the modified colors
102+
fig_table.cells.fill.color = colors
66103

67104
df2img.save_dataframe(fig=fig, filename="graphics/optype_opchar_matrix.png")
68105
df2img.save_dataframe(fig=fig, filename="graphics/optype_opchar_matrix.svg")

doc/source/conf.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import os
2020
import sys
21+
import sphinx_rtd_theme
2122

2223
sys.path.insert(0, os.path.abspath("../../"))
2324

@@ -36,6 +37,7 @@
3637
"sphinx.ext.todo",
3738
"sphinx.ext.viewcode",
3839
"sphinxarg.ext",
40+
"sphinx_rtd_theme",
3941
]
4042

4143
# Add any paths that contain templates here, relative to this directory.
@@ -52,7 +54,7 @@
5254

5355
# General information about the project.
5456
project = "GridPath"
55-
copyright = "2016-2022, Blue Marble Analytics LLC"
57+
copyright = "2016-2025, Blue Marble Analytics LLC"
5658
author = "Blue Marble Analytics LLC"
5759

5860
# The version info for the project you're documenting, acts as replacement for
@@ -95,7 +97,7 @@
9597
# The theme to use for HTML and HTML Help pages. See the documentation for
9698
# a list of builtin themes.
9799
# http://www.sphinx-doc.org/en/stable/theming.html
98-
html_theme = "nature"
100+
html_theme = "sphinx_rtd_theme"
99101

100102
# Theme options are theme-specific and customize the look and feel of a theme
101103
# further. For a list of options available for each theme, see the

0 commit comments

Comments
 (0)