From 44eb45a16e78c4fa717dc5aabfdd6cf06b2d311a Mon Sep 17 00:00:00 2001 From: Darryl Melander Date: Mon, 31 Jul 2023 11:36:53 -0600 Subject: [PATCH 1/4] Standardize line endings --- .../source/concepts/data_streams.rst | 28 +- doc/OnlineDocs/source/concepts/index.rst | 20 +- doc/OnlineDocs/source/concepts/markets.rst | 6 +- doc/OnlineDocs/source/concepts/reserves.rst | 2 +- .../source/concepts/ruc_sced_cycle.rst | 14 +- doc/OnlineDocs/source/examples/index.rst | 2 +- doc/OnlineDocs/source/reference/code.rst | 4 +- .../reference/file_formats/custom-input.rst | 2 +- .../reference/file_formats/rts-gmlc/bus.rst | 10 +- .../file_formats/rts-gmlc/dc_branch.rst | 6 +- .../reference/file_formats/rts-gmlc/gen.rst | 2 +- .../reference/file_formats/rts-gmlc/index.rst | 4 +- doc/OnlineDocs/source/tasks/configure.rst | 776 +++++++++--------- doc/OnlineDocs/source/tasks/index.rst | 24 +- doc/OnlineDocs/source/tasks/install.rst | 22 +- .../source/tasks/install_solvers.rst | 2 +- doc/OnlineDocs/source/tasks/output.rst | 12 +- doc/OnlineDocs/source/tasks/plugins.rst | 10 +- doc/OnlineDocs/source/tasks/run.rst | 372 ++++----- 19 files changed, 659 insertions(+), 659 deletions(-) diff --git a/doc/OnlineDocs/source/concepts/data_streams.rst b/doc/OnlineDocs/source/concepts/data_streams.rst index b647ce8f..5493e71a 100644 --- a/doc/OnlineDocs/source/concepts/data_streams.rst +++ b/doc/OnlineDocs/source/concepts/data_streams.rst @@ -2,7 +2,7 @@ Time Series Data Streams ======================== Prescient uses time series data from two data streams, the real-time stream -(i.e., actuals) and the forecast stream. As their names imply, the real-time +(i.e., actuals) and the forecast stream. As their names imply, the real-time stream includes data that the simulation should treat as actual values that occur at specific times in the simulation, and the forecast stream includes forecasts for time periods that have not yet occured in the simulation. @@ -13,25 +13,25 @@ generation data. Real-Time Data (Actuals) ------------------------ -The real-time data stream provides data that the simulation should treat as +The real-time data stream provides data that the simulation should treat as actual values. Real-time values are typically used only when the simulation reaches the corresponding simulation time. Real-time data can be provided at any time interval. The real-time data interval -generally matches the SCED interval -(see :ref:`sced-frequency-minutes`), but this is -not a requirement. If the SCED interval does not match the real-time interval +generally matches the SCED interval +(see :ref:`sced-frequency-minutes`), but this is +not a requirement. If the SCED interval does not match the real-time interval then real-time data will be interpolated or discarded as needed to match the SCED interval. Forecasts --------- -Forecast data are provided by the forecast data stream. The frequency of data +Forecast data are provided by the forecast data stream. The frequency of data provided through the forecast stream must be hourly. -New forecasts are retrieved each time a new RUC plan is generated. The -forecasts retrieved in a given batch are those required to satisfy the RUC horizon +New forecasts are retrieved each time a new RUC plan is generated. The +forecasts retrieved in a given batch are those required to satisfy the RUC horizon (see :ref:`ruc-horizon`), starting with the RUC activation time. @@ -40,17 +40,17 @@ forecasts retrieved in a given batch are those required to satisfy the RUC horiz Forecast Smoothing ~~~~~~~~~~~~~~~~~~ -As forecasts are retrieved from the forecast data stream, they may be adjusted so that +As forecasts are retrieved from the forecast data stream, they may be adjusted so that near-term forecasts are more accurate than forecasts further into the future. This serves two purposes: first, to avoid large jumps in timeseries values due to inaccurate forecasts; and second, to model how forecasts become more accurate as their time approaches. -The number of forecasts to be smoothed is determined by the +The number of forecasts to be smoothed is determined by the :ref:`ruc-prescience-hour` configuration option. Values for -the current simulation time are set equal to their actual value, ignoring data read from +the current simulation time are set equal to their actual value, ignoring data read from the forecast stream. Values for ``ruc-prescience-hour`` hours after the current simulation time are set equal to data read from the forecast stream. Between these two times, -values are a weighted average of the values provided by the actuals and forecast data +values are a weighted average of the values provided by the actuals and forecast data streams. The weights vary linearly with where the time falls between the current time and the ruc prescience hour. For example, if ``ruc-prescience-hour`` is 8, then the adjusted forecast for 2 hours after the current simulation time will be ``0.25*forecast + 0.75*actual``. @@ -62,8 +62,8 @@ Real-Time Forecast Adjustments ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Forecasts are adjusted further each time a SCED is run. This is done by comparing the forecast -for the current time with the actual value for the current time. The ratio of these two -values is calculated, then used as a scaling factor for forecast values. For example, if the +for the current time with the actual value for the current time. The ratio of these two +values is calculated, then used as a scaling factor for forecast values. For example, if the forecast for a value was 10% too high, all future forecasts for the same value are reduced by 10%. .. note:: diff --git a/doc/OnlineDocs/source/concepts/index.rst b/doc/OnlineDocs/source/concepts/index.rst index 5a184148..4f6a42a6 100644 --- a/doc/OnlineDocs/source/concepts/index.rst +++ b/doc/OnlineDocs/source/concepts/index.rst @@ -1,10 +1,10 @@ -Modeling Concepts ------------------ - -.. toctree:: - :maxdepth: 2 - - ruc_sced_cycle.rst - data_streams.rst - reserves.rst - markets.rst +Modeling Concepts +----------------- + +.. toctree:: + :maxdepth: 2 + + ruc_sced_cycle.rst + data_streams.rst + reserves.rst + markets.rst diff --git a/doc/OnlineDocs/source/concepts/markets.rst b/doc/OnlineDocs/source/concepts/markets.rst index 247f1356..65cbef96 100644 --- a/doc/OnlineDocs/source/concepts/markets.rst +++ b/doc/OnlineDocs/source/concepts/markets.rst @@ -1,3 +1,3 @@ -Energy Markets and Pricing -========================== - +Energy Markets and Pricing +========================== + diff --git a/doc/OnlineDocs/source/concepts/reserves.rst b/doc/OnlineDocs/source/concepts/reserves.rst index 860cf2e3..2ac598d9 100644 --- a/doc/OnlineDocs/source/concepts/reserves.rst +++ b/doc/OnlineDocs/source/concepts/reserves.rst @@ -1,2 +1,2 @@ -Reserves and Ancillary Services +Reserves and Ancillary Services =============================== \ No newline at end of file diff --git a/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst b/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst index 09af7b39..b5c0daa9 100644 --- a/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst +++ b/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst @@ -4,7 +4,7 @@ The Prescient Simulation Cycle .. image:: ../_static/image/RucScedCycle.png :class: align-right -Prescient simulates the operation of a power generation network throughout a +Prescient simulates the operation of a power generation network throughout a study horizon, finding the set of operational choices that satisfy demand at the lowest possible cost. @@ -36,7 +36,7 @@ will go into effect at midnight, one at 8:00 a.m., and one at 4:00 p.m. Each RUC plan covers the time period that starts when it goes into effect and ends just as the next RUC plan becomes active. -A RUC plan is based on the current state of the system at the time the plan is +A RUC plan is based on the current state of the system at the time the plan is generated (particularly the current dispatch and up- or down-time for dispatchable generators), and on forecasts for a number of upcoming time periods. The forecasts considered when forming a RUC plan must extend at least to the end of the RUC's planning period, @@ -50,24 +50,24 @@ they take effect. This is done by specifying a time of day for one of the plans be generated. The gap between the specified generation time and the next time a RUC plan is scheduled to take effect is called the RUC gap. Each RUC plan still covers the expected time period, from the time the plan takes effect until the next RUC plan -takes effect, but its decisions will be based on what is known at the time the RUC +takes effect, but its decisions will be based on what is known at the time the RUC plan is generated. The SCED Cycle -------------- -The SCED process selects dispatch levels for all active dispatchable generators +The SCED process selects dispatch levels for all active dispatchable generators in the current simulation time period. Dispatch levels are determined using a process that is very similar to that used to build a RUC plan. The current state of the system, together with forecasts for a number of future time periods, are examined to select dispatch levels that satisfy current loads and forecasted future loads at the lowest possible cost. -The SCED cycle is more frequent than the RUC cycle, with new dispatch levels selected +The SCED cycle is more frequent than the RUC cycle, with new dispatch levels selected at least once an hour. The SCED honors unit commitment decisions made in the RUC plan; -whether each generator is committed or not is dictatated by the RUC schedule +whether each generator is committed or not is dictatated by the RUC schedule currently in effect. -Costs are also determined with each SCED, based on dispatchable generation selected by +Costs are also determined with each SCED, based on dispatchable generation selected by the SCED process, the commitment and start-up costs as selected by the associated RUC process, as well as current actual demands and non-dispatchable generation levels. diff --git a/doc/OnlineDocs/source/examples/index.rst b/doc/OnlineDocs/source/examples/index.rst index c44d2f33..290f630d 100644 --- a/doc/OnlineDocs/source/examples/index.rst +++ b/doc/OnlineDocs/source/examples/index.rst @@ -1,2 +1,2 @@ -Examples and Tutorials +Examples and Tutorials ---------------------- \ No newline at end of file diff --git a/doc/OnlineDocs/source/reference/code.rst b/doc/OnlineDocs/source/reference/code.rst index 3b9514b8..3add577b 100644 --- a/doc/OnlineDocs/source/reference/code.rst +++ b/doc/OnlineDocs/source/reference/code.rst @@ -1,2 +1,2 @@ -Python Classes and Functions ----------------------------- +Python Classes and Functions +---------------------------- diff --git a/doc/OnlineDocs/source/reference/file_formats/custom-input.rst b/doc/OnlineDocs/source/reference/file_formats/custom-input.rst index fbcc5f9a..b0800927 100644 --- a/doc/OnlineDocs/source/reference/file_formats/custom-input.rst +++ b/doc/OnlineDocs/source/reference/file_formats/custom-input.rst @@ -16,7 +16,7 @@ to acquire initial data, and to request updates to data for specific time periods. For an example or a custom data provider, see the -`example `_ +`example `_ in the source code, or examine one of the `standard data providers `_. diff --git a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/bus.rst b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/bus.rst index 2705624f..0e8b4f24 100644 --- a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/bus.rst +++ b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/bus.rst @@ -4,11 +4,11 @@ bus.csv ======= This file is used to define buses. Add one row for each bus in the system. Each -row in the CSV file will cause a bus dictionary object to be added to +row in the CSV file will cause a bus dictionary object to be added to ``['elements']['bus']`` in the Egret model. Each row with a non-zero :col:`MW Load` and/or non-zero :col:`MVAR Load` will also cause a -load to be added to ``['elements']['load']`` in Egret, and each row with a non-zero +load to be added to ``['elements']['load']`` in Egret, and each row with a non-zero :col:`MW Shunt G` and/or non-zero :col:`MVAR Shunt B` will cause a shunt to be added to ``['elements']['shunt']`` in Egret. @@ -26,11 +26,11 @@ to ``['elements']['shunt']`` in Egret. - A human-friendly unique string for this bus. - Used as the bus name in Egret. Data for this bus is stored in a bus dictionary stored at :samp:`['elements']['bus'][{}]`. - + This is also the name of the load, if a load is added for the bus (a load is added if MW Load or MVAR Load is non-zero). The load dictionary is stored at :samp:`['elements']['load'][{}]`. - + This is also the name of the shunt, if a shunt is added for the bus (a bus is added if :col:`MW Shunt G` or :col:`MVAR Shunt G` is non-zero). The shunt dictionary is stored at :samp:`['elements']['shunt'][{}]`. @@ -77,7 +77,7 @@ to ``['elements']['shunt']`` in Egret. * - :col:`va` - Reference bus angle. If the :col:`Bus Type` is *Ref*, :col:`va` is required and must be zero. - - + - Additional Bus Values ~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/dc_branch.rst b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/dc_branch.rst index ba1dd854..ad594566 100644 --- a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/dc_branch.rst +++ b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/dc_branch.rst @@ -6,7 +6,7 @@ for DC branches, as indicated by the small number of columns in this file. This file is optional; if the file does not exist, no DC branches are added to the model. If the file exists, add a row for each DC branch in the model. -Each row in the file will cause a DC branch dictionary to be added to +Each row in the file will cause a DC branch dictionary to be added to ``['elements']['dc_branch']`` in the Egret model. .. list-table:: dc_branch.csv Columns @@ -21,12 +21,12 @@ Each row in the file will cause a DC branch dictionary to be added to branch dictionary located at :samp:`['elements']['dc_branch'][{}]`. * - :col:`From Bus` - The :col:`Bus ID` of one end of the branch - - The :col:`Bus Name` of the bus with the matching :col:`Bus ID`, as + - The :col:`Bus Name` of the bus with the matching :col:`Bus ID`, as entered in bus.csv, is stored in the Egret branch dictionary as ``from_bus``. * - :col:`To Bus` - The :col:`Bus ID` of the other end of the branch - - The :col:`Bus Name` of the bus with the matching :col:`Bus ID`, as + - The :col:`Bus Name` of the bus with the matching :col:`Bus ID`, as entered in bus.csv, is stored in the Egret branch dictionary as ``to_bus``. * - :col:`MW Load` diff --git a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/gen.rst b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/gen.rst index ab0d288e..94c04deb 100644 --- a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/gen.rst +++ b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/gen.rst @@ -208,7 +208,7 @@ based on how long it has been since the generator was shut off. than either the :col:`Min Down Time Hr` or the :col:`Start Time Hot Hr`, the generator cannot yet be restarted. -- If the time since shutdown is at least :col:`Min Down Time Hr` and +- If the time since shutdown is at least :col:`Min Down Time Hr` and :col:`Start Time Hot Hr`, but less than :col:`Start Time Warm Hr`, then the generator can do a hot start, consuming :col:`Start Heat Hot MMBTU`. diff --git a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/index.rst b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/index.rst index a6303a93..dfb7e8a9 100644 --- a/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/index.rst +++ b/doc/OnlineDocs/source/reference/file_formats/rts-gmlc/index.rst @@ -2,7 +2,7 @@ The CSV Input File Format ========================= The system being modeled by Prescient is read from a set of CSV files. The -CSV files and their format is based on the +CSV files and their format is based on the `RTS-GMLC format `_. Prescient uses only a subset of the columns present in RTS-GMLC format. This document identifies the columns read by Prescient, their meaning, and how they @@ -18,7 +18,7 @@ below: Required Files .. toctree:: :maxdepth: 1 - + bus branch gen diff --git a/doc/OnlineDocs/source/tasks/configure.rst b/doc/OnlineDocs/source/tasks/configure.rst index 5180a413..9c52c3de 100644 --- a/doc/OnlineDocs/source/tasks/configure.rst +++ b/doc/OnlineDocs/source/tasks/configure.rst @@ -1,388 +1,388 @@ -Configuration Options -===================== - -.. contents:: - :local: - -Overview --------- - -Prescient configuration options are used to indicate how -the Prescient simulation should be run. Configuration -options can be specified on the command line, in a text -configuration file, or in code, depending on how Prescient -is launched (see :doc:`run`). - -Each configuration option has a name, a data type, and a default value. -The name used on the command line and the name used in code vary slightly. -For example, the number of days to simulate is specified as `\-\-num-days` -on the command line, and `num_days` in code. - -Option Data Types ------------------ - -Most options use self-explanatory data types like `String`, -`Integer`, and `Float`, but some data types require more -explanation and may be specified in code in ways that are unavailable -on the command line: - -.. list-table:: Configuration Data Types - :header-rows: 1 - :class: table-top-align-cells table-wrap-headers - - * - Data type - - Command-line/config file usage - - In-code usage - * - Path - - A text string that refers to a file or folder. Can be - relative or absolute, and may include special characters - such as `~`. - - Same as command-line - * - Date - - A string that can be converted to a date, such as *1776-07-04*. - - Either a string or a datetime object. - * - Flag - - Simply include the option to set it to true. For example, the command - below sets `simulate_out_of_sample` to true:: - - runner.py --simulate-out-of-sample - - - Set the option by assigning True or False:: - - config.simulate_out_of_sample = True - * - Module - - Refer to a python module in one of the following ways: - - * The name of a python module (such as `prescient.simulator.prescient`) - * The path to a python file (such as `prescient/simulator/prescient.py`) - - In addition to the two string options available to the command-line, - code may also use a python module object. For example:: - - import my_custom_data_provider - config.data_provider = my_custom_data_provider - -List of Configuration Options ------------------------------ - -The table below describes all available configuration options. - -.. list-table:: Configuration Options - :header-rows: 1 - :widths: 20 20 25 35 - :class: table-top-align-cells table-wrap-headers - - * - Command-line Option - - In-Code Configuration Property - - Argument - - Description - * - \-\-config-file - - config_file - - Path. Default=None. - - Path to a file holding configuration options. Can be absolute or - relative. Cannot be set in code directly on a configuration object, but - can be passed to a configuration object's `parse_args()` function: - - .. code-block:: python - - p = Prescient() - p.config.parse_args(["--config-file", "my-config.txt"]) - - See :ref:`launch-with-runner-py` for a description of - configuration file syntax. - - * - **General Options** - - - - - - - * - \-\-start-date - - start_date - - Date. Default=2020-01-01. - - The start date for the simulation. - * - \-\-num-days - - num_days - - Integer. Default=7 - - The number of days to simulate. - * - **Data Options** - - - - - - - * - \-\-data-path - - or - - \-\-data-directory - - data_path - - Path. Default=input_data. - - Path to a file or folder where input data is located. Whether it - should be a file or a folder depends on the input format. See :doc:`input`. - * - \-\-input-format - - input_format - - String. Default=rts_gmlc. - - The format of the input data. Valid values are *dat* and *rts_gmlc*. - Ignored when using a custom data provider. See :doc:`input`. - * - \-\-data-provider - - data_provider - - Module. Default=No custom data provider. - - A python module with a custom data provider that will supply - data to Prescient during the simulation. Don't specify this option - unless you are using a custom data provider; use data_path and - input_format instead. - See :ref:`custom-data-providers`. - * - \-\-output-directory - - output_directory - - Path. Default=outdir. - - The path to the root directory to which all generated simulation - output files and associated data are written. - * - **RUC Options** - - - - - - - * - \-\-ruc_every-hours - - ruc_every_hours - - Integer. Default=24 - - How often a RUC is executed, in hours. Default is 24. - Must be a divisor of 24. - * - \-\-ruc-execution-hour - - ruc_execution_hour - - Integer. Default=16 - - Specifies an hour of the day the RUC process is executed. - If multiple RUCs are executed each day (because `ruc_every_hours` - is less than 24), any of the execution times may be specified. - Negative values indicate hours before midnight, positive after. - * - .. _config_ruc-horizon: - - \-\-ruc-horizon - - ruc_horizon - - Integer. Default=48 - - The number of hours to include in each RUC. - Must be >= `ruc_every_hours` and <= 48. - * - .. _config_ruc-prescience-hour: - - \-\-ruc-prescience-hour - - ruc_prescience_hour - - Integer. Default=0. - - The number of initial hours of each RUC in which linear blending of - forecasts and actual values is done, making some near-term - forecasts more accurate. - * - \-\-run-ruc-with-next-day-data - - run_ruc_with_next_day_data - - Flag. Default=false. - - If false (the default), never use more than 24 hours of - forecast data even if the RUC horizon is longer than 24 - hours. Instead, infer values beyond 24 hours. - - If true, use forecast data for the full RUC horizon. - * - \-\-simulate-out-of-sample - - simulate_out_of_sample - - Flag. Default=false. - - If false, use forecast input data as both forecasts and actual - values; the actual value input data is ignored. - - If true, values for the current simulation time are taken from - the actual value input, and actual values are used to blend - near-term values if `ruc_prescience_hour` is non-zero. - * - \-\-ruc-network-type - - ruc_network_type - - String. Default=ptdf. - - Specifies how the network is represented in RUC models. Choices are: - * ptdf -- power transfer distribution factor representation - * btheta -- b-theta representation - * - \-\-ruc-slack-type - - ruc_slack_type - - String. Default=every-bus. - - Specifies the type of slack variables to use in the RUC model formulation. - Choices are: - * every-bus -- slack variables at every system bus - * ref-bus-and-branches -- slack variables at only reference bus and each system branch - * - \-\-deterministic-ruc-solver - - deterministic_ruc_solver - - String. Default=cbc. - - The name of the solver to use for RUCs. - * - \-\-deterministic-ruc-solver-options - - deterministic_ruc_solver_options - - String. Default=None. - - Solver options applied to all RUC solves. - * - \-\-ruc-mipgap - - ruc_mipgap - - Float. Default=0.01. - - The mipgap for all deterministic RUC solves. - * - \-\-output-ruc-initial-conditions - - output_ruc_initial_conditions - - Flag. Default=false. - - Print initial conditions to stdout prior to each RUC solve. - * - \-\-output-ruc-solutions - - output_ruc_solutions - - Flag. Default=false. - - Print RUC solution to stdout after each RUC solve. - * - \-\-write-deterministic-ruc-instances - - write_deterministic_ruc_instances - - Flag. Default=false. - - Save each individual RUC model to a file. The date and - time the RUC was executed is indicated in the file name. - * - \-\-deterministic-ruc-solver-plugin - - deterministic_ruc_solver_plugin - - Module. Default=None. - - If the user has an alternative method to solve - RUCs, it should be specified here, e.g., - my_special_plugin.py. - - .. note:: - This option is ignored if `\-\-simulator-plugin` is used. - * - **SCED Options** - - - - - - - * - .. _config_sced-frequency-minutes: - - \-\-sced-frequency-minutes - - sced_frequency_minutes - - Integer. Default=60. - - How often a SCED will be run, in minutes. - Must divide evenly into 60, or be a multiple of 60. - * - \-\-sced-horizon - - sced_horizon - - Integer. Default=1 - - The number of time periods to include in each SCED. - Must be at least 1. - * - .. _config_run-sced-with-persistent-forecast-errors: - - \-\-run-sced-with-persistent-forecast-errors - - run_sced_with_persistent_forecast_errors - - Flag. Default=false. - - If true, then values in SCEDs use persistent forecast errors. - If false, all values in SCEDs use actual values for all time - periods, including future time periods. - See :ref:`forecast_smoothing`. - * - \-\-enforce-sced-shutdown-ramprate - - enforce_sced_shutdown_ramprate - - Flag. Default=false. - - Enforces shutdown ramp-rate constraints in the SCED. - Enabling this option requires a long SCED look-ahead - (at least an hour) to ensure the shutdown ramp-rate - constraints can be statisfied. - * - \-\-sced-network-type - - sced_network_type - - String. Default=ptdf. - - Specifies how the network is represented in SCED models. Choices are: - * ptdf -- power transfer distribution factor representation - * btheta -- b-theta representation - * - \-\-sced-slack-type - - sced_slack_type - - String. Default=every-bus. - - Specifies the type of slack variables to use in SCED models. Choices are: - * every-bus -- slack variables at every system bus - * ref-bus-and-branches -- slack variables at only reference bus and each system branch - * - \-\-sced-solver - - sced_solver - - String. Default=cbc. - - The name of the solver to use for SCEDs. - * - \-\-sced-solver-options - - sced_solver_options - - String. Default=None. - - Solver options applied to all SCED solves. - * - \-\-print-sced - - print_sced - - Flag. Default=false. - - Print results from SCED solves to stdout. - * - \-\-output-sced-initial-conditions - - output_sced_initial_conditions - - Flag. Default=false. - - Print SCED initial conditions to stdout prior to each solve. - * - \-\-output-sced-loads - - output_sced_loads - - Flag. Default=false. - - Print SCED loads to stdout prior to each solve. - * - \-\-write-sced-instances - - write_sced_instances - - Flag. Default=false. - - Save each individual SCED model to a file. The date and - time the SCED was executed is indicated in the file name. - * - **Output Options** - - - - - - - * - \-\-disable-stackgraphs - - disable_stackgraphs - - Flag. Default=false. - - Disable stackgraph generation. - * - \-\-output-max-decimal-places - - output_max_decimal_places - - Integer. Default=6. - - The number of decimal places to output to summary files. - Output is rounded to the specified accuracy. - * - \-\-output-solver-logs - - output_solver_logs - - Flag. Default=false. - - Whether to print solver logs to stdout during execution. - * - **Miscellaneous Options** - - - - - - - * - \-\-reserve-factor - - reserve_factor - - Float. Default=0.0. - - The reserve factor, expressed as a constant fraction of demand, for - spinning reserves at each time period of the simulation. Applies to - both RUC and SCED models. - * - \-\-no-startup-shutdown-curves - - no_startup_shutdown_curves - - Flag. Default=False. - - If true, then do not infer startup/shutdown ramping curves when starting-up - and shutting-down thermal generators. - * - \-\-symbolic-solver-labels - - symbolic_solver_labels - - Flag. Default=False. - - Whether to use symbol names derived from the model when interfacing with - the solver. - * - \-\-enable-quick-start-generator-commitment - - enable_quick_start_generator_commitment - - Flag. Default=False. - - Whether to allow quick start generators to be committed if load shedding - would otherwise occur. - * - **Market and Pricing Options** - - - - - - - * - .. _config_compute-market-settlements: - - \-\-compute-market-settlements - - compute_market_settlements - - Flag. Default=False. - - Whether to solve a day-ahead market as well as real-time market and - report the daily profit for each generator based on the computed prices. - * - \-\-day-ahead-pricing - - day_ahead_pricing - - String. Default=aCHP. - - The pricing mechanism to use for the day-ahead market. Choices are: - * LMP -- locational marginal price - * ELMP -- enhanced locational marginal price - * aCHP -- approximated convex hull price. - * - \-\-price-threshold - - price_threshold - - Float. Default=10000.0. - - Maximum possible value the price can take. If the price exceeds this - value due to Load Mismatch, then it is set to this value. - * - \-\-reserve-price-threshold - - reserve_price_threshold - - Float. Default=10000.0. - - Maximum possible value the reserve price can take. If the reserve price - exceeds this value, then it is set to this value. - * - **Plugin Options** - - - - - - - * - \-\-plugin - - plugin - - Module. Default=None. - - Python plugins are analyst-provided code that Prescient calls at - various points in the simulation process. See :doc:`plugins` for - details. - - After Prescient has been initialized, the configuration object's - `plugin` property holds plugin-specific setting values. - * - \-\-simulator-plugin - - simulator_plugin - - Module. Default=None. - - A module that implements the engine interface. Use this option - to replace methods that setup and solve RUC and SCED models with - custom implementations. +Configuration Options +===================== + +.. contents:: + :local: + +Overview +-------- + +Prescient configuration options are used to indicate how +the Prescient simulation should be run. Configuration +options can be specified on the command line, in a text +configuration file, or in code, depending on how Prescient +is launched (see :doc:`run`). + +Each configuration option has a name, a data type, and a default value. +The name used on the command line and the name used in code vary slightly. +For example, the number of days to simulate is specified as `\-\-num-days` +on the command line, and `num_days` in code. + +Option Data Types +----------------- + +Most options use self-explanatory data types like `String`, +`Integer`, and `Float`, but some data types require more +explanation and may be specified in code in ways that are unavailable +on the command line: + +.. list-table:: Configuration Data Types + :header-rows: 1 + :class: table-top-align-cells table-wrap-headers + + * - Data type + - Command-line/config file usage + - In-code usage + * - Path + - A text string that refers to a file or folder. Can be + relative or absolute, and may include special characters + such as `~`. + - Same as command-line + * - Date + - A string that can be converted to a date, such as *1776-07-04*. + - Either a string or a datetime object. + * - Flag + - Simply include the option to set it to true. For example, the command + below sets `simulate_out_of_sample` to true:: + + runner.py --simulate-out-of-sample + + - Set the option by assigning True or False:: + + config.simulate_out_of_sample = True + * - Module + - Refer to a python module in one of the following ways: + + * The name of a python module (such as `prescient.simulator.prescient`) + * The path to a python file (such as `prescient/simulator/prescient.py`) + - In addition to the two string options available to the command-line, + code may also use a python module object. For example:: + + import my_custom_data_provider + config.data_provider = my_custom_data_provider + +List of Configuration Options +----------------------------- + +The table below describes all available configuration options. + +.. list-table:: Configuration Options + :header-rows: 1 + :widths: 20 20 25 35 + :class: table-top-align-cells table-wrap-headers + + * - Command-line Option + - In-Code Configuration Property + - Argument + - Description + * - \-\-config-file + - config_file + - Path. Default=None. + - Path to a file holding configuration options. Can be absolute or + relative. Cannot be set in code directly on a configuration object, but + can be passed to a configuration object's `parse_args()` function: + + .. code-block:: python + + p = Prescient() + p.config.parse_args(["--config-file", "my-config.txt"]) + + See :ref:`launch-with-runner-py` for a description of + configuration file syntax. + + * - **General Options** + - + - + - + * - \-\-start-date + - start_date + - Date. Default=2020-01-01. + - The start date for the simulation. + * - \-\-num-days + - num_days + - Integer. Default=7 + - The number of days to simulate. + * - **Data Options** + - + - + - + * - \-\-data-path + + or + + \-\-data-directory + - data_path + - Path. Default=input_data. + - Path to a file or folder where input data is located. Whether it + should be a file or a folder depends on the input format. See :doc:`input`. + * - \-\-input-format + - input_format + - String. Default=rts_gmlc. + - The format of the input data. Valid values are *dat* and *rts_gmlc*. + Ignored when using a custom data provider. See :doc:`input`. + * - \-\-data-provider + - data_provider + - Module. Default=No custom data provider. + - A python module with a custom data provider that will supply + data to Prescient during the simulation. Don't specify this option + unless you are using a custom data provider; use data_path and + input_format instead. + See :ref:`custom-data-providers`. + * - \-\-output-directory + - output_directory + - Path. Default=outdir. + - The path to the root directory to which all generated simulation + output files and associated data are written. + * - **RUC Options** + - + - + - + * - \-\-ruc_every-hours + - ruc_every_hours + - Integer. Default=24 + - How often a RUC is executed, in hours. Default is 24. + Must be a divisor of 24. + * - \-\-ruc-execution-hour + - ruc_execution_hour + - Integer. Default=16 + - Specifies an hour of the day the RUC process is executed. + If multiple RUCs are executed each day (because `ruc_every_hours` + is less than 24), any of the execution times may be specified. + Negative values indicate hours before midnight, positive after. + * - .. _config_ruc-horizon: + + \-\-ruc-horizon + - ruc_horizon + - Integer. Default=48 + - The number of hours to include in each RUC. + Must be >= `ruc_every_hours` and <= 48. + * - .. _config_ruc-prescience-hour: + + \-\-ruc-prescience-hour + - ruc_prescience_hour + - Integer. Default=0. + - The number of initial hours of each RUC in which linear blending of + forecasts and actual values is done, making some near-term + forecasts more accurate. + * - \-\-run-ruc-with-next-day-data + - run_ruc_with_next_day_data + - Flag. Default=false. + - If false (the default), never use more than 24 hours of + forecast data even if the RUC horizon is longer than 24 + hours. Instead, infer values beyond 24 hours. + + If true, use forecast data for the full RUC horizon. + * - \-\-simulate-out-of-sample + - simulate_out_of_sample + - Flag. Default=false. + - If false, use forecast input data as both forecasts and actual + values; the actual value input data is ignored. + + If true, values for the current simulation time are taken from + the actual value input, and actual values are used to blend + near-term values if `ruc_prescience_hour` is non-zero. + * - \-\-ruc-network-type + - ruc_network_type + - String. Default=ptdf. + - Specifies how the network is represented in RUC models. Choices are: + * ptdf -- power transfer distribution factor representation + * btheta -- b-theta representation + * - \-\-ruc-slack-type + - ruc_slack_type + - String. Default=every-bus. + - Specifies the type of slack variables to use in the RUC model formulation. + Choices are: + * every-bus -- slack variables at every system bus + * ref-bus-and-branches -- slack variables at only reference bus and each system branch + * - \-\-deterministic-ruc-solver + - deterministic_ruc_solver + - String. Default=cbc. + - The name of the solver to use for RUCs. + * - \-\-deterministic-ruc-solver-options + - deterministic_ruc_solver_options + - String. Default=None. + - Solver options applied to all RUC solves. + * - \-\-ruc-mipgap + - ruc_mipgap + - Float. Default=0.01. + - The mipgap for all deterministic RUC solves. + * - \-\-output-ruc-initial-conditions + - output_ruc_initial_conditions + - Flag. Default=false. + - Print initial conditions to stdout prior to each RUC solve. + * - \-\-output-ruc-solutions + - output_ruc_solutions + - Flag. Default=false. + - Print RUC solution to stdout after each RUC solve. + * - \-\-write-deterministic-ruc-instances + - write_deterministic_ruc_instances + - Flag. Default=false. + - Save each individual RUC model to a file. The date and + time the RUC was executed is indicated in the file name. + * - \-\-deterministic-ruc-solver-plugin + - deterministic_ruc_solver_plugin + - Module. Default=None. + - If the user has an alternative method to solve + RUCs, it should be specified here, e.g., + my_special_plugin.py. + + .. note:: + This option is ignored if `\-\-simulator-plugin` is used. + * - **SCED Options** + - + - + - + * - .. _config_sced-frequency-minutes: + + \-\-sced-frequency-minutes + - sced_frequency_minutes + - Integer. Default=60. + - How often a SCED will be run, in minutes. + Must divide evenly into 60, or be a multiple of 60. + * - \-\-sced-horizon + - sced_horizon + - Integer. Default=1 + - The number of time periods to include in each SCED. + Must be at least 1. + * - .. _config_run-sced-with-persistent-forecast-errors: + + \-\-run-sced-with-persistent-forecast-errors + - run_sced_with_persistent_forecast_errors + - Flag. Default=false. + - If true, then values in SCEDs use persistent forecast errors. + If false, all values in SCEDs use actual values for all time + periods, including future time periods. + See :ref:`forecast_smoothing`. + * - \-\-enforce-sced-shutdown-ramprate + - enforce_sced_shutdown_ramprate + - Flag. Default=false. + - Enforces shutdown ramp-rate constraints in the SCED. + Enabling this option requires a long SCED look-ahead + (at least an hour) to ensure the shutdown ramp-rate + constraints can be statisfied. + * - \-\-sced-network-type + - sced_network_type + - String. Default=ptdf. + - Specifies how the network is represented in SCED models. Choices are: + * ptdf -- power transfer distribution factor representation + * btheta -- b-theta representation + * - \-\-sced-slack-type + - sced_slack_type + - String. Default=every-bus. + - Specifies the type of slack variables to use in SCED models. Choices are: + * every-bus -- slack variables at every system bus + * ref-bus-and-branches -- slack variables at only reference bus and each system branch + * - \-\-sced-solver + - sced_solver + - String. Default=cbc. + - The name of the solver to use for SCEDs. + * - \-\-sced-solver-options + - sced_solver_options + - String. Default=None. + - Solver options applied to all SCED solves. + * - \-\-print-sced + - print_sced + - Flag. Default=false. + - Print results from SCED solves to stdout. + * - \-\-output-sced-initial-conditions + - output_sced_initial_conditions + - Flag. Default=false. + - Print SCED initial conditions to stdout prior to each solve. + * - \-\-output-sced-loads + - output_sced_loads + - Flag. Default=false. + - Print SCED loads to stdout prior to each solve. + * - \-\-write-sced-instances + - write_sced_instances + - Flag. Default=false. + - Save each individual SCED model to a file. The date and + time the SCED was executed is indicated in the file name. + * - **Output Options** + - + - + - + * - \-\-disable-stackgraphs + - disable_stackgraphs + - Flag. Default=false. + - Disable stackgraph generation. + * - \-\-output-max-decimal-places + - output_max_decimal_places + - Integer. Default=6. + - The number of decimal places to output to summary files. + Output is rounded to the specified accuracy. + * - \-\-output-solver-logs + - output_solver_logs + - Flag. Default=false. + - Whether to print solver logs to stdout during execution. + * - **Miscellaneous Options** + - + - + - + * - \-\-reserve-factor + - reserve_factor + - Float. Default=0.0. + - The reserve factor, expressed as a constant fraction of demand, for + spinning reserves at each time period of the simulation. Applies to + both RUC and SCED models. + * - \-\-no-startup-shutdown-curves + - no_startup_shutdown_curves + - Flag. Default=False. + - If true, then do not infer startup/shutdown ramping curves when starting-up + and shutting-down thermal generators. + * - \-\-symbolic-solver-labels + - symbolic_solver_labels + - Flag. Default=False. + - Whether to use symbol names derived from the model when interfacing with + the solver. + * - \-\-enable-quick-start-generator-commitment + - enable_quick_start_generator_commitment + - Flag. Default=False. + - Whether to allow quick start generators to be committed if load shedding + would otherwise occur. + * - **Market and Pricing Options** + - + - + - + * - .. _config_compute-market-settlements: + + \-\-compute-market-settlements + - compute_market_settlements + - Flag. Default=False. + - Whether to solve a day-ahead market as well as real-time market and + report the daily profit for each generator based on the computed prices. + * - \-\-day-ahead-pricing + - day_ahead_pricing + - String. Default=aCHP. + - The pricing mechanism to use for the day-ahead market. Choices are: + * LMP -- locational marginal price + * ELMP -- enhanced locational marginal price + * aCHP -- approximated convex hull price. + * - \-\-price-threshold + - price_threshold + - Float. Default=10000.0. + - Maximum possible value the price can take. If the price exceeds this + value due to Load Mismatch, then it is set to this value. + * - \-\-reserve-price-threshold + - reserve_price_threshold + - Float. Default=10000.0. + - Maximum possible value the reserve price can take. If the reserve price + exceeds this value, then it is set to this value. + * - **Plugin Options** + - + - + - + * - \-\-plugin + - plugin + - Module. Default=None. + - Python plugins are analyst-provided code that Prescient calls at + various points in the simulation process. See :doc:`plugins` for + details. + + After Prescient has been initialized, the configuration object's + `plugin` property holds plugin-specific setting values. + * - \-\-simulator-plugin + - simulator_plugin + - Module. Default=None. + - A module that implements the engine interface. Use this option + to replace methods that setup and solve RUC and SCED models with + custom implementations. diff --git a/doc/OnlineDocs/source/tasks/index.rst b/doc/OnlineDocs/source/tasks/index.rst index 9de1e544..67358c81 100644 --- a/doc/OnlineDocs/source/tasks/index.rst +++ b/doc/OnlineDocs/source/tasks/index.rst @@ -1,13 +1,13 @@ -Using Prescient -=============== - -.. toctree:: - :maxdepth: 2 - - install.rst - run.rst - configure.rst - input.rst - output.rst - plugins.rst +Using Prescient +=============== + +.. toctree:: + :maxdepth: 2 + + install.rst + run.rst + configure.rst + input.rst + output.rst + plugins.rst \ No newline at end of file diff --git a/doc/OnlineDocs/source/tasks/install.rst b/doc/OnlineDocs/source/tasks/install.rst index 96747c32..1008fd14 100644 --- a/doc/OnlineDocs/source/tasks/install.rst +++ b/doc/OnlineDocs/source/tasks/install.rst @@ -24,7 +24,7 @@ Prescient requires a mixed-integer linear programming (MILP) solver that is comp and commercial solvers such as CPLEX, Gurobi, or Xpress. The specific mechanics of installing a solver is specific to the solver and/or the platform. An easy way to -install an open source solver on Linux and Mac is to install the CBC Anaconda package into the +install an open source solver on Linux and Mac is to install the CBC Anaconda package into the current conda environment:: conda install -c conda-forge coincbc @@ -47,7 +47,7 @@ Instructions to install other solvers can be found :doc:`here ` Install Prescient Using Pip ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Prescient is available as a python package that can be installed using pip. To install the latest +Prescient is available as a python package that can be installed using pip. To install the latest release of Prescient use the following command: pip install gridx-prescient @@ -57,7 +57,7 @@ Be sure the intended python environment is active before issuing the command abo Install Prescient From Source ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You may want to install from source if you want to use the latest pre-release +You may want to install from source if you want to use the latest pre-release version of the code, or if you want to modify/contribute to the code yourself. The steps required to install Prescient from source are described below: @@ -86,30 +86,30 @@ Once you have create the new environment, make it the active environment:: conda activate prescient -If you are using something other than Anaconda to manage your python environment, use the -information in `environment.yml` to identify which packages to install. +If you are using something other than Anaconda to manage your python environment, use the +information in `environment.yml` to identify which packages to install. .. _install-prescient-package: Install Egret ------------- -When installing Prescient from the latest version of the source code, Egret may need -to be installed manually because pre-release versions of Prescient sometimes depend -on pre-release versions of EGRET. Install EGRET from source according to the instructions +When installing Prescient from the latest version of the source code, Egret may need +to be installed manually because pre-release versions of Prescient sometimes depend +on pre-release versions of EGRET. Install EGRET from source according to the instructions `here `. Install the Prescient python package ------------------------------------ -The steps above configure a python environment with Prescient's prerequisites. Now we must +The steps above configure a python environment with Prescient's prerequisites. Now we must install Prescient itself. From the prescient python environment, issue the following command:: pip install -e . -This will update the active python environment to include Prescient's source code. Any changes to Prescient +This will update the active python environment to include Prescient's source code. Any changes to Prescient source code will take affect each time Prescient is run. -This command will also install a few utilities that Prescient users may find useful, +This command will also install a few utilities that Prescient users may find useful, including `runner.py` (see :doc:`run`). Verify your installation diff --git a/doc/OnlineDocs/source/tasks/install_solvers.rst b/doc/OnlineDocs/source/tasks/install_solvers.rst index f9e84a32..e488e6e8 100644 --- a/doc/OnlineDocs/source/tasks/install_solvers.rst +++ b/doc/OnlineDocs/source/tasks/install_solvers.rst @@ -36,7 +36,7 @@ Gurobi ------ Gurobi is a highly regarded commercial solver. Gurobi requires a valid -license to be used by Prescient. See the documentation on the +license to be used by Prescient. See the documentation on the `Gurobi `_ website for instructions on how to acquire and install a license. diff --git a/doc/OnlineDocs/source/tasks/output.rst b/doc/OnlineDocs/source/tasks/output.rst index c1967434..9dc2ac85 100644 --- a/doc/OnlineDocs/source/tasks/output.rst +++ b/doc/OnlineDocs/source/tasks/output.rst @@ -1,6 +1,6 @@ -Results and Statistics Output ------------------------------ - -.. admonition:: Under Construction - - Documentation coming soon +Results and Statistics Output +----------------------------- + +.. admonition:: Under Construction + + Documentation coming soon diff --git a/doc/OnlineDocs/source/tasks/plugins.rst b/doc/OnlineDocs/source/tasks/plugins.rst index b664c56b..927008a8 100644 --- a/doc/OnlineDocs/source/tasks/plugins.rst +++ b/doc/OnlineDocs/source/tasks/plugins.rst @@ -1,6 +1,6 @@ -Customizing Prescient with Plugins -================================== - -.. admonition:: Under Construction - +Customizing Prescient with Plugins +================================== + +.. admonition:: Under Construction + Documentation coming soon \ No newline at end of file diff --git a/doc/OnlineDocs/source/tasks/run.rst b/doc/OnlineDocs/source/tasks/run.rst index 82d7ce1b..480eab6e 100644 --- a/doc/OnlineDocs/source/tasks/run.rst +++ b/doc/OnlineDocs/source/tasks/run.rst @@ -1,186 +1,186 @@ -.. highlight:: none - -Running Prescient -================= - -There are three ways to launch and run Prescient: - -* With a configuration file, :ref:`using runner.py` -* With command line options, :ref:`using the prescient.simulator module` -* From python code, :ref:`using in-code configuration` - -In all three cases, the analyst supplies configuration values that -identify input data and dictate which options to use during -the Prescient simulation. Configuration options can be specified in -a configuration file, on the command line, in-code, or a combination -of these methods, depending on how Prescient is launched. - -To see what configuration options are available, see :doc:`./configure`. - -.. _launch-with-runner-py: - -Launch with runner.py ---------------------- - -Prescient can be run using `runner.py`, a utility which is installed -along with Prescient (see :ref:`install-prescient-package`). -Before executing `runner.py`, you must create a configuration file -indicating how Prescient should be run. Here is an example of a configuration -file that can be used with `runner.py`:: - - command/exec simulator.py - --data-directory=example_scenario_input - --output-directory=example_scenario_output - --input-format=rts-gmlc - --run-sced-with-persistent-forecast-errors - --start-date=07-11-2024 - --num-days=7 - --sced-horizon=1 - --sced-frequency-minutes=10 - --ruc-horizon=36 - -Because runner.py can potentially be used for more than launching -Prescient, the first line of the configuration file must match the line -shown in the example above. Otherwise runner.py won't know that you -intend to run Prescient. - -All subsequent lines set the value of a configuration option. Configuration -options are described in :doc:`configure`. - -Once you have the configuration file prepared, you can launch Prescient -using the following command:: - - runner.py config.txt - -where `config.txt` should be replaced with the name of your configuration file. - -.. _launch-with-prescient-module: - -Launch with the `prescient.simulator` module --------------------------------------------- - -Another way to run Prescient is to execute the `prescient.simulator` module:: - - python -m prescient.simulator - -where `options` specifies the configuration options for the run. An example might -be something like this:: - - python -m prescient.simulator --data-directory=example_scenario_input --output-directory=example_scenario_output --input-format=rts-gmlc --run-sced-with-persistent-forecast-errors --start-date=07-11-2024 --num-days=7 --sced-horizon=1 --sced-frequency-minutes=10 --ruc-horizon=36 - -Configuration options can also be specified in a configuration file:: - - python -m prescient.simulator --config-file=config.txt - -You can combine the `--config-file` option with other command line options. The contents of the configuration -file are effectively inserted into the command line at the location of the `--config-file` option. You can -override values in a configuration file by repeating the option at some point after the `--config-file` option. - -Running the `prescient.simulator` module allows you to run Prescient without explicitly installing it, as long -as Prescient is found in the python module search path. - -.. _launch-with-code: - -Running Prescient from python code ----------------------------------- - -Prescient can be configured and launched from python code: - -.. code-block:: python - - from prescient.simulator import Prescient - - Prescient().simulate( - data_path='deterministic_scenarios', - simulate_out_of_sample=True, - run_sced_with_persistent_forecast_errors=True, - output_directory='deterministic_simulation_output', - start_date='07-10-2020', - num_days=7, - sced_horizon=4, - reserve_factor=0.0, - deterministic_ruc_solver='cbc', - sced_solver='cbc', - sced_frequency_minutes=60, - ruc_horizon=36, - enforce_sced_shutdown_ramprate=True, - no_startup_shutdown_curves=True) - -The code example above creates an instance of the Prescient class and passes -configuration options to its `simulate()` method. An alternative is to set -values on a configuration object, and then run the simulation after configuration -is done: - -.. code-block:: python - - from prescient.simulator import Prescient - - p = Prescient() - - config = p.config - config.data_path='deterministic_scenarios' - config.simulate_out_of_sample=True - config.run_sced_with_persistent_forecast_errors=True - config.output_directory='deterministic_simulation_output' - config.start_date='07-10-2020' - config.num_days=7 - config.sced_horizon=4 - config.reserve_factor=0.0 - config.deterministic_ruc_solver='cbc' - config.sced_solver='cbc' - config.sced_frequency_minutes=60 - config.ruc_horizon=36 - config.enforce_sced_shutdown_ramprate=True - config.no_startup_shutdown_curves=True - - p.simulate() - -A third option is to store configuration values in a `dict`, which can potentially -be shared among multiple runs: - -.. code-block:: python - - from prescient.simulator import Prescient - - options = { - 'data_path':'deterministic_scenarios', - 'simulate_out_of_sample':True, - 'run_sced_with_persistent_forecast_errors':True, - 'output_directory':'deterministic_simulation_output' - } - - Prescient().simulate(**options) - -These three methods can be used together quite flexibly. The example below -demonstrates a combination of approaches to configuring a prescient run: - -.. code-block:: python - - from prescient.simulator import Prescient - - simulator = Prescient() - - # Set some configuration options using the simulator's config object - config = simulator.config - config.data_path='deterministic_scenarios' - config.simulate_out_of_sample=True - config.run_sced_with_persistent_forecast_errors=True - config.output_directory='deterministic_simulation_output' - - # Others will be stored in a dictionary that can - # potentially be shared among multiple prescient runs - options = { - 'start_date':'07-10-2020', - 'sced_horizon':4, - 'reserve_factor':0.0, - 'deterministic_ruc_solver':'cbc', - 'sced_solver':'cbc', - 'sced_frequency_minutes':60, - 'ruc_horizon':36, - 'enforce_sced_shutdown_ramprate':True, - 'no_startup_shutdown_curves':True, - } - - # And finally, pass the dictionary to the simulate() method, - # along with an additional function argument. - simulator.simulate(**options, num_days=7) +.. highlight:: none + +Running Prescient +================= + +There are three ways to launch and run Prescient: + +* With a configuration file, :ref:`using runner.py` +* With command line options, :ref:`using the prescient.simulator module` +* From python code, :ref:`using in-code configuration` + +In all three cases, the analyst supplies configuration values that +identify input data and dictate which options to use during +the Prescient simulation. Configuration options can be specified in +a configuration file, on the command line, in-code, or a combination +of these methods, depending on how Prescient is launched. + +To see what configuration options are available, see :doc:`./configure`. + +.. _launch-with-runner-py: + +Launch with runner.py +--------------------- + +Prescient can be run using `runner.py`, a utility which is installed +along with Prescient (see :ref:`install-prescient-package`). +Before executing `runner.py`, you must create a configuration file +indicating how Prescient should be run. Here is an example of a configuration +file that can be used with `runner.py`:: + + command/exec simulator.py + --data-directory=example_scenario_input + --output-directory=example_scenario_output + --input-format=rts-gmlc + --run-sced-with-persistent-forecast-errors + --start-date=07-11-2024 + --num-days=7 + --sced-horizon=1 + --sced-frequency-minutes=10 + --ruc-horizon=36 + +Because runner.py can potentially be used for more than launching +Prescient, the first line of the configuration file must match the line +shown in the example above. Otherwise runner.py won't know that you +intend to run Prescient. + +All subsequent lines set the value of a configuration option. Configuration +options are described in :doc:`configure`. + +Once you have the configuration file prepared, you can launch Prescient +using the following command:: + + runner.py config.txt + +where `config.txt` should be replaced with the name of your configuration file. + +.. _launch-with-prescient-module: + +Launch with the `prescient.simulator` module +-------------------------------------------- + +Another way to run Prescient is to execute the `prescient.simulator` module:: + + python -m prescient.simulator + +where `options` specifies the configuration options for the run. An example might +be something like this:: + + python -m prescient.simulator --data-directory=example_scenario_input --output-directory=example_scenario_output --input-format=rts-gmlc --run-sced-with-persistent-forecast-errors --start-date=07-11-2024 --num-days=7 --sced-horizon=1 --sced-frequency-minutes=10 --ruc-horizon=36 + +Configuration options can also be specified in a configuration file:: + + python -m prescient.simulator --config-file=config.txt + +You can combine the `--config-file` option with other command line options. The contents of the configuration +file are effectively inserted into the command line at the location of the `--config-file` option. You can +override values in a configuration file by repeating the option at some point after the `--config-file` option. + +Running the `prescient.simulator` module allows you to run Prescient without explicitly installing it, as long +as Prescient is found in the python module search path. + +.. _launch-with-code: + +Running Prescient from python code +---------------------------------- + +Prescient can be configured and launched from python code: + +.. code-block:: python + + from prescient.simulator import Prescient + + Prescient().simulate( + data_path='deterministic_scenarios', + simulate_out_of_sample=True, + run_sced_with_persistent_forecast_errors=True, + output_directory='deterministic_simulation_output', + start_date='07-10-2020', + num_days=7, + sced_horizon=4, + reserve_factor=0.0, + deterministic_ruc_solver='cbc', + sced_solver='cbc', + sced_frequency_minutes=60, + ruc_horizon=36, + enforce_sced_shutdown_ramprate=True, + no_startup_shutdown_curves=True) + +The code example above creates an instance of the Prescient class and passes +configuration options to its `simulate()` method. An alternative is to set +values on a configuration object, and then run the simulation after configuration +is done: + +.. code-block:: python + + from prescient.simulator import Prescient + + p = Prescient() + + config = p.config + config.data_path='deterministic_scenarios' + config.simulate_out_of_sample=True + config.run_sced_with_persistent_forecast_errors=True + config.output_directory='deterministic_simulation_output' + config.start_date='07-10-2020' + config.num_days=7 + config.sced_horizon=4 + config.reserve_factor=0.0 + config.deterministic_ruc_solver='cbc' + config.sced_solver='cbc' + config.sced_frequency_minutes=60 + config.ruc_horizon=36 + config.enforce_sced_shutdown_ramprate=True + config.no_startup_shutdown_curves=True + + p.simulate() + +A third option is to store configuration values in a `dict`, which can potentially +be shared among multiple runs: + +.. code-block:: python + + from prescient.simulator import Prescient + + options = { + 'data_path':'deterministic_scenarios', + 'simulate_out_of_sample':True, + 'run_sced_with_persistent_forecast_errors':True, + 'output_directory':'deterministic_simulation_output' + } + + Prescient().simulate(**options) + +These three methods can be used together quite flexibly. The example below +demonstrates a combination of approaches to configuring a prescient run: + +.. code-block:: python + + from prescient.simulator import Prescient + + simulator = Prescient() + + # Set some configuration options using the simulator's config object + config = simulator.config + config.data_path='deterministic_scenarios' + config.simulate_out_of_sample=True + config.run_sced_with_persistent_forecast_errors=True + config.output_directory='deterministic_simulation_output' + + # Others will be stored in a dictionary that can + # potentially be shared among multiple prescient runs + options = { + 'start_date':'07-10-2020', + 'sced_horizon':4, + 'reserve_factor':0.0, + 'deterministic_ruc_solver':'cbc', + 'sced_solver':'cbc', + 'sced_frequency_minutes':60, + 'ruc_horizon':36, + 'enforce_sced_shutdown_ramprate':True, + 'no_startup_shutdown_curves':True, + } + + # And finally, pass the dictionary to the simulate() method, + # along with an additional function argument. + simulator.simulate(**options, num_days=7) From bfcd4de697b2be3b6ec63e1207be9159b4b41ef5 Mon Sep 17 00:00:00 2001 From: Darryl Melander Date: Tue, 1 Aug 2023 18:08:46 -0600 Subject: [PATCH 2/4] Simplify callback names to avoid confusion. The after_get_initial_* functions make more sense if you don't call it a forecast model or actuals model, so I changed the following callback names: * after_get_initial_actuals_model_for_sced * after_get_initial_forecast_model_for_sced * after_get_initial_actuals_model_for_simulation_actuals --- prescient/engine/egret/egret_plugin.py | 6 +-- prescient/plugins/internal.py | 6 +-- prescient/plugins/plugin_registration.py | 47 ++++++++++++------------ 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/prescient/engine/egret/egret_plugin.py b/prescient/engine/egret/egret_plugin.py index 80315832..8dd5101a 100644 --- a/prescient/engine/egret/egret_plugin.py +++ b/prescient/engine/egret/egret_plugin.py @@ -115,7 +115,7 @@ def create_sced_instance(data_provider:DataProvider, assert current_state is not None sced_md = data_provider.get_initial_actuals_model(options, sced_horizon, current_state.minutes_per_step) - options.plugin_context.callback_manager.invoke_after_get_initial_actuals_model_for_sced_callbacks( + options.plugin_context.callback_manager.invoke_after_get_initial_model_for_sced_callbacks( options, sced_md) # Set initial state @@ -391,7 +391,7 @@ def create_deterministic_ruc(options, # Create a new model md = data_provider.get_initial_forecast_model(options, ruc_horizon, 60) - options.plugin_context.callback_manager.invoke_after_get_initial_forecast_model_for_ruc_callbacks( + options.plugin_context.callback_manager.invoke_after_get_initial_model_for_ruc_callbacks( options, md) initial_ruc = current_state is None or current_state.timestep_count == 0 @@ -642,7 +642,7 @@ def create_simulation_actuals( # Get a new model total_step_count = options.ruc_horizon * 60 // step_size_minutes md = data_provider.get_initial_actuals_model(options, total_step_count, step_size_minutes) - options.plugin_context.callback_manager.invoke_after_get_initial_actuals_model_for_simulation_actuals_callbacks( + options.plugin_context.callback_manager.invoke_after_get_initial_model_for_simulation_actuals_callbacks( options, md) # Fill it in with data diff --git a/prescient/plugins/internal.py b/prescient/plugins/internal.py index ca13be17..371ea2e7 100644 --- a/prescient/plugins/internal.py +++ b/prescient/plugins/internal.py @@ -15,9 +15,9 @@ class _StatisticsSubscribers(NamedTuple): callbacks = ['options_preview', 'update_operations_stats', - 'after_get_initial_actuals_model_for_sced', - 'after_get_initial_forecast_model_for_ruc', - 'after_get_initial_actuals_model_for_simulation_actuals', + 'after_get_initial_model_for_sced', + 'after_get_initial_model_for_ruc', + 'after_get_initial_model_for_simulation_actuals', 'after_ruc_generation', 'after_ruc_activation', 'before_operations_solve', diff --git a/prescient/plugins/plugin_registration.py b/prescient/plugins/plugin_registration.py index a04026bb..c47508dd 100644 --- a/prescient/plugins/plugin_registration.py +++ b/prescient/plugins/plugin_registration.py @@ -8,6 +8,7 @@ from prescient.simulator.simulator import Simulator from prescient.engine.abstract_types import OperationsModel, RucModel from prescient.simulator.config import PrescientConfig + from prescient.simulator.data_manager import RucPlan from pyomo.common.fileutils import import_file class PluginRegistrationContext: @@ -26,8 +27,8 @@ def __init__(self): self._callback_manager = PluginCallbackManager() def register_plugin( - self, - plugin_module:'module', + self, + plugin_module:'module', config: PrescientConfig, plugin_config: ConfigDict) -> None: ''' Allow a plugin module to register for callbacks @@ -36,7 +37,7 @@ def register_plugin( this registration context as an argument. The register_plugins method should use the context to register whatever callbacks are appropriate for the plugin. The method is also provided with the - PrescientConfig to be used in the simulation, as well as the + PrescientConfig to be used in the simulation, as well as the plugin-specific portion of the configuration. ''' register_func = getattr(plugin_module, "register_plugins", None) @@ -45,7 +46,7 @@ def register_plugin( register_func(self, config, plugin_config) def register_for_operations_stats( - self, + self, callback: Callable[[OperationsStats], None] ) -> None: ''' @@ -56,7 +57,7 @@ def register_for_operations_stats( self.callback_manager.register_operations_stats_callback(callback) def register_for_hourly_stats( - self, + self, callback: Callable[[HourlyStats], None] ) -> None: ''' @@ -67,7 +68,7 @@ def register_for_hourly_stats( self.callback_manager.register_hourly_stats_callback(callback) def register_for_daily_stats( - self, + self, callback: Callable[[DailyStats], None] ) -> None: ''' @@ -78,7 +79,7 @@ def register_for_daily_stats( self.callback_manager.register_daily_stats_callback(callback) def register_for_overall_stats( - self, + self, callback: Callable[[OverallStats], None] ) -> None: ''' @@ -89,7 +90,7 @@ def register_for_overall_stats( self.callback_manager.register_overall_stats_callback(callback) def register_options_preview_callback( - self, + self, callback: Callable[[Options], None] ) -> None: ''' Request a method be called after options have been parsed, but before they @@ -98,7 +99,7 @@ def register_options_preview_callback( self.callback_manager.register_options_preview_callback(callback) def register_initialization_callback( - self, + self, callback: Callable[[Options, Simulator], None] ) -> None: ''' Request a method be called after core prescient objects have been initialized, but @@ -106,32 +107,32 @@ def register_initialization_callback( ''' self.callback_manager.register_initialization_callback(callback) - def register_after_get_initial_actuals_model_for_sced_callback( + def register_after_get_initial_model_for_sced_callback( self, callback: Callable[[Options, OperationsModel], None] ) -> None: ''' Request a method to be called immediately after an actuals model for the sced has been generated, but before any data is loaded into it. ''' - self.callback_manager.register_after_get_initial_actuals_model_for_sced_callback(callback) + self.callback_manager.register_after_get_initial_model_for_sced_callback(callback) - def register_after_get_initial_forecast_model_for_ruc_callback( + def register_after_get_initial_model_for_ruc_callback( self, callback: Callable[[Options, RucModel], None] ) -> None: ''' Request a method to be called immediately after an forecast model for the ruc has been generated, but before any data is loaded into it. ''' - self.callback_manager.register_after_get_initial_forecast_model_for_ruc_callback(callback) + self.callback_manager.register_after_get_initial_model_for_ruc_callback(callback) - def register_after_get_initial_actuals_model_for_simulation_actuals_callback( + def register_after_get_initial_model_for_simulation_actuals_callback( self, callback: Callable[[Options, RucModel], None] ) -> None: ''' Request a method to be called immediately after an actuals model for the simulation_actuals has been generated, but before any data is loaded into it. ''' - self.callback_manager.register_after_get_initial_actuals_model_for_simulation_actuals_callback(callback) + self.callback_manager.register_after_get_initial_model_for_simulation_actuals_callback(callback) def register_finalization_callback( self, @@ -142,7 +143,7 @@ def register_finalization_callback( self.callback_manager.register_finalization_callback(callback) def register_before_ruc_solve_callback( - self, + self, callback: Callable[[Options, Simulator, RucModel, str, int], None] ) -> None: ''' Register a callback to be called before a ruc model is solved. @@ -152,7 +153,7 @@ def register_before_ruc_solve_callback( self.callback_manager.register_before_ruc_solve_callback(callback) def register_after_ruc_generation_callback( - self, + self, callback: Callable[[Options, Simulator, RucPlan, str, int], None] ) -> None: ''' Register a callback to be called after each new RUC plan is generated. @@ -161,9 +162,9 @@ def register_after_ruc_generation_callback( are stored in the DataManager. ''' self.callback_manager.register_after_ruc_generation_callback(callback) - + def register_after_ruc_activation_callback( - self, + self, callback: Callable[[Options, Simulator], None] ): ''' Register a callback to be called after activating a RUC. @@ -175,7 +176,7 @@ def register_after_ruc_activation_callback( self.callback_manager.register_after_ruc_activation_callback(callback) def register_before_operations_solve_callback( - self, + self, callback: Callable[[Options, Simulator, OperationsModel], None] ) -> None: ''' Register a callback to be called before an operations model is solved. @@ -185,7 +186,7 @@ def register_before_operations_solve_callback( self.callback_manager.register_before_operations_solve_callback(callback) def register_after_operations_callback( - self, + self, callback: Callable[[Options, Simulator, OperationsModel, OperationsModel], None] ) -> None: ''' Register a callback to be called after the operations model has been created and @@ -207,7 +208,7 @@ def register_update_operations_stats_callback( self, callback: Callable[[Options, Simulator, OperationsStats], None] ) -> None: - ''' Register a callback to be called after intial statistics have been gathered for an + ''' Register a callback to be called after intial statistics have been gathered for an solved operations model, but before the statistics have been published. The operations stats object may be modified by the registered callback. @@ -239,7 +240,7 @@ def register_before_new_actuals_ruc_callback(self, callback): ''' Register a callback to be called just before an actuals RUC is generated. The callback will be called once for each actuals RUC. It is called after - the corresponding forecast RUC has been created and solved, but before the + the corresponding forecast RUC has been created and solved, but before the actuals RUC is created and solved. ''' raise RuntimeError("This callback is not yet implemented") From 99843cdd74346d174a8cdfec1aab9ad4631cca85 Mon Sep 17 00:00:00 2001 From: Darryl Melander Date: Tue, 1 Aug 2023 18:11:11 -0600 Subject: [PATCH 3/4] Detailed documentation for RUCs, SCEDs, and plugins --- .../image/PrescientSimulationCycle.png | Bin 0 -> 31589 bytes .../source/concepts/ruc_sced_cycle.rst | 38 ++- .../source/reference/detailed_lifecycle.rst | 181 ++++++++++ doc/OnlineDocs/source/reference/index.rst | 4 + doc/OnlineDocs/source/reference/plugins.rst | 317 ++++++++++++++++++ .../source/reference/ruc_details.rst | 64 ++++ .../source/reference/sced_details.rst | 34 ++ doc/OnlineDocs/source/tasks/configure.rst | 20 +- 8 files changed, 639 insertions(+), 19 deletions(-) create mode 100644 doc/OnlineDocs/source/_static/image/PrescientSimulationCycle.png create mode 100644 doc/OnlineDocs/source/reference/detailed_lifecycle.rst create mode 100644 doc/OnlineDocs/source/reference/plugins.rst create mode 100644 doc/OnlineDocs/source/reference/ruc_details.rst create mode 100644 doc/OnlineDocs/source/reference/sced_details.rst diff --git a/doc/OnlineDocs/source/_static/image/PrescientSimulationCycle.png b/doc/OnlineDocs/source/_static/image/PrescientSimulationCycle.png new file mode 100644 index 0000000000000000000000000000000000000000..7aed64bda10fcd7a3db0428fa7bb71ef7035d165 GIT binary patch literal 31589 zcmce-c{tSX`#!8P)-1^uNm?jEg%M(i60#fHkcng)V_zcFC_9qT-LHGS?(06U^E&S^JsouxCO#$_8X6Xj z+iC_hG>31~&>SgZI1GNN(k$=>e-3#VsNbL|Y&$svzR=pKXsgiBlteS{-h+VejIOuM zJZNZG8>s&dHM!*8r=juN)=*P1^1VwQ_J8#Tp1c^e+pe*l^0`Ir^F6umxtW>cZrmwn z>CL2k?@vyha29$jq~SBAi5{D94g2Z(Rpq35B1Fi9LF4OQmyl1G(2d72LUi2hPg8|d zc^l83!N7Q>BktjTY&_gXpk!+$Ea8^z3wb#sqig17x@0?8f8I#y{Os(4;mF$y;TgF{ zxd^xPId9tLF+jsJE{Gc5EC%276GbtR85hEvjgFzfH>2!uWF{zl6;8{4Q=c>L-5DbF z)jR*AR~?s-{!=_IhiQ<$6Ib885EUctZ;g)7&>*YWQ8bV52oY&$5^oeAqPhAEd4%RZ z6M>HAD<_79Cgvh7Kh0^wS89~4)M_KXat0`k@`tnk=fWW(#C4_p7BLr7&&h#QC+EfM zwrS;Qp=Fc9#eRzoDt0t9&9X-c-s5=!675X!S0#zGG>@--VZ~=57F)mcD@Q7lJ+*t( zn5(l5bvoaR6E*j@na9gD!>+wItdW;vp;5k465I-TU8*89RWu9pz2hO{b%7Vf1S4H0 zikAKSrS@1ZgASW*9nU1VO%w@+2cH4`pEykvRV_ZGoXnqsG+YzB z&Rrn>RjEKf15+uzR&3V>4;Q2aC;0hJutb2dXw~Pm%g>pb8_Oo=1W4+U2eEu&@{tRS z-8i@XPcns9km^14Dz(HC&%^5-ZR!**UZQPR;a_DLWz!+Mingdw{XLegC)#RK@TJPL=goKdTuz-N2Q&Jh(yW*Zue0&Sh-#zm zAD(%$F0pybx~h&`s2W;?-puEog(&nFQaVkHq<68yU9LMS(svW2wp<$mN;)mbgJq@X zD9-ZQJwqzY`>T~W_lXTg;fKK~AyrDMN1smRbi2QblAyf1oPih+0E5RaT@9Bdkj#+rCN2S_tv9y{MNpN1+ zjlni$?V_(7O~>~TIpQ65muCF#Vr-n$kiwwF@GCK$nRCVPyfj5Cxtt%{Z+TFIWow-u zn2Zl8$L2>Mk88(StmiI|J`#O^Oz%Hhs@c9+ z-M`T1A#i<1Id63kyeWkq$$p0HO>6j&(Yba}fA%=)LbVqy;u6p9_i&-Rz<{>AiGzkP2m*j z#)`YXPNbooU=?<=tSP@=Rkru}Grrv}zSw}m<&Ej)*AXQH;5pc~Hk-LTs;KSn0vMNMt3>9AM@ZY=?dNdzSSvp|Nagy@%HT}{qA zzx}A=GZ%JYyQL@{9RE$B?Sr?^k{?YMy9}{0#oI6J2~luirD?UR;e#M*Um-@P6~<*| z4V|RWcf;atnSDU`g#oQGl_=ZmEZ^P=8ai5u?zwJatS+@B;2fJCom*~sm z9#!`q`Idv5x7k||SK*Np#Tn2%7j!UIJ&IS+ZP-k`uMbIhr;QSetB-S2v=oes?_C)E zi1}?rVZcAQRV);hOTYssw2w@-N}}W1i8KFc7c7==fp3D@TkqnL=G{1R6@Qg1-G=G= z;g;`8`(W@Ov2kOER2AhK(SXd^6NJ9+4A9TVWQZ>!`}eDg?wPNMYlmP`4*83~sLBZ>oW;vG3ShtH=$@$n87*><}dWIm%FE?mUtZPtA zYrnHcUcFdG3d7=dRJAz0{50`u2-4}n3%2LM$b1D_{?hQ@huqjvUZF@;<10$1SuwZ; zc2uN&duKv4W%ho@bDHrZKTi{9SqbrrE3%3&{hzVCGB`J_SC_S+m`ZBFx;R!Aeu>YA z+858To2;i6+j{k>R_4iv>b_61Xu!JEtq$_{W$c;MkiI_rzWMkX1HMMJc%lqhHeX_! z^>Q@*4s^A4?*jjBg{r=OF-tP*)bgFmPYZMeI$qEZqVC~bzEzQ4O@6=Pu*2W3YETB* ziz>MJ@dcvS?vj38vR_?M#v%mc&WEnsu#u-#eC=^M%FKZ`suXj}!cM+vx>tEJVnX+(>yi5KB-%m98Gb7LQ zCJEWzk=1>LoddRy#7VmaUAY36NXmJk z+AwS)tC79MB}@vUOIXoUftmifsziY@Z$zIk+HA;y-`N0cJw_+O@Gs4S>1NSqQ6!>X z5ubo_SVPF4Y#dC|7>f{ zQ4;kTLW-phlBXA*YHtyY+ad)x4;G8PR}a$~r}canxzf@&Iu!g~c6C)R(tPPpjkQWD zzEy9Qj(=K5OK2VqXq#|7iP>p!<@%D14kucnf0!ySeLlT?<{OF}HYN?WoF-{;uIary~!e zMfQ!oQx=}1t38Vy1}y7HxLSP`f3Ck3b}>UctL9pkkD zxeKEAdrK#tYB9h>%g3&M94+Ivs3iqgt!%K_kqe_cCl}E6IDyW3t^LwuI|6d0UCq;z z6lZ@NVO#4?c08(+{pi5JRgK=!VeN?(2^qkPxzEuxn~SnQTNvXS{k)3x?^3o^>%BV6 zTj=JHku^*(o%yZ;rc*i?X^uJMM3k7haRhltKtIy)A}`81U?`oO-kkh4IlW$X&J5B> z|5>G2C~p?S(vVA}h~|Bynl@DJX0gmk3=0d`N=CGZ1|edH>z^N`{*)KR;1d6?`7u=M zi-UdlJpA9ysA`n6UTB|O4dY$xIJ)|NZh-ABn=&7$z-z?I-&}Z+A>_LB5yeHjR?><0 zryfhQqn^*w`$u`*eRSaG_1OmEuaEPHcb5tNeM-gz4Z+-pu9o5+PFMFy?N|0wF8H3O zxhO=ue6((JxOR=Q0UY*bAOb(Lr9JYn&OR~a_m~XL+fZb~(k3Cr1~jxaqER^~(|vC6 z!Ek2De)4c7E%^i#Z}&y6fBvVyZME$FQv|xtm)FA^nDDjHsYeG7^>7pD)Bw%{4n_GK zEkCfE|Ld!rg@+mezn4?b^8a3LnWrC?heYfwiK!?&9y~*Qe47D!I%<%f|1oAz;sb)P zPCt&OzG@*J9GQ`8y_UGBn2q$`ohq6*WylGq2awiiZLN|yMXz|6vPwztzoTy?zzJY) zFAwS5a6a3>^DL01aYBiPX%4vc%6|ee*wVbJW22| zTMTe>ULEzL0ifc%?HW(A8-z3%diSeh_JurF0GxAYBfy9JrT_gaj&qCDZA|!qAcdN5E6_+;-^_|t)F`cA#JrpLC7?Y5y&HFgoxC=aQYwq#jQ9D z`8`DU|M7qW!vc<;|CIaptJ(UP78Aa#E=by*UJn6mhY{G8O7WqWz?4pcuipkkt@Mlc zzN|&l{ofn({wTIr~LI~N|AcvViq68A4d&VYiWz;+OfMQU8Ex&W(98J@-AWWflZ$EyR`3RtV!Z#T46}Th;1>+ zl^k0MH8|QtM~?6y>$V3#_vQ)S=YO6!O?=D{0waD7pj@J05gFxW6-oTnjT{8yBrJ04 z+x_OFP+QZ$3-M8RKEC+yvlv5O7#9ilrjaq?Axz3n20i`!p(1z5H4;vb2uq!p5IKk( zVxeBF#)m?Ht>yxhzwy8(Ms^`VRTR2g$(_%N=imqZ-pW6TD^-e1;YgyoIz36kMeL4L+Tt(@l%Ou)*fE9r!73K3(V!1B}XVp?0j8||y#9@_CI@IPi^bCP_0CW-WJ zxb-kIHz8!Rt!nZ)#(76Kh#%~>bU#L@+o+a@ppaYY*CiO#8qE2bV$Zi`$579ssr|}C zdZY##4XEF?FxnL4zj7Ya8nB>Wrikl3wpVc;dhTzVQ5fwZ{^({p?e{3TP2%&5@w$QX z+`F6BB`nX7s)Jy&VyKYcY_}vQc_FY${7;d>52lB?NO}y=w`9q}AR_{P{f7yLI%8G@ z>U_a(9+&J-p*YKResBMvuTd
*lnM%!Y^l=HZ^o_Baufkw&!JPDYK+n%q1O z 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 Q*4T9CRW6>%I&FskUjvK*m;e9( literal 0 HcmV?d00001 diff --git a/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst b/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst index b5c0daa9..ddeece79 100644 --- a/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst +++ b/doc/OnlineDocs/source/concepts/ruc_sced_cycle.rst @@ -19,7 +19,7 @@ The RUC Cycle ------------- The RUC cycle periodically generates a RUC plan. A RUC plan consists of two types of -data: a unit commitment schedule and optionally a pricing schedule (when +data: a unit commitment schedule and, optionally, a pricing schedule (when :ref:`compute-market-settlements` is True). The unit commitment schedule indicates which dispatchable generators should be activated or deactivated during @@ -37,22 +37,20 @@ RUC plan covers the time period that starts when it goes into effect and ends just as the next RUC plan becomes active. A RUC plan is based on the current state of the system at the time the plan is -generated (particularly the current dispatch and up- or down-time for dispatchable generators), and on -forecasts for a number of upcoming time periods. The forecasts considered when -forming a RUC plan must extend at least to the end of the RUC's planning period, -but typically extend further into the future in order to avoid poor choices at -the end of the plan ("end effects"). The amount of time to consider when -generating a RUC plan is known as the RUC horizon. A commonly used RUC horizon -is 48 hours. +generated (particularly the current dispatch and up- or down-time for dispatchable +generators), and on forecasts for a number of upcoming time periods. The forecasts +considered when forming a RUC typically extend beyond the end of the RUC's planning +period, to avoid poor choices at the end of the plan ("end effects"). The simulation can be configured to generate RUC plans some number of hours before -they take effect. This is done by specifying a time of day for one of the plans to -be generated. The gap between the specified generation time and the next time a RUC -plan is scheduled to take effect is called the RUC gap. Each RUC plan still covers +they take effect. Each RUC plan still covers the expected time period, from the time the plan takes effect until the next RUC plan takes effect, but its decisions will be based on what is known at the time the RUC plan is generated. +More information about RUCs is found in :doc:`../reference/ruc_details`. + + The SCED Cycle -------------- @@ -68,6 +66,18 @@ at least once an hour. The SCED honors unit commitment decisions made in the RUC whether each generator is committed or not is dictatated by the RUC schedule currently in effect. -Costs are also determined with each SCED, based on dispatchable generation selected by -the SCED process, the commitment and start-up costs as selected by the associated RUC -process, as well as current actual demands and non-dispatchable generation levels. +Costs are determined with each SCED, based on dispatchable generation levels selected by +the SCED process, commitment and start-up decisions selected by the active RUC +plan, and actual demands and non-dispatchable generation levels for the current simulation +time. If market settlement is enabled, market-based generator revenue is also calculated. + +More information about SCEDs is found in :doc:`../reference/sced_details`. + + +.. seealso:: + + A more detailed description of the Prescient simulation process can be found + in the :doc:`../reference/detailed_lifecycle` documentation. + + More information about RUCs and SCEDs is available from + :doc:`../reference/ruc_details` and :doc:`../reference/sced_details`. diff --git a/doc/OnlineDocs/source/reference/detailed_lifecycle.rst b/doc/OnlineDocs/source/reference/detailed_lifecycle.rst new file mode 100644 index 00000000..3a28b71d --- /dev/null +++ b/doc/OnlineDocs/source/reference/detailed_lifecycle.rst @@ -0,0 +1,181 @@ +Detailed Prescient Simulation Lifecycle +======================================= + +As Prescient simulates the operation of a power generation network, the simulation +follows a repeating cycle of Reliability Unit Commitment (RUC) plans and Security +Constrained Economic Dispatch (SCED) plans. This cycle is described at a high level +in the concepts section (see :doc:`../concepts/ruc_sced_cycle`). This page +provides a more detailed description of the simulation process, including plugin +points that provide opportunities for custom code to observe or modify the +simulation. + +.. image:: ../_static/image/PrescientSimulationCycle.png + :class: align-right + +A Prescient simulation consists of three phases: startup, the main simulation +loop, and finalization. Each phase includes one or more tasks that are executed +in a specific order. In the case of the main simulation loop, these tasks are +carried out multiple times, once per SCED during the simulation period. + +The Prescient simulation lifecycle is executed when you run the Prescient +command-line application, or in code when the `simulate()` method is called on +a `prescient.simulator.Prescient` object. + +Startup +------------------ + +The startup phase consists of one-time activities that occur before the main +simulation loop begins. + +Pre-Simulation Startup +...................... + +During the pre-simulation startup task, Prescient carries out activities such +as parsing options, initializing plugins, and setting up data structures. + +First, any plugins specified in the simulation configuration are given an +opportunity to register their callbacks. See :ref:`Identifying Plugins` and +:ref:`Plugin Module Initialization`. + +After plugins have been initialized, two plugin callbacks are called: + + * :ref:`plugin-options_preview` + * :ref:`plugin-initialization` + +After callbacks have been called, the current simulation time is set to midnight of +the :ref:`simulation start date`. + + +The Main Simulation Loop +------------------------ + +The main simulation loop is executed once for every simulation time step, where +the simulation time step duration is the +:ref:`SCED frequency`. The first simulation time +step occurs at midnight of the first day (midnight is the beginning of the day, +not the end). The last simulation time step occurs at the end of the final day +of the simulation, just before midnight of the next day. + +A SCED is solved every time through the loop. Some times through the loop, a RUC may +also be generated and/or activated. + +.. _Generate RUC: + +Generate RUC +............ + +If the current simulation time is a RUC generation hour, a new RUC is generated. +This is either the same timestep the RUC will be activated, or an earlier +timestep if a RUC delay has been specified. See :doc:`ruc_details` for information on the +timing and frequency of RUC generation and its relationship to RUC activation. + +Note that the initial RUC is always generated on the first timestep of the +simulation, even if Prescient has been configured to generate other RUCs earlier +than they are activated. + +If a RUC is generated before its activation time, the first step of the RUC +generation process is to solve a SCED-like model to estimate what the state of the +system will be at the RUC activation time. Solving this model causes a single +callback to be called: + + * :ref:`plugin-after_get_initial_model_for_sced` + +This callback is only called if the RUC is generated in a different timestep than +the RUC will be activated. The initial RUC never triggers this callback. + +As part of the RUC generation process, forecasts and actual values for upcoming +periods are retrieved from the data source and loaded into Egret model. The +callbacks listed below are called as a new batch of values is about to be loaded, +giving plugins an opportunity to load any custom data they may need: + + * :ref:`plugin-after_get_initial_model_for_simulation_actuals` + * :ref:`plugin-after_get_initial_model_for_ruc` + +Finally, the RUC itself is generated and solved. The following callbacks will be +called: + + * :ref:`plugin-before_ruc_solve` + * :ref:`plugin-after_ruc_generation` + +.. _Activate RUC: + +Activate RUC +............ + +If the current simulation time is a RUC activation time, the most recently +generated RUC will be activated. Activating a RUC simply marks the point in the +simulation when the RUC's decisions first begin to be followed. RUC activation +hours occur at regular intervals starting at midnight of the first day and repeating +at the :ref:`RUC frequency` for the rest of the simulation. +See :doc:`ruc_details` for information on the timing and frequency of RUC +activation. + +The following callback is called each time a RUC is activated: + + * :ref:`plugin-after_ruc_activation` + +.. _Deploy SCED: + +Deploy SCED +........... + +A SCED is generated, solved, and applied every simulation timestep. +When a SCED is applied, generator setpoints are set for the current simulation time. +See :doc:`sced_details`. + +The following callbacks are called each time a SCED is deployed: + + * :ref:`plugin-after_get_initial_model_for_sced` + * :ref:`plugin-before_operations_solve` + * :ref:`plugin-after_operations` + * :ref:`plugin-update_operations_stats` + +.. _Finalize Timestep: + +Finalize Timestep +................. + +After SCED deployment is complete, statistics for the timestep are published +and the simulation clock advances to the time of the next SCED, as determined +by the :ref:`SCED frequency`. + +Several callbacks related to statistics may be called at this time. Calling a +callback related to statistics is referred to as "publishing" statistics. + +Operations statistics (statistics about SCED results) are published every timestep +by calling the following callback: + + * :ref:`plugin-operations_stats` + +If the timestep is the final timestep in a given hour, hourly statistics are +published: + + * :ref:`plugin-hourly_stats` + +If the timestep is the final timestep in a given day, daily statistics are +published: + + * :ref:`plugin-daily_stats` + +The simulation clock is advanced after all relevant statistics have been published. +If the new time is later than the simulation end date, the main simulation loop +ends and Prescient moves to the Finalization stage. Otherwise Prescient repeats the +main simulation loop for the new timestep. + +Finalization +------------ + +The finalization phase consists of tasks that occur once at the end of the +simulation. + +Finalize Simulation +................... + +Statistics for the simulation as a whole are published during finalization: + + * :ref:`plugin-overall_stats` + +Another callback is called to notify callbacks that the simulation is complete, +giving plugins a chance to cleanly shut down: + + * :ref:`plugin-finalization` diff --git a/doc/OnlineDocs/source/reference/index.rst b/doc/OnlineDocs/source/reference/index.rst index 568448f2..143d5d5a 100644 --- a/doc/OnlineDocs/source/reference/index.rst +++ b/doc/OnlineDocs/source/reference/index.rst @@ -5,5 +5,9 @@ Reference :maxdepth: 1 input_data.rst + detailed_lifecycle.rst + ruc_details.rst + sced_details.rst + plugins.rst code.rst \ No newline at end of file diff --git a/doc/OnlineDocs/source/reference/plugins.rst b/doc/OnlineDocs/source/reference/plugins.rst new file mode 100644 index 00000000..d2734df1 --- /dev/null +++ b/doc/OnlineDocs/source/reference/plugins.rst @@ -0,0 +1,317 @@ +Plugins +======= + +Plugins provide opportunities for custom code to observe or modify simulation +data at specific points in the simulation lifecycle. Plugins are python +modules that include a specific set of functions that enable Prescient to +interact with the plugin module. Plugins are specified on the command line, or +in the options passed to the Prescient `simulate()` method if running Prescient +in code. + +Plugin modules must include a registration function, through which the plugin +requests that custom code be called at specific points in the simulation process. +Each point at which custom code may be called is known as a *plugin point*. The +function that is called at a plugin point is known as a *callback*. + +Plugin points come in two flavors: statistics plugin points and simulation plugin +points. Statistics points allow plugins to view statistics at various stages of +the simulation. Simulation plugin points provide a more detailed view of specific +steps within the simulation; some provide opportunities to customize simulation +behavior. + +.. _Identifying Plugins: + +Identifying Plugins +------------------- + +Any plugins that will be included in a Prescient simulation must be specified +with the :ref:`--plugin` simulation option. The syntax for this +option is a little different than other options, and is best explained by example. + +Every plugin in a particular Prescient run is given an alias. This is the name by +which the plugin will be identified in the run. It determines where the plugin's +configuration options will be stored in the configuration object, and may be used +to give the plugin's custom options a unique name on the command line. + +Plugins are identified by path to the python module (.py file), or by python +module name as it would appear in a python `imports` statement. If the module is +specified by module name, it must be able to be found by python's module import +system, such as being located in the `PYTHONPATH`. + +The command line syntax to include a plugin is `--plugin \:\`. For example, the following partial command line will include two plugin +modules, one specified by relative path and one specified by module name:: + + python -m prescient.simulator --plugin plug1:custom/plugin1.py --plugin plug2:custom.plugin2 + +If a plugin defines new configuration options, values can be provided for the new options +anywhere after the plugin has been specified:: + + python -m --plugin myplug:custom_plugin.py --custom-opt 100 + +When configuring Prescient from code, assign a nested dictionary to the `plugin` +element of the configuration options object. The following code example is +equivalent to the previous command line example: + +.. code-block:: python + + from prescient.simulator import Prescient + + p = Prescient() + config = p.config + config.plugin = { + 'myplug':{ + 'module':'custom_plugin.py', + 'custom_opt':100 + } + } + # ...additional configuration ommitted + p.simulate() + +The outer dictionary assigned to the plugin option holds one entry per plugin. +Each entry's key is the plugin's alias, while the entry's value is a dictionary +holding the plugin's data. At a minimum, a plugin's data dictionary must include +a `'module'` element identifying the python module. If the plugin module defines +custom options, values for those options may be supplied as additional dictionary +entries. Values can also be set on separate lines of code: + +.. code-block:: python + + config.plugin = { + 'myplug':{ + 'module':'custom_plugin.py', + } + } + config.plugin.myplug.custom_opt = 100 + +.. _Plugin Module Initialization: + +Plugin Module Initialization +---------------------------- + +A plugin module must have two functions with specific names and signatures. +Prescient initializes each plugin module by calling these two required functions +before the simulation starts, in the order listed below. + +get_configuration() +................... + +The `get_configuration()` function allows plugins to add custom options to the +Prescient configuration. Once a plugin has defined custom options, those options +can be set on the command line or in code just like standard configuration options. + +The `get_configuration()` function must have the following signature: + +.. code:: python + + def get_configuration(key: str): -> Optional[pyomo.common.config.ConfigDict] + +The `key` is the plugin's alias specified in the configuration. The key may be +incorporated into the text of custom options. + +The function should return a pyomo ConfigDict containing any custom options, or +None if the plugin has no custom options. + +register_plugins() +.................. + +The `register_plugins()` function allows a plugin to indicate what callback +functions should be called, and at what plugin points. + +The `register_plugins()` function must have the following signature: + +.. code:: python + + def register_plugins(context: pplugins.PluginRegistrationContext, + options: PrescientConfig, + plugin_config: ConfigDict) -> None: + +The `context` is an object used to register callbacks. The `context` object +has a registration function for each plugin point. Each registration function +takes a function (or other Callable) as an argument. A plugin's implementation +of `register_plugins()` should call the `context` object's registration +method for each plugin point of interest, passing in the callback function +to be called at the corresponding plugin point. + +For example, the code below requests that a function named `my_stats_callback` +be called every time daily statistics are published: + +.. code:: python + + context.register_for_daily_stats(my_stats_callback) + +Registration function names follow a pattern that embeds the name of the plugin +point. The pattern used to name plugin registration functions differs for statistics +callbacks and simulation callbacks. For statistics callbacks, the pattern is +`register_for__stats()`, where *which* is the desired time frame. For +simulation callbacks, the pattern is `register__callback()`, where +*which* is the name of the plugin point. + +The `options` argument is the full set of configuration options for the simulation. + +The `plugin_config` is the plugin's custom options as defined by what was returned +from the plugin's `get_configuration()` method, with their values as set from +the command line or in code. It is the same as what is found at `options.plugins.`, +where `` is the plugin's alias passed to the `get_configuration()` +function earlier. + +Statistics Plugin Points +------------------------ + +Statistics plugin points allow plugins to see statistics +about the simulation. Statistics are published at various time scales. + +.. _plugin-operations_stats: + +Operations Statistics +..................... + +Operations statistics are published at the end of every timestep. They report the +results of a single SCED. + +.. _plugin-hourly_stats: + +Hourly Statistics +................. + +Hourly statistics are published after the final timestep of every hour They report the +aggregate results of all SCEDs within the hour. + +.. _plugin-daily_stats: + +Daily Statistics +................ + +Daily statistics are published after the final timestep of every day (the last +timestep before midnight). They report the aggregate results of all SCEDs within +the day. + +.. _plugin-overall_stats: + +Overall Statistics +.................. + +Overal statistics are published after the final timestep of the simulation. They report +aggregate results for the full simulation. + +Simulation Plugin Points +------------------------ + +Each plugin point occurs at a different place in the simulation process, and +serves a different purpose. + +.. _plugin-options_preview: + +The options_preview Callback +............................ + +This callback is called after command line options have been parsed, but before +they have been used to initialize simulation objects. The callback may modify +option values. + +.. _plugin-initialization: + +The initialization Callback +........................... + +This callback is called after Prescient simulation objects have been created and +initialized. The callback may choose to initialize its own data structures at this +time. + +.. _plugin-after_get_initial_model_for_simulation_actuals: + +The after_get_initial_model_for_simulation_actuals Callback +........................................................... + +Prescient manages actual values by periodically loading from the input data source +into an Egret model. This callback is called after an Egret model has been prepared +to hold actual values, but before the values have been loaded. The structure of the +model will be in place - network elements like generators and branches will be +present - but values will not have been loaded yet. The callback can insert any +non-standard elements and actual values it may use. The callback should not +populate values normally provided by Prescient, as those values will be overwritten +after this callback returns. + +.. _plugin-after_get_initial_model_for_ruc: + +The after_get_initial_model_for_ruc Callback +............................................ + +Prescient manages forecasts by periodically loading them into an Egret model from +the input data source. This callback is called after an Egret model has been +prepared to hold forecast values but before the values have been loaded. The +structure of the model will be in place - network elements like generators and +branches will be present - but values will not have been loaded yet. The callback +can insert any non-standard elements and forecast values it may use. The callback +should not insert forecast values normally provided by Prescient, as those values +will be overwritten after this callback returns. + +.. _plugin-before_ruc_solve: + +The before_ruc_solve Callback +............................. + +This callback is called after an Egret model has been fully prepared for a RUC +and is about to be solved. The callback may modify the Egret model. + +.. _plugin-after_ruc_generation: + +The after_ruc_generation Callback +................................. + +This callback is called after a RUC model has been solved. The callback is able +to see (and potentially modify) the resulting RUC plan. + +.. _plugin-after_ruc_activation: + +The after_ruc_activation Callback +................................. + +This callback is called at the beginning of the effective period of a new RUC. +Unit commitment decisions made by the newly activated RUC will be honored until +the next time the *after_ruc_activation* callback is called. + +.. _plugin-after_get_initial_model_for_sced: + +The after_get_initial_model_for_sced Callback +..................................................... + +This callback is called as a SCED model is being prepared. When this callback is +called, the structure of the model will be in place - network elements like +generators and branches will be present - but values will not have been loaded yet. +The callback can insert any non-standard elements and values it may use. The +callback should not insert values normally provided by Prescient, as those values +will be overwritten after this callback returns. + +.. _plugin-before_operations_solve: + +The plugin-before_operations_solve Callback +........................................... + +This callback is called after a fully populated SCED Egret model has been generated, +before the model has been solved. The callback may modify the Egret model. + +.. _plugin-after_operations: + +The plugin-after_operations Callback +.................................... + +This callback is called after an Egret SCED model has been solved. The callback can +examine (and potentially modify) the results. + +.. _plugin-update_operations_stats: + +The update_operations_stats Callback +.................................... + +This callback is called after an Egret SCED model has been solved and examined by +any :ref:`plugin-after_operations` callbacks, just before the results are +incorporated into statistics. + +.. _plugin-finalization: + +The finalization Callback +......................... + +This callback is called after the simulation is complete. It gives plugins a chance +to cleanly shut down. diff --git a/doc/OnlineDocs/source/reference/ruc_details.rst b/doc/OnlineDocs/source/reference/ruc_details.rst new file mode 100644 index 00000000..76c4f7b1 --- /dev/null +++ b/doc/OnlineDocs/source/reference/ruc_details.rst @@ -0,0 +1,64 @@ +RUC Details +=========== + +A Reliability Unit Commitment plan, or RUC, determines which dispatchable +generators will be active during a portion of the simulation. RUCs work in +conjunction with :doc:`SCEDs` (Security Constraint Economic +Dispatch plans) to simulate operation of the power network. + +Each RUC covers a specific period within the simulation. For each hour within its +applicable period, a RUC dictates whether each dispatchable generator is on or off. +The unit commitment decisions in a RUC are made by building a model which reflects +the current state of the power network and forecasts for future loads and future +renewable power generation. The model is solved to find the most cost-efficient way +to satisfy forecasted loads while honoring system constraints such as reserve +requirements and line limits. + +RUCs may also include pricing schedules. This option is enabled when the +:ref:`compute-market-settlements` option +is set to true. The pricing schedule sets the contract price for expected power +delivery and for reserves (ancillary service products). + +A new RUC is generated at regular intervals. The number of hours between RUCs is +called the :ref:`RUC interval`. The RUC interval also +dictates how many hours each RUC is active. The RUC interval must be between 1 and +24 hours and must divide evenly into 24 hours. + +The number of hours of forecast data to include in the RUC model is determined by +the :ref:`RUC horizon`. The RUC horizon must be at least +equal to the RUC interval, but typically extends further into the future to avoid +poor choices at the end of the plan ("end effects"). A commonly used RUC horizon is +48 hours. + +Each RUC may be generated just as its applicable period is about to begin, or it +may be generated in advance. For this reason, Prescient splits RUC management +into two phases: RUC generation and RUC activation. In the RUC generation phase, a +RUC model is created and optimized, resulting in a RUC plan. In the RUC activation +phase, the commitment decisions identified in the RUC plan begin to take effect. + +A new RUC is always activated at the beginning of each day, and at each time that +is a multiple of the RUC interval. For example, if the RUC interval is 8 hours, +then a new RUC is activated each day at midnight, 8:00 a.m., and 4:00 p.m. + +To generate RUCs in advance of their activation time, set the :ref:`RUC execution +hour` to indicate the time of day that one of the +day's RUC should be generated. If the specified time falls on a scheduled RUC +activation time, then RUCs will not be generated in advance. Otherwise, the +specified time is interpreted as the time to generate the next scheduled RUC. For +example, if the RUC interval is 8 hours and the RUC execution hour is 14 (2:00 +p.m.), then each RUC will be generated 2 hours before its activation time (because +the next RUC activation time ater 2:00 p.m. is 4:00 p.m.). The gap between RUC +generation and RUC activation is called the RUC delay. + +When there is a non-zero RUC delay, generating a RUC model includes an additional +step at the beginning of the RUC generation process. In this first step, a SCED +model is created and solved for the period starting with the current simulation +time and ending after the RUC activation time. Next, a RUC model is created using +the future system state predicted by the SCED as its initial conditions. + +The very first RUC of the simulation is always generated with zero RUC delay, even +if Prescient has been configured to generate other RUCs in advance. + +Prescient provides several plugin points to allow the RUC generation and activation +process to be observed or modified. These are documented in the +:doc:`detailed_lifecycle`. diff --git a/doc/OnlineDocs/source/reference/sced_details.rst b/doc/OnlineDocs/source/reference/sced_details.rst new file mode 100644 index 00000000..eeb042b6 --- /dev/null +++ b/doc/OnlineDocs/source/reference/sced_details.rst @@ -0,0 +1,34 @@ +SCED Details +============ + +A Security Constrained Economic Dispatch plan, or SCED, determines the power output +level of each dispatchable generator during a single timestep of the simulation. +SCEDs work in conjunction with :doc:`RUCs` (Reliability Unit +Commitment plans) to simulate operation of the power network. + +Each SCED determines operational parameters of each dispatchable generator for a single time step. The SCED coordinates +changes to generator setpoints to minimize total costs for the system as a whole. +The decisions in a +SCED are made by building a model which reflects the state of the power network +at the current simulation time, forecasts for future loads and future renewable +power generation, and unit commitments as dictated by the most recently activated +RUC. The model is solved to find the most cost-efficient way to satisfy +current and forecasted loads while honoring system constraints such as reserve requirements +and line limits. SCEDs always honor unit commitment decisions made by the active +RUC. The number of hours of forecast data to include in the SCED model is +determined by the :ref:`SCED horizon`. + +Something about calculating costs. + +If :ref:`market settlement` is enabled, +additional market-related statistics are calculated with each SCED. These +statistics report performance against day-ahead commitments and reserve +requirements and the resulting impact on generator revenue. + +SCEDs are generated more frequently than RUCs. Where a new RUC is typically +generated between 1 and 4 times a day, SCEDs occur at least hourly. The :ref:`SCED +frequency` determines how often a SCED is +generated, and also serves as the size of the simulation time step. + +Prescient provides several plugin points to allow the SCED generation process to +be observed or modified. These are documented in the :doc:`detailed_lifecycle`. \ No newline at end of file diff --git a/doc/OnlineDocs/source/tasks/configure.rst b/doc/OnlineDocs/source/tasks/configure.rst index 9c52c3de..0870ae18 100644 --- a/doc/OnlineDocs/source/tasks/configure.rst +++ b/doc/OnlineDocs/source/tasks/configure.rst @@ -94,7 +94,9 @@ The table below describes all available configuration options. - - - - * - \-\-start-date + * - .. _config_start-date: + + \-\-start-date - start_date - Date. Default=2020-01-01. - The start date for the simulation. @@ -137,12 +139,16 @@ The table below describes all available configuration options. - - - - * - \-\-ruc_every-hours + * - .. _config_ruc-every-hours: + + \-\-ruc-every-hours - ruc_every_hours - Integer. Default=24 - How often a RUC is executed, in hours. Default is 24. Must be a divisor of 24. - * - \-\-ruc-execution-hour + * - .. _config_ruc-execution-hour: + + \-\-ruc-execution-hour - ruc_execution_hour - Integer. Default=16 - Specifies an hour of the day the RUC process is executed. @@ -239,7 +245,9 @@ The table below describes all available configuration options. - Integer. Default=60. - How often a SCED will be run, in minutes. Must divide evenly into 60, or be a multiple of 60. - * - \-\-sced-horizon + * - .. _config_sced-horizon: + + \-\-sced-horizon - sced_horizon - Integer. Default=1 - The number of time periods to include in each SCED. @@ -371,7 +379,9 @@ The table below describes all available configuration options. - - - - * - \-\-plugin + * - .. _config_plugin: + + \-\-plugin - plugin - Module. Default=None. - Python plugins are analyst-provided code that Prescient calls at From 311cab7b29ebf35cbd97fc1d99d52446f93b3b6e Mon Sep 17 00:00:00 2001 From: Darryl Melander Date: Mon, 7 Aug 2023 11:32:49 -0600 Subject: [PATCH 4/4] Fix documentation typos and formatting --- doc/OnlineDocs/source/reference/plugins.rst | 4 ++-- doc/OnlineDocs/source/reference/sced_details.rst | 2 -- doc/OnlineDocs/source/tasks/configure.rst | 13 +++++++++---- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/doc/OnlineDocs/source/reference/plugins.rst b/doc/OnlineDocs/source/reference/plugins.rst index d2734df1..9012dbae 100644 --- a/doc/OnlineDocs/source/reference/plugins.rst +++ b/doc/OnlineDocs/source/reference/plugins.rst @@ -285,7 +285,7 @@ will be overwritten after this callback returns. .. _plugin-before_operations_solve: -The plugin-before_operations_solve Callback +The before_operations_solve Callback ........................................... This callback is called after a fully populated SCED Egret model has been generated, @@ -293,7 +293,7 @@ before the model has been solved. The callback may modify the Egret model. .. _plugin-after_operations: -The plugin-after_operations Callback +The after_operations Callback .................................... This callback is called after an Egret SCED model has been solved. The callback can diff --git a/doc/OnlineDocs/source/reference/sced_details.rst b/doc/OnlineDocs/source/reference/sced_details.rst index eeb042b6..79fcf3eb 100644 --- a/doc/OnlineDocs/source/reference/sced_details.rst +++ b/doc/OnlineDocs/source/reference/sced_details.rst @@ -18,8 +18,6 @@ and line limits. SCEDs always honor unit commitment decisions made by the active RUC. The number of hours of forecast data to include in the SCED model is determined by the :ref:`SCED horizon`. -Something about calculating costs. - If :ref:`market settlement` is enabled, additional market-related statistics are calculated with each SCED. These statistics report performance against day-ahead commitments and reserve diff --git a/doc/OnlineDocs/source/tasks/configure.rst b/doc/OnlineDocs/source/tasks/configure.rst index 0870ae18..5ddd8ac7 100644 --- a/doc/OnlineDocs/source/tasks/configure.rst +++ b/doc/OnlineDocs/source/tasks/configure.rst @@ -190,7 +190,8 @@ The table below describes all available configuration options. * - \-\-ruc-network-type - ruc_network_type - String. Default=ptdf. - - Specifies how the network is represented in RUC models. Choices are: + - Specifies how the network is represented in RUC models. Choices are: + * ptdf -- power transfer distribution factor representation * btheta -- b-theta representation * - \-\-ruc-slack-type @@ -198,6 +199,7 @@ The table below describes all available configuration options. - String. Default=every-bus. - Specifies the type of slack variables to use in the RUC model formulation. Choices are: + * every-bus -- slack variables at every system bus * ref-bus-and-branches -- slack variables at only reference bus and each system branch * - \-\-deterministic-ruc-solver @@ -271,13 +273,15 @@ The table below describes all available configuration options. * - \-\-sced-network-type - sced_network_type - String. Default=ptdf. - - Specifies how the network is represented in SCED models. Choices are: + - Specifies how the network is represented in SCED models. Choices are: + * ptdf -- power transfer distribution factor representation * btheta -- b-theta representation * - \-\-sced-slack-type - sced_slack_type - String. Default=every-bus. - - Specifies the type of slack variables to use in SCED models. Choices are: + - Specifies the type of slack variables to use in SCED models. Choices are: + * every-bus -- slack variables at every system bus * ref-bus-and-branches -- slack variables at only reference bus and each system branch * - \-\-sced-solver @@ -361,7 +365,8 @@ The table below describes all available configuration options. * - \-\-day-ahead-pricing - day_ahead_pricing - String. Default=aCHP. - - The pricing mechanism to use for the day-ahead market. Choices are: + - The pricing mechanism to use for the day-ahead market. Choices are: + * LMP -- locational marginal price * ELMP -- enhanced locational marginal price * aCHP -- approximated convex hull price.