Event Handlers
ropt.workflow.event_handlers.EventHandler
Bases: ABC
Abstract base class for event handlers.
This class defines the fundamental interface for all event handlers within an optimization workflow. Concrete handler implementations, (e.g., tracking results, storing data, logging), must inherit from this base class.
Handlers may store state using dictionary-like access ([]), allowing
them to accumulate information or make data available to other components in
an optimization workflow.
Subclasses must implement the abstract
handle_event
method to define their specific event processing logic.
Event handlers are attached to a
ComputeStep using its
add_event_handler
method. When the compute step emits an event, the handle_event method of
each attached handler is invoked, allowing it to process the event.
event_types
abstractmethod
property
Return the event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
handle_event
abstractmethod
Process an event.
This abstract method must be implemented by concrete EventHandler
subclasses. It defines the event handler's core logic for reacting to
EnOptEvent objects emitted in the
optimization workflow.
Implementations should inspect the event object (its event_type and
data) and perform computations accordingly, such as storing results,
logging information, or updating internal state.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event object. |
required |
__getitem__
Retrieve a value from the event handler's internal state.
This method enables dictionary-like access (handler[key]) to the
values stored within the event handler's internal state dictionary. This
allows handlers to store and retrieve data accumulated during workflow
execution.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The string key identifying the value to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The value associated with the specified key. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If the provided |
__setitem__
Store or update a value in the event handler's internal state.
This method enables dictionary-like assignment (handler[key] = value)
to store arbitrary data within the event handler's internal state
dictionary. This allows event handlers to accumulate information or make
data available to other components of the workflow.
The key must be a valid Python identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The string key identifying the value to store (must be an identifier). |
required |
value
|
Any
|
The value to associate with the key. |
required |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If the provided |
ropt.workflow.event_handlers.Tracker
Bases: EventHandler
The default event handler for tracking optimization results.
This event handler listens for
FINISHED_EVALUATION events
emitted from within an optimization workflow. It processes the
Results objects contained within these events and
selects a single FunctionResults object to
retain based on defined criteria.
The criteria for selection are:
what='best'(default): Tracks the result with the lowest weighted objective value encountered so far.what='last': Tracks the most recently received valid result.
Optionally, results can be filtered based on constraint violations using the
constraint_tolerance parameter. If provided, any result violating
constraints beyond this tolerance is ignored.
The selected result (in the optimizer domain) is stored internally. The
result accessible via dictionary access (handler["results"]) is the
selected result, potentially transformed to the user domain.
event_types
property
Return the event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
__init__
__init__(
*,
what: Literal["best", "last"] = "best",
constraint_tolerance: float | None = None,
) -> None
Initialize a default tracker event handler.
This event handler monitors Results objects
and selects a single FunctionResults
object to retain based on the what criterion ('best' or 'last').
The 'best' result is the one with the lowest weighted objective value
encountered so far. The 'last' result is the most recently received
valid result. Results can optionally be filtered by
constraint_tolerance to ignore those violating constraints beyond the
specified threshold.
Tracking logic (comparing 'best' or selecting 'last') operates on the
results in the optimizer's domain. However, the final selected result
that is made accessible via dictionary access (handler["results"]) is
transformed to the user's domain.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
what
|
Literal['best', 'last']
|
Criterion for selecting results ('best' or 'last'). |
'best'
|
constraint_tolerance
|
float | None
|
Optional threshold for filtering constraint violations. |
None
|
handle_event
Handle incoming events.
This method processes incoming
FINISHED_EVALUATION
events.
If a relevant event containing results is received, this method updates
the tracked result (self["results"]) based on the what criterion
('best' or 'last') and the optional constraint_tolerance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event object. |
required |
ropt.workflow.event_handlers.Store
Bases: EventHandler
The default event handler for storing optimization results.
This event handler listens for
FINISHED_EVALUATION events
emitted by specified compute steps from within an optimization workflow. It
collects all Results objects contained within
these events and stores them sequentially in memory.
The accumulated results are stored as a tuple and can be accessed via
dictionary access using the key "results" (e.g., handler["results"]).
Each time new results are received from a valid source, they are appended to
this tuple.
event_types
property
Return the event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
__init__
Initialize a default store event handler.
This event handler collects and stores all
Results objects it receives. It listens for
FINISHED_EVALUATION events
and appends the results contained within them to an internal tuple.
The results are converted from the optimizer domain to the user domain
before being stored. The accumulated results are stored as a tuple and
can be accessed via dictionary access using the key "results" (e.g.,
handler["results"]). Initially, handler["results"] is None.
handle_event
Handle incoming events.
This method processes events it receives. It specifically listens for
FINISHED_EVALUATION events.
If a relevant event containing results is received, this method
retrieves the results, optionally transforms them to the user domain and
appends them to the tuple stored in self["results"].
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event object. |
required |
ropt.workflow.event_handlers.Table
Bases: EventHandler
This event handler tracks results and stores them in pandas DataFrames.
Tables
The functions and gradients inputs are dictionaries where each item
denotes a table to generate, for
FunctionsResults and
GradientsResults respectively. Tables are
accessed by their name in attributes, i.e. if the functions input has an
entry evaluations, this table can be accessed via
handler["evaluations"]. Note that the tables are generated on the fly from
internal data when accessing them in this way. When multiple access are
needed, it is more efficient to first store them in a variable.
By default the functions and gradients are set to None directing the handler
to generate a set of default tables:
- For the
functionsinput:"functions": contains a set of values of the calculated functions."evaluations": contains a set of values for all evaluations."constraints": contains a set of values for all constraints.
- For the
gradientsinput:"gradients": contains a set of values of the calculated gradients."perturbations": contains a set of values for all perturbations.
To change (or disable) the generation of these table, pass an appropriate (or empty) dictionary specifying the desired tables.
Table specification
Each value of each entry in the functions and gradients dictionaries is
another dictionary that determines which fields in the results should be
stored in the corresponding table. The keys denote the names of the fields,
using attribute syntax. For instance a result.function.objectives key
indicates the the result should contain a column with objective values that
are found in the objectives field of the function field of the result.
The values corresponding to the keys are used to provide the column names.
For example, passing this dictionary via the functions input generates a
table containing the batch id, the values of all calculated objectives and
the vector of variables.
{
"functions": {
"batch_id": "Batch",
"functions.objectives": "Objective",
"evaluations.variables": "Variables",
}
}
Some fields may result in multiple columns in the DataFrame if their values
are vectors or matrices. For example, evaluations.variables will generate
a separate column for each variable. The table specification above may
generate a pandas dataframe looking something like this:
Batch Objective,0 Variables,v0 Variables,v1 Variables,v2
0 0 1.309826e+02 0.500000 0.900000 1.300000
1 0 4.362553e+12 120.900265 20.698539 -90.578972
...
Here, because the variables are vectors of length 2, there are two variable
columns generated. The corresponding column names consist of the column
title and the name of the variable vector, separated by a comma. Note that
the function.objectives column also contains a comma followed by a 0
value. This is because the functions.objectives is also a vector of
values, there just happens to be only one objective. Its index is used
instead of a name, because no name was provided in the configuration of the
optimization. Fields may even have matrix values, in which case the column
names may be contain two item names or indices separated by commas.
Changing the column name separator.
By default a comma is used to separate fields in the column names if
needed. The sep input can be used to provide an alternative separator.
You can exploit this by specifying a newline as the separator and
display a nicely formatted table using the tabulate package:
which will show something like this using multi-line headers:
Callback functionality
The tables are updated anytime a result is processed. To be able to do
something with the tables each time they are updated a callback can be
provided via the callback input. This callback will called anytime the
tables are update, passing the handler as its only argument.
event_types
property
Return the event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
__init__
__init__(
*,
functions: dict[str, dict[str, str]] | None = None,
gradients: dict[str, dict[str, str]] | None = None,
sep: str = ",",
callback: Callable[[EventHandler], None] | None = None,
) -> None
Initialize a default table event handler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
functions
|
dict[str, dict[str, str]] | None
|
Dictionary of tables with function results. |
None
|
gradients
|
dict[str, dict[str, str]] | None
|
Dictionary of tables with gradient results. |
None
|
sep
|
str
|
Separator used in column names. |
','
|
callback
|
Callable[[EventHandler], None] | None
|
An optional callback that is called when the tables are update. |
None
|
handle_event
Handle incoming events.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event object. |
required |
__getitem__
Retrieve a of a table from the event handler.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
key
|
str
|
The string key identifying the table to retrieve. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The table associated with the specified key. |
Raises:
| Type | Description |
|---|---|
AttributeError
|
If the requested table does not exist. |
add_column
ropt.workflow.event_handlers.Observer
Bases: EventHandler
The default event handler for observing events.
This event handler listens for events and forwards them to one or more callback functions.
event_types
property
Return the event types that are handled.
Returns:
| Type | Description |
|---|---|
set[EnOptEventType]
|
A set of event types that are handled. |
__init__
Initialize a default event handler.
This event handler responds to events by calling callback if the event
type matches event_types.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event_types
|
set[EnOptEventType]
|
The set of event types to respond to. |
required |
callback
|
Callable[[EnOptEvent], None]
|
The callable to call. |
required |
handle_event
Handle incoming events.
This method processes events emitted from within the workflow.
If a event containing results is received, and its type equals the stored event type, the stored callback is called.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
EnOptEvent
|
The event object emitted from the workflow. |
required |