Topology Optimizer#
toop_engine_topology_optimizer.interfaces.messages.commands
#
Defines the interaction between the optimizer and a backend.
The backend will send commands in the form of messages to the optimizer, which will trigger a certain behaviour. The Optimizer will respond with results, for this see results.py
StartOptimizationCommand
#
Bases: BaseModel
Command with parameters for starting an optimization run.
message_type
class-attribute
instance-attribute
#
The command type for deserialization, don't change this
dc_params
class-attribute
instance-attribute
#
dc_params = DCOptimizerParameters()
The parameters for the DC optimizer
ac_params
class-attribute
instance-attribute
#
ac_params = ACOptimizerParameters()
The parameters for the AC optimizer
grid_files
instance-attribute
#
The grid files to load, where each gridfile represents one timestep. The grid files also include coupling information for the timesteps.
optimization_id
instance-attribute
#
The id of the optimization run, used to identify the optimization run in the results. Should stay the same for the whole optimization run and should be equal to the kafka event key
ShutdownCommand
#
Command
#
Bases: BaseModel
Base class for all commands to the optimizer.
validate_first_gridfile_uncoupled
#
Check that the first gridfile is uncoupled
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/interfaces/messages/commands.py
toop_engine_topology_optimizer.interfaces.messages.dc_params
#
The DC optimizer is the GPU stage where massive amounts of topologies are being checked.
This holds the parameters to start the optimization. Some parameters can not be changed (mainly the names of the kafka streams) and are included in the command line start parameters instead.
BatchedMEParameters
#
Bases: BaseModel
Parameters for starting the batched genetic algorithm (In this case Map-Elites)
iterations_per_epoch
class-attribute
instance-attribute
#
The number of iterations per epoch
random_seed
class-attribute
instance-attribute
#
The random seed to use for reproducibility
enable_nodal_inj_optim
class-attribute
instance-attribute
#
Whether to enable the nodal injection optimization stage. This can optimize PSTs (currently) and soon HVDC and potentially even redispatch clusters. Using this will increase runtime.
n_worst_contingencies
class-attribute
instance-attribute
#
The number of worst contingencies to consider in the scoring function. This is used to determine the worst cases for overloads.
enable_bb_outage
class-attribute
instance-attribute
#
Whether the optimizer should include busbar outage effects in scoring. If the preprocessed grid file does not contain busbar outage data, this flag is ignored.
bb_outage_as_nminus1
class-attribute
instance-attribute
#
Whether busbar outages are handled as additional N-1 cases. If this is True, they are just part of the N-1 matrix and will contribute to normal overload energy, max load, etc. If this is False, a separate busbar outage penalty is computed and added to the scores. If no busbar outage data is provided in the grid model, this parameter will be ignored.
clip_bb_outage_penalty
class-attribute
instance-attribute
#
Whether busbar outage penalties are clipped at 0. This is only relevant in case of bb_outage_as_nminus1=False, where busbar outage penalties are added to the scores as a separate term. If this is True, the busbar outage penalty will be clipped at 0, meaning that topologies that improve the busbar outage penalty will not be rewarded for it. If this is False, topologies that improve the busbar outage penalty will receive a negative penalty, which can lead to higher scores and thus be rewarded by the optimizer. If no busbar outage data is provided in the grid model or if bb_outage_as_nminus1 is True, this parameter will be ignored.
bb_outage_more_islands_penalty
class-attribute
instance-attribute
#
Islanding penalty used for busbar outage baseline comparisons. This is only relevant in case of bb_outage_as_nminus1=False, where busbar outage penalties are added to the scores as a separate term. If a busbar outage computation fails due to grid splits/islanding, this penalty will be applied to the score proportional to the number of islands. If no busbar outage data is provided in the grid model or if bb_outage_as_nminus1 is True, this parameter will be ignored.
mutation_repetition
class-attribute
instance-attribute
#
More chance to get unique mutations by mutating multiple copies of the repertoire
random_topo_prob
class-attribute
instance-attribute
#
The probability to create a random topology instead of mutating the existing one. This can help to escape local minima.
n_subs_mutated_lambda
class-attribute
instance-attribute
#
The number of substations to mutate in a single iteration is drawn from a poisson with this lambda
add_split_prob
class-attribute
instance-attribute
#
The probability to add an additional split to a substation, applied after the number of substations to mutate is drawn
change_split_prob
class-attribute
instance-attribute
#
The probability to change an existing split in a substation
remove_split_prob
class-attribute
instance-attribute
#
The probability to remove a split from a substation
add_disconnection_prob
class-attribute
instance-attribute
#
The probability to add a disconnection, applied after the number of disconnections to mutate is drawn
change_disconnection_prob
class-attribute
instance-attribute
#
The probability to change an existing disconnection
remove_disconnection_prob
class-attribute
instance-attribute
#
The probability to remove an existing disconnection
pst_mutation_sigma
class-attribute
instance-attribute
#
The sigma to use for the normal distribution that mutates the PST taps. The mutation is applied by adding a random value drawn from this distribution to the current tap position. A value of 0.0 means no PST mutation.
pst_mutation_probability
class-attribute
instance-attribute
#
The probability for an individual PST to be selected for mutation. A value of 0.0 means no PST mutation. A value of 1.0 means all PSTs will be mutated.
pst_reset_probability
class-attribute
instance-attribute
#
The probability for an individual PST to be reverted to its initial set point. A value of 0.0 means no reset. A value of 1.0 means all PSTs will be reset.
proportion_crossover
class-attribute
instance-attribute
#
The proportion of the first topology to take in the crossover
crossover_mutation_ratio
class-attribute
instance-attribute
#
The ratio of crossovers to mutations
target_metrics
class-attribute
instance-attribute
#
The list of metrics to optimize for with their weights
observed_metrics
class-attribute
instance-attribute
#
observed_metrics = (
"max_flow_n_0",
"overload_energy_n_0",
"overload_energy_limited_n_0",
"max_flow_n_1",
"overload_energy_n_1",
"overload_energy_limited_n_1",
"split_subs",
"switching_distance",
)
The observed metrics, i.e. which metrics are to be computed for logging purposes. The target_metrics and me_descriptors must be included in the observed metrics and will be added automatically by the validator if they are missing
me_descriptors
class-attribute
instance-attribute
#
me_descriptors = (
DescriptorDef(metric="split_subs", num_cells=5),
DescriptorDef(
metric="switching_distance", num_cells=45
),
)
The descriptors to use for MAP-Elites. This includes a metric that determines the cell index and a number of cells. If the metric exceeds the number of cells, it will be clipped to the largest cell index. Currently, this must be integer metrics
cell_depth
class-attribute
instance-attribute
#
When applicable, each cell contains cell_depth unique topologies. Use 1 to retain the original map-elites behaviour
infer_missing_observed_metrics
#
Add potentially missing target and descriptor metrics to the observed metrics.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/interfaces/messages/dc_params.py
probabilities_less_than_one
#
Check that the mutation probabilities are not larger than 1.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/interfaces/messages/dc_params.py
me_descriptors_cannot_be_empty
#
Check that MeDescriptors tuple is not empty.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/interfaces/messages/dc_params.py
LoadflowSolverParameters
#
Bases: BaseModel
Parameters for the loadflow solver.
max_num_splits
class-attribute
instance-attribute
#
The maximum number of splits per topology
max_num_disconnections
class-attribute
instance-attribute
#
The maximum number of disconnections to apply per topology
batch_size
class-attribute
instance-attribute
#
The batch size for the genetic algorithm
distributed
class-attribute
instance-attribute
#
Whether to run the genetic algorithm distributed over multiple devices
cross_coupler_flow
class-attribute
instance-attribute
#
Whether to compute cross-coupler flows
DCOptimizerParameters
#
Bases: BaseModel
The set of parameters that are used in the DC optimizer only
ga_config
class-attribute
instance-attribute
#
ga_config = BatchedMEParameters()
The configuration options for the genetic algorithm
loadflow_solver_config
class-attribute
instance-attribute
#
loadflow_solver_config = LoadflowSolverParameters()
The configuration options for the loadflow solver
double_limits
class-attribute
instance-attribute
#
The double limits for the optimization, if they should be updated
summary_frequency
class-attribute
instance-attribute
#
The frequency to push back results, based on number of iterations. Default is after every 10 iterations.
check_command_frequency
class-attribute
instance-attribute
#
The frequency to check for new commands, based on number of iterations. Should be a multiple of summary_frequency
max_num_splits_unequal_zero_if_descriptor_exists
#
Check that max_num_splits is larger than the MeDescriptor size-1 of split_subs.
If the map elites descriptor contains split_subs, max_num_splits must be larger
than 0. Otherwise, the computation of the BSDF will fail.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/interfaces/messages/dc_params.py
toop_engine_topology_optimizer.interfaces.messages.ac_params
#
The parameters for the AC optimizer.
On AC, some subtelties are different to the DC optimization such as that the optimization is not batched, and the parameters are slightly different.
ACGAParameters
#
Bases: BaseModel
Parameters for the AC genetic algorithm
runtime_seconds
class-attribute
instance-attribute
#
The maximum runtime of the AC optimization in seconds
n_worst_contingencies
class-attribute
instance-attribute
#
How many worst contingencies to consider for the initial metrics, i.e. the top k contingencies that are used to compute the initial metrics. This is used to compute the top_k_overloads_n_1
runner_processes
class-attribute
instance-attribute
#
How many processes to spawn for computing the N-1 cases in each timestep in parallel. Note that this multiplies with contingency_processes and you might run out of memory if you set both too high
contingency_processes
class-attribute
instance-attribute
#
How many processes to spawn for computing the contingencies of each strategy in parallel. Note that this multiplies with runner_processes and you might run out of memory if you set both too high
worst_k_runner_processes
class-attribute
instance-attribute
#
How many processes to spawn per topology during the worst-k stage.
worst_k_contingency_processes
class-attribute
instance-attribute
#
How many processes to spawn for computing the contingencies of each strategy in parallel during the worst-k stage.
remaining_loadflow_wait_seconds
class-attribute
instance-attribute
#
Maximum time to keep collecting non-rejected strategies before starting the remaining contingency evaluation, even if the survivor threshold has not been reached.
filter_strategy
class-attribute
instance-attribute
#
The filter strategy to use for the optimization, used to filter out strategies based on the discriminator, median or dominator filter.
enable_ac_rejection
class-attribute
instance-attribute
#
Whether to enable the AC rejection, i.e. no messages will be sent to the results topic in case of non-acceptance.
reject_convergence_threshold
class-attribute
instance-attribute
#
The rejection threshold for the convergence rate, i.e. the split case must have at most the same amount of non converging loadflows as the unsplit case or it will be rejected.
reject_overload_threshold
class-attribute
instance-attribute
#
The rejection threshold for the overload energy improvement, i.e. the split case must have at least 5% lower overload energy than the unsplit case or it will be rejected.
reject_critical_branch_threshold
class-attribute
instance-attribute
#
The rejection threshold for the critical branches increase, i.e. the split case must have less than 10% more critical branches than the unsplit case or it will be rejected.
early_stop_validation
class-attribute
instance-attribute
#
Whether to enable early stopping during the optimization process.
early_stopping_non_convergence_percentage_threshold
class-attribute
instance-attribute
#
The threshold for the early stopping criterion, i.e. if the percentage of non-converging cases is greater than this value, the ac validation will be stopped early.
max_initial_wait_seconds
class-attribute
instance-attribute
#
The maximum amount of seconds to wait for the initial DC results. If no results have arrived within this time, we assume the DC optimizer had some problem and abort the optimization run.
ACOptimizerParameters
#
Bases: BaseModel
The set of parameters that are used in the AC optimizer only
initial_loadflow
class-attribute
instance-attribute
#
If an initial AC loadflow was computed before the start of the optimization run, this can be passed and will be used e.g. to compute double limits. It will be sent back through the initial topology push.
ga_config
class-attribute
instance-attribute
#
ga_config = ACGAParameters()
The genetic algorithm configuration
AC Validation#
toop_engine_topology_optimizer.ac.evolution_functions
#
Implements an adjusted AC evolution
Instead of the original GA evolution which only knows mutate and crossover, we introduce the following operations: - The pull operator will take a promising topology from the DC repertoire and re-evaluate it on AC. The notion of promising is defined through a interest-scoring function which tries to balance the explore/exploit trade-off.
select_repertoire
#
Select the topologies that are suitable for mutation and crossover
In this case, all topologies that satisfy the filter criteria are suitable, however a check after the mutate is necessary to ensure that the topology is not already in the database.
The unsplit strategy is never selected for mutation or crossover.
| PARAMETER | DESCRIPTION |
|---|---|
optimization_id
|
The optimization ID to filter for
TYPE:
|
optimizer_type
|
The optimizer types to filter for (whitelist)
TYPE:
|
without_children_on
|
If the topology already spawned a child on any of these optimizer types, it will be filtered out.
TYPE:
|
session
|
The database session to use
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ACOptimTopology]
|
The topologies that are suitable for mutation and crossover |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/evolution_functions.py
get_unsplit_ac_topology
#
Get the unsplit AC topology for the given optimization ID
| PARAMETER | DESCRIPTION |
|---|---|
optimization_id
|
The optimization ID to filter for
TYPE:
|
session
|
The database session to use
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ACOptimTopology
|
The unsplit AC topology for the given optimization ID, or None if not found |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/evolution_functions.py
default_scorer
#
Return raw fitness values for the default lower-is-better AC selection.
| PARAMETER | DESCRIPTION |
|---|---|
metrics
|
The metrics DataFrame to score
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Series
|
The topology fitness values. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/evolution_functions.py
get_contingency_indices_from_ids
#
Map contingency ids to their indices in the N-1 definition.
This is a helper method used in update_initial_metrics_with_worst_k_contingencies method.
| PARAMETER | DESCRIPTION |
|---|---|
case_ids
|
A list of contingency ids for a specific topology.
TYPE:
|
n_minus1_definition
|
The N-1 definition containing the contingencies.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[int]
|
A list of indices of the contingencies in the N-1 definition. If a contingency id is not found, it will be skipped. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/evolution_functions.py
pull
#
Pull a promising topology from the DC repertoire to AC
This only copies the topology without any changes other than setting the optimizer type to AC. This function takes a list of selected DC topologies and creates corresponding AC topologies by copying relevant attributes, setting the optimizer type to AC, and merging contingency case indices from both the DC and unsplit AC topologies.
| PARAMETER | DESCRIPTION |
|---|---|
selected_strategy
|
The selected strategy to pull
TYPE:
|
session
|
The database session to use, by default None. The session object is used to fetch the unsplit AC topology which is then used to add the critical contingency cases to the pulled strategy. These critical cases can then be used for early stopping of AC N-1 contingency analysis.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ACStrategy
|
The a copy of the input topologies with the optimizer type set to AC |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/evolution_functions.py
evolution
#
Perform the AC evolution.
| PARAMETER | DESCRIPTION |
|---|---|
rng
|
The random number generator to use
TYPE:
|
session
|
The database session to use, will write the new topologies to the database
TYPE:
|
optimization_id
|
The optimization ID to filter for
TYPE:
|
max_retries
|
The maximum number of retries to perform if a strategy is already in the database
TYPE:
|
batch_size
|
Number of unevaluated topologies to sample and convert to AC in one try.
TYPE:
|
filter_strategy
|
The filter strategy to use for the optimization, used to filter out strategies that are too far away from the original topology.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ACStrategy
|
The strategy that was created during the evolution or an empty list if something went wrong at all retries |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/evolution_functions.py
evolution_try
#
Perform a single try of the AC evolution.
| PARAMETER | DESCRIPTION |
|---|---|
rng
|
The random number generator to use
TYPE:
|
session
|
The database session to use, will write the new topologies to the database
TYPE:
|
optimization_id
|
The optimization ID to filter for
TYPE:
|
batch_size
|
Number of unevaluated topologies to sample and convert to AC.
TYPE:
|
filter_strategy
|
The filter strategy to use for the optimization, used to filter out strategies that are too far away from the original topology.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ACOptimTopology]
|
The list of topologies that were created during the evolution or an empty list if something went wrong during the try |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/evolution_functions.py
toop_engine_topology_optimizer.ac.listener
#
A listener that listens for new topologies on a kafka result stream and saves them to db
This is intended for usage both in the AC optimizer and the backend, as they both listen for topologies on the result kafka stream. The backend has some further logic as it watches all optimizations and might change the state of the optimization to "running" if it receives a start optimization result and "stopped" if a stop optimization result is received.
One of the requirements is that the AC listener will only want to listen to a single optimization_id and not to messages by itself. Hence a filtering mechanic is added.
finish_optimization
#
Mark an optimization as finished in the database.
If it was a DC optimization, this function just saves an entry to DB. If it was an AC optimization, this function also deletes all topologies from the database that belong to this optimization, as they are no longer relevant and we don't want to keep them around.
| PARAMETER | DESCRIPTION |
|---|---|
db
|
The database session to use for saving the finished optimization
TYPE:
|
optimization_id
|
The optimization ID of the finished optimization as sent via kafka
TYPE:
|
optimizer_type
|
Which optimizer type has finished
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/listener.py
poll_results_topic
#
Poll the results topic for new topologies to store in the DB
We store topologies from all optimization jobs, as it could be that we will later optimize the same job in this worker.
| PARAMETER | DESCRIPTION |
|---|---|
db
|
The database session to use for saving the topologies
TYPE:
|
consumer
|
The kafka consumer to poll messages from. It should already be subscribed to the result topic.
TYPE:
|
first_poll
|
If True, we assume the optimizatin has just started and we can afford to wait for the first DC results for a longer time (30 seconds). If False, we assume the optimization is already running and we don't want to block the consumer for too long (100 ms), by default True
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict[str, int]
|
A dictionary with the number of topologies added to the database for each optimization ID |
list[str]
|
A list of optimization IDs for which a stop optimization result was received. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/listener.py
toop_engine_topology_optimizer.ac.optimizer
#
Implements initialize and run_epoch functions for the AC optimizer
AcNotConvergedError
#
Bases: Exception
An exception that is raised when the AC optimization did not converge in the base grid
update_initial_metrics_with_worst_k_contingencies
#
Update the initial metrics with the worst k contingencies.
This function computes the worst k contingencies for each timestep in the initial loadflow results and updates the initial metrics with the case ids and the top k overloads. This way, a baseline for the worst k contingencies to compare to is established, i.e. in the initial loadflow results these are the reference, disregarding the worst k for the specific strategy.
| PARAMETER | DESCRIPTION |
|---|---|
initial_loadflow
|
The initial loadflow results containing the branch results.
TYPE:
|
initial_metrics
|
The initial metrics for each timestep.
TYPE:
|
worst_k
|
The number of worst contingencies to consider for the initial metrics.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
make_runner
#
make_runner(
action_set,
nminus1_definition,
grid_file,
n_processes,
batch_size,
processed_gridfile_fs,
lf_params=None,
)
Initialize a runner for a gridfile, action set and n-1 def
| PARAMETER | DESCRIPTION |
|---|---|
action_set
|
The action set to use
TYPE:
|
nminus1_definition
|
The N-1 definition to use
TYPE:
|
grid_file
|
The grid file to use
TYPE:
|
n_processes
|
The number of processes to use, from the ACGAParameters
TYPE:
|
batch_size
|
The batch size to use, if any, from the ACGAParameters
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
lf_params
|
The loadflow parameters to use for the runner, if any. This is passed in the preprocessing results and can be used to run the loadflows with the same parameters as the initial loadflow in the preprocessing step. If None, the runner will use default parameters.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
AbstractLoadflowRunner
|
The initialized loadflow runner, either Pandapower or Powsybl |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
initialize_optimization
#
initialize_optimization(
params,
session,
optimization_id,
grid_file,
loadflow_result_fs,
processed_gridfile_fs,
)
Initialize an optimization run for the AC optimizer
| PARAMETER | DESCRIPTION |
|---|---|
params
|
The parameters for the AC optimizer
TYPE:
|
session
|
The database session to use for storing topologies
TYPE:
|
optimization_id
|
The ID of the optimization run
TYPE:
|
grid_file
|
The grid file to optimize on
TYPE:
|
loadflow_result_fs
|
A filesystem where the loadflow results are stored. Loadflows will be stored here using the uuid generation process and passed as a StoredLoadflowReference which contains the subfolder in this filesystem.
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
OptimizerData
|
The initial optimizer data |
Strategy
|
The initial strategy |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | |
wait_for_first_dc_results
#
wait_for_first_dc_results(
results_consumer,
session,
max_wait_time,
optimization_id,
heartbeat_fn,
)
Wait an initial period for DC results to arrive before proceeding with the optimization.
Call this after initialize optimization and before run epoch to ensure that the DC optimizer has started, and avoid the AC optimizer idling while waiting for the first DC results to arrive.
| PARAMETER | DESCRIPTION |
|---|---|
results_consumer
|
The consumer where to listen for DC results
TYPE:
|
session
|
The database session to use for storing topologies
TYPE:
|
max_wait_time
|
The maximum time to wait for DC results, in seconds
TYPE:
|
optimization_id
|
The ID of the optimization run, used to filter the incoming topologies and only proceed when DC results from the correct optimization run arrive. Note that other DC runs could be active.
TYPE:
|
heartbeat_fn
|
A function to send heartbeats while waiting for DC results, as this wait time can be relatively long.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
TimeoutError
|
If no DC results arrive within the maximum wait time |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
persist_topology
#
Persist a topology and return the payload needed for later emission.
This function stores the topology in the database, including the loadflow results if available, and returns the final message payload and scoring result. Emission is handled separately so callers can persist without necessarily sending a result immediately.
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
The topology to persist and send
TYPE:
|
scoring_result
|
The scoring result for the topology, containing the metrics, loadflow results and rejection reason if any
TYPE:
|
optimizer_data
|
The optimizer data containing the session and the loadflow storage function
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple[Topology, TopologyScoringResult]
|
The message payload to emit and the final scoring result after persistence handling. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
send_topology_result
#
send_topology_result(
topology_message,
scoring_result,
epoch,
enable_ac_rejection,
send_result_fn,
)
Send the persisted topology result to the result topic.
This function sends either a TopologyPushResult or a TopologyRejectionResult depending on the scoring result and the AC rejection settings.
| PARAMETER | DESCRIPTION |
|---|---|
topology_message
|
The topology message to send, containing the actions, metrics and loadflow result reference
TYPE:
|
scoring_result
|
The scoring result for the topology, containing the metrics, loadflow results and rejection reason if any. The rejection reason will be used to determine whether to send a push result or a rejection result
TYPE:
|
epoch
|
The current epoch number.
TYPE:
|
enable_ac_rejection
|
Whether to enable AC rejection. If True, topologies with a rejection reason in the scoring result will be sent as rejections. If False, all topologies will be sent as push results regardless of the scoring result.
TYPE:
|
send_result_fn
|
The function to send results to the result topic, used for sending either the push result or the rejection result depending on the scoring result and AC rejection settings.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
run_fast_failing_epoch
#
Run one epoch of fast-failing AC evaluation only.
This imports new DC topologies, pulls up to topology_batch_size strategies from the
evolution function, evaluates them with the worst-k fast-failing scorer, and returns the
evaluated strategies together with their early-stage scoring results.
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The optimizer data containing the evolution and fast-failing scoring functions.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ACOptimTopology]
|
The strategies that were pulled and evaluated in the fast-failing stage. |
list[EarlyStoppingStageResult]
|
The corresponding fast-failing scoring results. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
process_fast_failing_results
#
process_fast_failing_results(
optimizer_data,
topologies,
fast_failing_results,
epoch,
send_result_fn,
)
Process the fast-failing stage, emitting only rejected strategies.
Rejected strategies are persisted immediately and emitted as rejections. Surviving strategies are returned so they can be fully evaluated on the remaining contingencies before any accepted push result is sent.
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The optimizer data containing the session and the loadflow storage function.
TYPE:
|
topologies
|
The topologies that were evaluated in the fast-failing stage.
TYPE:
|
fast_failing_results
|
The corresponding fast-failing scoring results, containing the rejection reason if any.
TYPE:
|
epoch
|
The current epoch number, used for logging and for sending in the result messages.
TYPE:
|
send_result_fn
|
The function to send results to the result topic.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ACOptimTopology]
|
The topologies that passed the fast-failing stage and can proceed to the remaining-contingency evaluation. |
list[EarlyStoppingStageResult]
|
The corresponding fast-failing scoring results for the surviving topologies. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
run_remaining_epoch
#
Run one epoch of remaining-contingency AC evaluation only.
This evaluates the full remaining-loadflow stage for strategies that already passed the fast-failing worst-k evaluation and returns the same strategies together with their final scoring results.
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The optimizer data containing the remaining-stage scoring function.
TYPE:
|
topologies
|
The survivor topologies to evaluate in the remaining stage.
TYPE:
|
early_stage_results
|
The corresponding fast-failing stage results for each topology.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ACOptimTopology]
|
The topologies that were evaluated in the remaining stage. |
list[TopologyScoringResult]
|
The corresponding final scoring results. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
process_remaining_results
#
Process the results of the remaining-contingency stage and send the strategies to the result topic.
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The optimizer data containing the session and the loadflow storage function.
TYPE:
|
topologies
|
The topologies that were evaluated in the remaining stage.
TYPE:
|
full_results
|
The corresponding full scoring results, containing the final metrics, loadflow results and rejection reason if any.
TYPE:
|
epoch
|
The current epoch number, used for logging and for sending in the result messages.
TYPE:
|
send_result_fn
|
The function to send results to the result topic.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ACOptimTopology]
|
The topologies that were evaluated in the remaining stage, with their metrics and fitness updated based on the full scoring results. |
list[TopologyScoringResult]
|
The corresponding full scoring results for each topology, which can be used for further processing in the next epoch, e.g. for the evolution function. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
evaluate_remaining_contingencies
#
evaluate_remaining_contingencies(
send_result_fn,
optimizer_data,
epoch,
survivor_topologies,
survivor_early_results,
)
Evaluate the remaining contingencies for the strategies that passed the fast-failing stage.
| PARAMETER | DESCRIPTION |
|---|---|
survivor_topologies
|
The topologies that passed the fast-failing stage and need to be evaluated on the remaining contingencies.
TYPE:
|
survivor_early_results
|
The early results from the fast-failing stage for the topologies that passed.
TYPE:
|
send_result_fn
|
The function to send results to the result topic, used for sending the final results after evaluating the remaining contingencies.
TYPE:
|
optimizer_data
|
The optimizer data containing the scoring function for the remaining contingencies and other necessary data for the evaluation.
TYPE:
|
epoch
|
The current epoch number, used for logging and for sending in the result messages.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/optimizer.py
toop_engine_topology_optimizer.ac.scoring_functions
#
Scoring functions for the AC optimizer - in this case this runs an N-1 and computes metrics for it
ACScoringParameters
dataclass
#
ACScoringParameters(
reject_convergence_threshold,
reject_overload_threshold,
reject_critical_branch_threshold,
base_case_id,
early_stop_validation,
)
Parameters for ac scoring
This is a subset of all ac parameters and grouped to shorten the signature of the scoring and acceptance functions.
reject_convergence_threshold
instance-attribute
#
The rejection threshold for the convergence rate, i.e. the split case must have at most the same amount of non converging loadflows as the unsplit case or it will be rejected.
reject_overload_threshold
instance-attribute
#
The rejection threshold for the overload energy improvement, i.e. the split case must have at least 5% lower overload energy than the unsplit case or it will be rejected.
reject_critical_branch_threshold
instance-attribute
#
The rejection threshold for the critical branches increase, i.e. the split case must have less than 10% more critical branches than the unsplit case or it will be rejected.
base_case_id
instance-attribute
#
The base case id for the loadflow runner (used to separately compute the N-0 flows).
early_stop_validation
instance-attribute
#
Whether to enable early stopping during the optimization process.
get_early_stopping_contingency_ids
#
Extract the contingency ids for early stopping from a list of ACOptimTopology strategies.
This function extracts the worst k contingency case ids from each topology's worst_k_contingency_cases attribute for each timestep. These ids are used to determine which contingencies to include in the N-1 analysis for early stopping.
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
An ACOptimTopology object containing a worst_k_contingency_cases attribute with contingency case ids.
TYPE:
|
base_case_id
|
An optional base case id to include in the early stopping subset. If provided, this will be added to the list of contingency case ids for each timestep.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Optional[list[str]]
|
A list of contingency case IDs, or None if any required metric is missing. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
update_runner_nminus1
#
Update the N-1 definitions in the runners to only include the worst k contingencies.
This modifies the N-1 definitions in the runners to only include the contingencies at the given indices.
| PARAMETER | DESCRIPTION |
|---|---|
runner
|
The loadflow runner to update.
TYPE:
|
nminus1_def
|
The original N-1 definition to use as a template.
TYPE:
|
case_ids_all_t
|
A list of contingency ids for each runner, indicating which contingencies to keep in the N-1 definition. Each element should be an index to the contingencies in the original N-1 definition.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
compute_loadflow_and_metrics
#
Compute loadflow results and associated metrics for a given set of strategies.
This function runs loadflow simulations for each provided strategy using the specified runners, then computes additional metrics based on the simulation results.
| PARAMETER | DESCRIPTION |
|---|---|
runner
|
The loadflow runner to use for simulations.
TYPE:
|
topology
|
The topology to evaluate.
TYPE:
|
base_case_id
|
The base case identifier for the topology. Can be None.
TYPE:
|
cases_subset
|
Subset of contingency cases to use for loadflow computation. If None, all available contingencies are used.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
lfs
|
The results of the loadflow simulations.
TYPE:
|
additional_info
|
Additional information for the actions taken in the topology.
TYPE:
|
metrics
|
Computed metrics for the topology.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
extract_switching_distance
#
Extract the switching distance from the additional action info
| PARAMETER | DESCRIPTION |
|---|---|
additional_info
|
The additional action info containing the switching distance
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
int
|
The switching distance, or 0 if not available |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
compute_metrics_single_timestep
#
compute_metrics_single_timestep(
actions,
disconnections,
loadflow,
additional_info,
base_case_id=None,
)
Compute the metrics for a single timestep
| PARAMETER | DESCRIPTION |
|---|---|
actions
|
The reconfiguration assignment for the timestep
TYPE:
|
disconnections
|
The disconnections for the timestep
TYPE:
|
loadflow
|
The loadflow results for the timestep, use select_timestep to get the results for a specific timestep
TYPE:
|
additional_info
|
Additional information about the actions taken, such as switching distance or other metrics.
TYPE:
|
base_case_id
|
The base case id from the nminus1 definition, to separate N-0 flows from N-1
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Metrics
|
The metrics for the timestep |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
compute_loadflow
#
Compute the loadflow for a given strategy
| PARAMETER | DESCRIPTION |
|---|---|
actions
|
The reconfiguration actions for the timestep
TYPE:
|
disconnections
|
The disconnections for the timestep
TYPE:
|
pst_setpoints
|
The PST setpoints for the topology, or None if PST taps are not part of the topology.
TYPE:
|
runner
|
The loadflow runner to use
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
LoadflowResultsPolars
|
The loadflow results for all timesteps in the strategy |
list[Optional[AdditionalActionInfo]]
|
Additional information about the actions taken, such as switching distance or other metrics. The length of the list is n_timesteps. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
evaluate_acceptance
#
evaluate_acceptance(
metrics_split,
metrics_unsplit,
reject_convergence_threshold=1.0,
reject_overload_threshold=0.95,
reject_critical_branch_threshold=1.1,
early_stopping=False,
)
Evaluate if the split loadflow results are acceptable compared to the unsplit results.
Compares the unsplit metrics * the thresholds to the split metrics. If all split metrics are better than the unsplit metrics * thresholds, the split results are accepted.
Checked metrics are: non_converging_loadflows: the number of non-converging loadflows should be less than or equal to reject_convergence_threshold * unsplit.extra_scores.get("non_converging_loadflows", 0) overload_energy_n_1: the overload energy should be less than or equal to reject_overload_threshold * unsplit.extra_scores.get("overload_energy_n_1", 0) critical_branch_count_n_1: the number of critical branches should be less than or equal to reject_critical_branch_threshold * unsplit.extra_scores.get("critical_branch_count_n_1", 0) TODO: Check Voltage Jumps between N0 and N1
| PARAMETER | DESCRIPTION |
|---|---|
metrics_split
|
The metrics for the split case.
TYPE:
|
metrics_unsplit
|
The metrics for the unsplit case.
TYPE:
|
reject_convergence_threshold
|
The threshold for the convergence rate, by default 1. (i.e. the split case must have at most the same amount of nonconverging loadflows as the unsplit case.)
TYPE:
|
reject_overload_threshold
|
The threshold for the overload energy improvement, by default 0.95 (i.e. the split case must have at least 5% lower overload energy than the unsplit case).
TYPE:
|
reject_critical_branch_threshold
|
The threshold for the critical branches increase, by default 1.1 (i.e. the split case must not have more than 110 % of the critical branches in the unsplit case).
TYPE:
|
early_stopping
|
Whether the acceptance is computed as part of an early stopping criterion, will set the early_stopping field in the TopologyRejectionReason
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Optional[TopologyRejectionReason]
|
A TopologyRejectionReason if the split results are rejected, None if accepted. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | |
compute_remaining_loadflows
#
Compute the loadflows for the remaining contingencies that were not included in the early stopping subset.
This function is called after the early stopping loadflows have been computed and accepted. It computes the loadflows for the remaining contingencies that were not included in the early stopping subset, and then computes the metrics for the full set of loadflows.
| PARAMETER | DESCRIPTION |
|---|---|
runner
|
The loadflow runners to use, length n_timesteps.
TYPE:
|
topology
|
The topology to score, length n_timesteps
TYPE:
|
base_case_id
|
The base case id for the loadflow runners, used to separately compute the N-0 flows.
TYPE:
|
loadflows_subset
|
The loadflow results for the early stopping subset, used to avoid recomputing these loadflows.
TYPE:
|
cases_subset
|
The contingency case ids that were included in the early stopping subset for each timestep. This could be extracted from the loadflows_subset but as it is available it is faster to pass it in.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
LoadflowResultsPolars
|
The loadflow results for all contingencies, including those from the early stopping subset. |
Metrics
|
The metrics for the full set of loadflows. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
score_strategy_worst_k
#
score_strategy_worst_k(
topology,
runner,
loadflow_results_unsplit,
metrics_unsplit,
scoring_params,
)
Evaluate only the worst-k stage for a single strategy.
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
The topology to evaluate, length n_timesteps
TYPE:
|
runner
|
The loadflow runner to use for the evaluation of the strategy
TYPE:
|
loadflow_results_unsplit
|
The loadflow results for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
metrics_unsplit
|
The metrics for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
scoring_params
|
The parameters for scoring, including thresholds for acceptance and early stopping settings.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
EarlyStoppingStageResult
|
The result of the worst-k stage evaluation, including loadflow results, metrics and rejection reason if rejected. If early stopping is enabled and the strategy is rejected based on the worst-k contingencies, the early_stopping flag will be set. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 | |
score_strategy_worst_k_batch
#
score_strategy_worst_k_batch(
topologies,
worst_k_runner_groups,
loadflow_results_unsplit,
metrics_unsplit,
scoring_params,
)
Evaluate the worst-k stage for a batch of strategies.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to evaluate, length n_strategies.
TYPE:
|
worst_k_runner_groups
|
The loadflow runner groups to use for the evaluation of the strategies, length n_strategies.
TYPE:
|
loadflow_results_unsplit
|
The loadflow results for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
metrics_unsplit
|
The metrics for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
scoring_params
|
The parameters for scoring, including thresholds for acceptance and early stopping settings.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[EarlyStoppingStageResult]
|
The results of the worst-k stage evaluation for each strategy, including loadflow results, metrics and rejection reason if rejected. If early stopping is enabled and a strategy is rejected based on the worst-k contingencies, the early_stopping flag will be set in the rejection reason. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
score_topology_remaining
#
Evaluate the remaining contingencies for a surviving strategy.
This function is called for strategies that survived the worst-k stage (i.e. were not rejected based on the worst-k contingencies). It computes the loadflows for the remaining contingencies that were not included in the worst-k stage, and then computes the metrics for the full set of loadflows. Finally, it evaluates the acceptance of the full set of loadflows compared to the unsplit case.
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
The topology to evaluate, length n_timesteps
TYPE:
|
runner
|
The loadflow runner to use for the evaluation of the strategy
TYPE:
|
metrics_unsplit
|
The metrics for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
scoring_params
|
The parameters for scoring, including thresholds for acceptance and early stopping settings.
TYPE:
|
early_stage_result
|
The result from the worst-k stage evaluation, including loadflow results, metrics and cases subset used for early stopping. This is used to compute the remaining loadflows and metrics without recomputing the early stopping subset.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
TopologyScoringResult
|
The result of the full evaluation, including loadflow results, metrics and rejection reason if rejected. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
score_strategy_full
#
Evaluate a strategy on the full set of contingencies in one pass.
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
The topology to evaluate, length n_timesteps
TYPE:
|
runner
|
The loadflow runner to use for the evaluation of the strategy
TYPE:
|
metrics_unsplit
|
The metrics for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
scoring_params
|
The parameters for scoring, including thresholds for acceptance and early stopping settings.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
TopologyScoringResult
|
The result of the full evaluation, including loadflow results, metrics and rejection reason if rejected. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
score_strategy_full_batch
#
Evaluate a batch of topologies on the full set of contingencies.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to evaluate, length n_strategies.
TYPE:
|
runner_groups
|
The loadflow runner groups to use for the evaluation of the strategies, length n_strategies.
TYPE:
|
metrics_unsplit
|
The metrics for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
scoring_params
|
The parameters for scoring, including thresholds for acceptance and early stopping settings.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[TopologyScoringResult]
|
The results of the full evaluation for each strategy, including loadflow results, metrics and rejection reason if rejected. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
score_remaining_contingency_batch
#
score_remaining_contingency_batch(
topologies,
early_stage_results,
runner_group,
metrics_unsplit,
scoring_params,
)
Evaluate the remaining contingencies for a batch of surviving topologies.
This function is called for strategies that survived the worst-k stage (i.e. were not rejected based on the worst-k contingencies). It computes the loadflows for the remaining contingencies that were not included in the worst-k stage, and then computes the metrics for the full set of loadflows.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to evaluate, length n_strategies.
TYPE:
|
early_stage_results
|
The results from the worst-k stage evaluation for each topology, including loadflow results, metrics and cases subset used for early stopping. This is used to compute the remaining loadflows and metrics without recomputing the early stopping subset.
TYPE:
|
runner_group
|
The loadflow runner group to use for the evaluation of the strategies, length n_strategies.
TYPE:
|
metrics_unsplit
|
The metrics for the unsplit case, used for comparison in the acceptance evaluation.
TYPE:
|
scoring_params
|
The parameters for scoring, including thresholds for acceptance and early stopping settings.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[TopologyScoringResult]
|
The results of the full evaluation for each strategy, including loadflow results, metrics and rejection reason if rejected. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 | |
score_topology_batch
#
score_topology_batch(
topologies,
runner_group,
metrics_unsplit,
scoring_params,
early_stage_results=None,
)
Score a batch of topologies in two stages.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to be scored.
TYPE:
|
runner_group
|
The group of runners to use for scoring.
TYPE:
|
metrics_unsplit
|
The metrics to be used for scoring.
TYPE:
|
scoring_params
|
The parameters for scoring, including thresholds for acceptance and early stopping settings.
TYPE:
|
early_stage_results
|
The results from the early stage, by default None.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[TopologyScoringResult]
|
The results of the full evaluation for each strategy, including loadflow results, metrics and rejection reason if rejected. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/scoring_functions.py
toop_engine_topology_optimizer.ac.select_strategy
#
Selection strategy for AC optimization topologies.
select_strategy
#
select_strategy(
rng,
repertoire,
candidates,
interest_scorer,
batch_size=1,
lower_scores_are_better=False,
filter_strategy=None,
)
Select promising unevaluated topologies from the candidate pool.
Make sure the repertoire only contains topologies with the right optimizer type and optimization id as select_strategy will not filter for this.
| PARAMETER | DESCRIPTION |
|---|---|
rng
|
The random number generator to use
TYPE:
|
repertoire
|
The filtered repertoire with all individuals of the optimization in all optimizer types
TYPE:
|
candidates
|
Candidates which have not yet been evaluated. For a pull operation this will only include DC candidates without an AC parent.
TYPE:
|
interest_scorer
|
The function to score the topologies in the candidate pool. The higher the score, the more interesting the topology is. Eventually, the topology will be selected with a probability proportional to its score.
TYPE:
|
batch_size
|
Number of topologies to sample without replacement. If more topologies are requested than available candidates, all available candidates are returned.
TYPE:
|
lower_scores_are_better
|
Whether lower values returned by
TYPE:
|
filter_strategy
|
Whether to filter the candidates based on discriminator, median or dominator filter.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[BaseDBTopology]
|
The selected topologies sampled from the candidate pool. If no topology could be selected because the candidate pool is empty, return an empty list |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/select_strategy.py
filter_metrics_df
#
Get a mask for the metrics DataFrame that filters out rows based on discriminator and median masks.
This function applies a discriminator, median and dominator mask.
| PARAMETER | DESCRIPTION |
|---|---|
metrics_df
|
The DataFrame containing the metrics to filter. This is typically the DC repertoire from which new results shall be pulled.
TYPE:
|
discriminator_df
|
The DataFrame containing the discriminator metrics. These are topologies that have previously been AC validated
TYPE:
|
filter_strategy
|
The filter strategy to use for the optimization, used to filter out strategies based on the discriminator, median or dominator filter.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
The filtered metrics DataFrame with similar topologies removed. If all topologies are filtered out, the original metrics DataFrame is returned. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/select_strategy.py
get_repertoire_filter_mask
#
Get a mask for the metrics DataFrame that filters out rows based on discriminator and median masks.
This function applies a discriminator, median and dominator mask.
| PARAMETER | DESCRIPTION |
|---|---|
metrics_df
|
The DataFrame containing the metrics to filter.
TYPE:
|
discriminator_df
|
The DataFrame containing the discriminator metrics.
TYPE:
|
filter_strategy
|
The filter strategy to use for the optimization, used to filter out strategies based on the discriminator, median or dominator filter.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Bool[ndarray, ' metrics_df.shape[0]']
|
A boolean mask where True indicates the row is not filtered out. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/select_strategy.py
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | |
get_median_mask
#
Get a mask for fitness values below the median for each discrete value of the target metrics.
Note: expects the target metrics to be discrete values, not continuous.
| PARAMETER | DESCRIPTION |
|---|---|
metrics_df
|
The DataFrame containing the metrics to filter.
TYPE:
|
target_metrics
|
A list of metrics with discrete values to consider for filtering. example: ["split_subs"].
TYPE:
|
fitness_col
|
The column name that contains the fitness values. Defaults to "fitness".
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
filter_mask
|
A boolean mask where True indicates the row is not below the median for any of the target metrics.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/select_strategy.py
get_dominator_mask
#
Get a mask for rows from a DataFrame that are dominated by other rows based on specified metrics.
A metric entry if there is any other metric entry with a better fitness, in respect to the distance to the original topology. The distance in measured by the metric, assuming that lower values are better.
The target metric is used to fix the discrete value for which the dominance is checked. The fitness column is used to determine the fitness of the rows. Each observed metric is checked against the minimum fitness of all discrete target values.
Intended use is target_metrics = ["switching_distance", "split_subs"] and observed_metrics = Any additional metric to the target metrics, e.g. "disconnections"
| PARAMETER | DESCRIPTION |
|---|---|
metrics_df
|
The DataFrame to filter.
TYPE:
|
target_metrics
|
A list of metrics to consider for dominance. A target metric is expected to have discrete values (e.g. not fitness, overload_energy, or max_flow) If None, defaults to ["switching_distance", "split_subs"].
TYPE:
|
observed_metrics
|
A list of metrics to observe for dominance. If None, defaults to ["switching_distance", "split_subs"].
TYPE:
|
fitness_col
|
The column name that contains the fitness values. Defaults to "fitness". Note: the values are expected to be negative, best fitness converges to zero.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
filter_mask
|
A boolean mask where True indicates the row is not dominated by another row.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/select_strategy.py
get_discriminator_mask
#
Get a mask for rows in metrics_df that are within a certain distance from the discriminator_df.
The distance is defined by the metric_distances dictionary, which contains the metrics and their respective distances.
Use the use_split_sub_multiplier flag to apply a multiplier in respect to the split_subs_col.
e.g. use_split_sub_multiplier=False, the metric_distances is applied directly to the metrics_df.
If use_split_sub_multiplier=True, the metric_distances are multiplied by the split_subs, leading to a
larger distance for larger split_subs values.
| PARAMETER | DESCRIPTION |
|---|---|
metrics_df
|
The DataFrame containing the metrics to filter.
TYPE:
|
discriminator_df
|
The DataFrame containing the discriminator metrics.
TYPE:
|
metric_distances
|
A dictionary defining the metric distances for filtering. The keys are metric names and the values are sets of distances. example: metric_distances = { "split_subs": {0}, "switching_distance": {-0.9, 0.9}, "fitness": {-0.1, 0.1}, } Note: the fitness is treated as a percentage.
TYPE:
|
metric_multiplier
|
A dictionary defining multiplier for the metric distances.
The keys are metric names and the values are multipliers.
If None, defaults to an empty dictionary.
Multiple values are added by:
distance_multiplier = (
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
filter_mask
|
A boolean mask where True indicates the row is not within the distance defined by the discriminator_df and metric_distances.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If not all metric distances are present in the discriminator DataFrame columns. If the metric_distances is None, it will use default values based on the use_split_sub_multiplier flag. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/select_strategy.py
327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 | |
get_discriminator_df
#
Get a discriminator DataFrame from the metrics DataFrame.
The discriminator DataFrame is a subset of the metrics DataFrame that contains only the target metrics. It is used to filter out similar topologies from the metrics DataFrame.
| PARAMETER | DESCRIPTION |
|---|---|
metrics_df
|
The DataFrame containing the metrics to filter. Note: expects the metrics_df to contain only AC topologies that have as a metric the "fitness_dc" column.
TYPE:
|
target_metrics
|
A list of metrics to consider for filtering.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DataFrame
|
A DataFrame containing only the target metrics. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/select_strategy.py
toop_engine_topology_optimizer.ac.storage
#
The database models to store topologies in the AC optimizer
ACOptimTopology
#
Bases: BaseDBTopology
Inherits from the base topology to make a database table for AC optimizer topologies
This can include both AC and DC topologies, with the specific needs of the AC optimizer
parent_id
class-attribute
instance-attribute
#
The mutation parent id, i.e. the topology that this topology was mutated from. This is mostly for debugging purposes to see where a topology came from and understand the mutation process.
acceptance
class-attribute
instance-attribute
#
Whether the strategy was accepted or not.
id
class-attribute
instance-attribute
#
The table primary key
actions
class-attribute
instance-attribute
#
The branch/injection reconfiguration actions as indices into the action set.
disconnections
class-attribute
instance-attribute
#
A list of disconnections, indexing into the disconnectable branches set in the action set.
pst_setpoints
class-attribute
instance-attribute
#
The setpoints for the PSTs if they have been computed. This is an index into the range of pst taps, i.e. the smallest tap is 0 and the neutral tap somewhere in the middle of the range. The tap range is defined in the action set. The list always has the same length, i.e. the number of controllable PSTs in the system, and each entry corresponds to the PST at the same position in the action set.
unsplit
instance-attribute
#
Whether all topologies in the strategy including this one have no branch assignments, disconnections or injections.
strategy_hash
instance-attribute
#
The hash of the strategy - this hashes actions, disconnections and pst_setpoints for all timesteps in the strategy, making it possible to form a unique constraint on the strategy. This value will be set to the same for all topologies in the same strategy, furthermore making it possible to group timesteps.
metrics
class-attribute
instance-attribute
#
The metrics of this topology
worst_k_contingency_cases
class-attribute
instance-attribute
#
The worst k contingency case IDs for the topology.
created_at
class-attribute
instance-attribute
#
The time the topology was recorded in the database
stored_loadflow_reference
class-attribute
instance-attribute
#
The file reference for the loadflow results of this topology/strategy, if they were computed. Multiple topologies belonging to the same strategy will have the same serialized loadflow results object as there is a timestep notion in the loadflow results. To obtain the correct loadflow results, use the timestep attribute. This is stored as a json serialized StoredLoadflowReference object
__table_args__
class-attribute
instance-attribute
#
__table_args__ = (
UniqueConstraint(
"optimization_id",
"optimizer_type",
"strategy_hash",
"timestep",
name="topo_unique",
),
)
get_loadflow_reference
#
Get the loadflow reference as a StoredLoadflowReference object
| RETURNS | DESCRIPTION |
|---|---|
Optional[StoredLoadflowReference]
|
The loadflow reference, or None if it is not set |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/interfaces/models/base_storage.py
set_loadflow_reference
#
Set the loadflow reference from a StoredLoadflowReference object
| PARAMETER | DESCRIPTION |
|---|---|
loadflow_reference
|
The loadflow reference to set, or None to unset it
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/interfaces/models/base_storage.py
FinishedOptimizations
#
Bases: SQLModel
A table to store finished optimizations, to prevent picking up old topologies from previous optimizations
optimization_id
class-attribute
instance-attribute
#
The optimization ID of the finished optimization as sent via kafka
optimizer_type
class-attribute
instance-attribute
#
Which optimizer type has finished
finished_at
class-attribute
instance-attribute
#
When the optimization was marked as finished in the database
convert_single_topology
#
convert_single_topology(
topology,
optimization_id,
optimizer_type,
timestep,
strategy_hash,
unsplit,
)
Convert a single Topology to a ACOptimTopology
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
The topology to convert
TYPE:
|
optimization_id
|
The optimization ID to assign to the db topology
TYPE:
|
optimizer_type
|
The optimizer type to assign to the db topology
TYPE:
|
timestep
|
The timestep of the topology
TYPE:
|
strategy_hash
|
The hash of the strategy computed through hash_strategy
TYPE:
|
unsplit
|
Whether the strategy is unsplit
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ACOptimTopology
|
The converted topology |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/storage.py
convert_message_topo_to_db_topo
#
Convert a TopologyPushResult to a list of ACOptimTopology
| PARAMETER | DESCRIPTION |
|---|---|
message_strategy
|
The strategy to convert, usually from a TopologyPushResult or OptimizationStartedResult. Strategy timesteps are flattened into the list of topologies that are being returned.
TYPE:
|
optimization_id
|
The optimization ID to assign to the topologies. This was sent through with the parent result message and is not part of TopologyPushResult
TYPE:
|
optimizer_type
|
The optimizer type to assign. This was sent through with the parent result message and is not part of TopologyPushResult
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[ACOptimTopology]
|
A list of converted topologies where for each timestep a new ACOptimTopology instance is created. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/storage.py
create_session
#
Create a thread-safe shared in-memory SQLite session for the AC worker.
Using StaticPool plus check_same_thread=False keeps the
worker on a single shared in-memory database connection.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/storage.py
scrub_db
#
Scrub the database of the worker to prevent memory issues.
The AC worker has to store topologies from all runs, not only the current one, as it might have to pick up an optimization later. Meaning, the AC worker busily collects all topologies into memory. To prevent memory leak issues, we scrub the database of topologies that are older than a day as we do not expect to ever have to go back to those.
| PARAMETER | DESCRIPTION |
|---|---|
session
|
The database session. The session object will be modified in-place
TYPE:
|
max_age_seconds
|
The maximum age of topologies to keep in the database, in seconds. Topologies older than this will be removed.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/storage.py
toop_engine_topology_optimizer.ac.worker
#
The AC worker that listens to the kafka topics, organizes optimization runs, etc.
Args
#
Bases: Args
Command line arguments for the AC worker.
Mostly the same as the DC worker except for an additional loadflow results folder
kafka_broker
class-attribute
instance-attribute
#
The Kafka broker to connect to.
optimizer_command_topic
class-attribute
instance-attribute
#
The Kafka topic to listen for commands on.
optimizer_results_topic
class-attribute
instance-attribute
#
The topic to push results to.
optimizer_heartbeat_topic
class-attribute
instance-attribute
#
The topic to push heartbeats to.
heartbeat_interval_ms
class-attribute
instance-attribute
#
The interval in milliseconds to send heartbeats.
max_command_age_hours
class-attribute
instance-attribute
#
The maximum age of a command in hours. If a command is received that is older than this, the command will be ignored.
WorkerData
dataclass
#
Data that is stored across optimization runs
command_consumer
instance-attribute
#
A kafka consumer listening in for optimization commands
result_consumer
instance-attribute
#
A kafka consumer listening on the results topic, constantly writing results to the database. This is polled both during the optimization and idle loop to keep the database up to date.
initialize_optimization_run
#
initialize_optimization_run(
ac_params,
grid_file,
worker_data,
send_result_fn,
send_heartbeat_fn,
optimization_id,
loadflow_result_fs,
processed_gridfile_fs,
)
Initialize the AC optimization and wait for the first DC results.
Parameters are identical to optimization_loop plus the bound logger.
| RETURNS | DESCRIPTION |
|---|---|
tuple[OptimizerData, Strategy]
|
The initialized optimizer data and the initial topology message. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/worker.py
run_optimization_epochs
#
run_optimization_epochs(
ac_params,
optimizer_data,
worker_data,
send_result_fn,
send_heartbeat_fn,
optimization_id,
)
Run the iterative AC optimization phase.
| PARAMETER | DESCRIPTION |
|---|---|
ac_params
|
The parameters for the AC optimizer
TYPE:
|
optimizer_data
|
The initialized optimizer data containing the curried functions and database session
TYPE:
|
worker_data
|
The dataclass with the results consumer and database
TYPE:
|
send_result_fn
|
The function to send results
TYPE:
|
send_heartbeat_fn
|
The function to send heartbeats
TYPE:
|
optimization_id
|
The ID of the optimization run
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
None
|
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/worker.py
140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | |
summarize_optimization_run
#
summarize_optimization_run(
optimization_id,
grid_file,
worker_data,
optimizer_data,
processed_gridfile_fs,
)
Write the optimization summary artifacts.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/worker.py
optimization_loop
#
optimization_loop(
ac_params,
grid_file,
worker_data,
send_result_fn,
send_heartbeat_fn,
optimization_id,
loadflow_result_fs,
processed_gridfile_fs,
)
Run the main loop for the AC optimizer.
This function will run the AC optimizer on the given grid files with the given parameters.
| PARAMETER | DESCRIPTION |
|---|---|
ac_params
|
The parameters for the AC optimizer
TYPE:
|
grid_file
|
The grid file to optimize on
TYPE:
|
worker_data
|
The dataclass with the results consumer and database
TYPE:
|
send_result_fn
|
The function to send results
TYPE:
|
send_heartbeat_fn
|
The function to send heartbeats
TYPE:
|
optimization_id
|
The ID of the optimization run
TYPE:
|
loadflow_result_fs
|
A filesystem where the loadflow results are stored. Loadflows will be stored here using the uuid generation process and passed as a StoredLoadflowReference which contains the subfolder in this filesystem.
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/worker.py
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | |
idle_loop
#
idle_loop(
worker_data,
send_heartbeat_fn,
send_result_fn,
heartbeat_interval_ms,
max_command_age_hours,
)
Run idle loop of the AC optimizer worker.
This will be running when the worker is currently not optimizing This will wait until a StartOptimizationCommand is received and return it. In case a ShutdownCommand is received, the worker will exit with the exit code provided in the command.
| PARAMETER | DESCRIPTION |
|---|---|
worker_data
|
The dataclass with the command consumer, results consumer and database
TYPE:
|
send_heartbeat_fn
|
A function to call when there were no messages received for a while.
TYPE:
|
send_result_fn
|
A function to call to send results back to the results topic, used to send a message in case a command is too old.
TYPE:
|
heartbeat_interval_ms
|
The time to wait for a new command in milliseconds. If no command has been received, a heartbeat will be sent and then the receiver will wait for commands again.
TYPE:
|
max_command_age_hours
|
The maximum age of a command in hours. If a command is received that is older than this, the command will be ignored and a message will be sent to the results topic.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
StartOptimizationCommand
|
The start optimization command to start the optimization run with |
| RAISES | DESCRIPTION |
|---|---|
SystemExit
|
If a ShutdownCommand is received |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/worker.py
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 | |
warmup_result_storage
#
Go through the results topic and stores all published topology results in the database
This way, when an optimization run starts, the local in-memory results storage is already populated with results, so no time is wasted in spooling through the results topic.
| PARAMETER | DESCRIPTION |
|---|---|
worker_data
|
The dataclass with the results consumer and database
TYPE:
|
heartbeat_fn
|
A function to call to send heartbeats during the warmup loop, as it can take a while if there are many results to spool through.
TYPE:
|
heartbeat_interval_ms
|
The time interval in milliseconds to send heartbeats during the warmup loop, by default 5000 ms
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/worker.py
main
#
main(
args,
loadflow_result_fs,
processed_gridfile_fs,
producer,
command_consumer,
result_consumer,
)
Run the main AC worker loop.
| PARAMETER | DESCRIPTION |
|---|---|
args
|
The command line arguments
TYPE:
|
loadflow_result_fs
|
A filesystem where the loadflow results are stored. Loadflows will be stored here using the uuid generation process and passed as a StoredLoadflowReference which contains the subfolder in this filesystem.
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
producer
|
A kafka producer to send heartbeats and results
TYPE:
|
command_consumer
|
A kafka consumer listening in for optimization commands
TYPE:
|
result_consumer
|
A kafka consumer listening in for results
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
SystemExit
|
If the worker receives a ShutdownCommand |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/ac/worker.py
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | |
Benchmarks#
toop_engine_topology_optimizer.benchmark.benchmark
#
Run benchmark.
This module provides functionality to run benchmark tasks based on a provided configuration.
It supports grid search for sweeping through the values of number of CUDA devices or a single parameter
not defined inside lf_config and ga_config. Multiple parameter sweeps are not supported yet.
| FUNCTION | DESCRIPTION |
|---|---|
main |
|
main
#
Run benchmark tasks based on the provided configuration.
| PARAMETER | DESCRIPTION |
|---|---|
cfg
|
Configuration object containing benchmark tasks and output settings.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
None
|
|
Notes
The function performs the following steps: 1. Iterates over the benchmark tasks specified in the configuration. 2. Checks for grid search configurations and generates new configurations for each value in the grid. 3. Sets environment variables for each benchmark task. 4. Runs each benchmark task in a separate process to avoid side-effects. 5. Collects the results and logs them into a JSON file specified in the configuration.
Grid search currently supports sweeping through the values of number of CUDA devices or
a single parameter not defined inside lf_config and ga_config. Multiple parameter sweeps are not supported yet.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/benchmark/benchmark.py
DC Optimizer#
toop_engine_topology_optimizer.dc.ga_helpers
#
Helper functions for genetic algorithms.
MixingEmitterState
#
Bases: EmitterState
The state of a MixingEmitter.
It extends the EmitterState with additional fields to track the number of branch and injection combinations and splits.
TrackingMixingEmitter
#
Bases: MixingEmitter
A MixingEmitter that tracks the number of branch and injection combinations and splits.
init
#
Overwrite the Emitter.init function to seed an EmitterState.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/ga_helpers.py
state_update
#
Overwrite the state update to store information for the running means.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/ga_helpers.py
RunningMeans
dataclass
#
RunningMeans(
start_time,
last_time,
time_step,
total_branch_combis,
total_inj_combis,
br_per_sec,
inj_per_sec,
split_per_iter,
last_emitter_state,
n_outages,
n_devices,
)
A dataclass to hold the running means estimations for the TQDM progress bar.
init_running_means
#
Initialize an empty RunningMeans object.
| PARAMETER | DESCRIPTION |
|---|---|
n_outages
|
The number of outages
TYPE:
|
n_devices
|
The number of devices
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
RunningMeans
|
The initialized running means |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/ga_helpers.py
update_running_means
#
Aggregate the emitter state statistics into the running means.
| PARAMETER | DESCRIPTION |
|---|---|
running_means
|
The running means to be updated
TYPE:
|
emitter_state
|
The emitter state of the current iteration
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
RunningMeans
|
The updated running means |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/ga_helpers.py
toop_engine_topology_optimizer.dc.main
#
Launcher for the Map-Elites optimizer.
example args:
--fixed_files /workspaces/AICoE_HPC_RL_Optimizer/data/static_information.hdf5 --stats_dir /workspaces/AICoE_HPC_RL_Optimizer/stats/ --tensorboard_dir /workspaces/AICoE_HPC_RL_Optimizer/stats/tensorboard/ --ga_config.target_metrics overload_energy_n_1 1.0 # The metrics to optimize with their weight --ga_config.me_descriptors.0.metric split_subs --ga_config.me_descriptors.0.num_cells 5 --ga_config.me_descriptors.1.metric switching_distance --ga_config.me_descriptors.1.num_cells 45 # The metrics to use as descriptors along with their maximum value --ga_config.observed_metrics overload_energy_n_1 split_subs switching_distance # All the relevant metrics, including target, descriptors and extra metrics you want to see in the report --ga_config.substation_unsplit_prob 0.5 # Instinctively better suited for mapelites --ga_config.substation_split_prob 0.5 # Instinctively better suited for mapelites --ga_config.plot # Enable plot generation and saving in stats_dir/plots/ --ga_config.iterations_per_epoch 50 # Basically how often you wanna get a report. Suggested range : 50 - 1000 --ga_config.runtime_seconds 300 # How many seconds to run the optimization for The first descriptor metric is the vertical axis, the second the horizontal axis.
CLIArgs
#
Bases: BaseModel
The arguments for a CLI invocation, mostly equal to OptimizationStartCommand.
ga_config
class-attribute
instance-attribute
#
ga_config = Field(default_factory=BatchedMEParameters)
The configuration for the genetic algorithm
lf_config
class-attribute
instance-attribute
#
lf_config = Field(default_factory=LoadflowSolverParameters)
The configuration for the loadflow solver
fixed_files
class-attribute
instance-attribute
#
The file containing the static information. You can pass multiple files here
tensorboard_dir
class-attribute
instance-attribute
#
The directory to store the tensorboard logs
stats_dir
class-attribute
instance-attribute
#
The directory to store the json summaries
summary_frequency
class-attribute
instance-attribute
#
How often to write tensorboard summaries
checkpoint_frequency
class-attribute
instance-attribute
#
How often to write json summaries
double_limits
class-attribute
instance-attribute
#
The double limits to use in the form (lower_limit, upper_limit). lower_limit: float The relative lower limit to set, for branches whose n-1 flows are below the lower limit upper_limit: float The relative upper_limit determining at what relative load a branch is considered overloaded. Branches in the band between lower and upper limit are considered overloaded if more load is added.
log_tensorboard
#
Log fitness and metrics to tensorboard.
| PARAMETER | DESCRIPTION |
|---|---|
fitness
|
The fitness value
TYPE:
|
metrics
|
The metrics to log
TYPE:
|
iteration
|
The current iteration number
TYPE:
|
writer
|
The tensorboard writer
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/main.py
write_summary
#
write_summary(
optimizer_data,
repertoire,
emitter_state,
iteration,
folder,
cli_args,
processed_gridfile_fs,
final_results=False,
)
Write a summary to a json file.
Watch out : here, the optimizer data is out of sync with the jax_data
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The optimizer data of the optimization. This includes a jax_data, however as the jax_data is updated per-iteration and the optimizer_data only per-epoch, we need to pass the jax_data separately
TYPE:
|
repertoire
|
The current repertoire for this iteration, will be used instead of the one in the optimizer_data |
emitter_state
|
The emitter state for this iteration, will be used instead of the one in the optimizer_data
TYPE:
|
iteration
|
The iteration number
TYPE:
|
folder
|
The folder to write the summary to, relative to the processed_gridfile_fs
TYPE:
|
cli_args
|
The arguments used for invocation, will be added to the summary for documentation purposes
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
final_results
|
Whether this is the final results summary "res.json" or an intermediate one "res_{iteration}.json"
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
The summary that was written |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/main.py
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | |
main
#
Run main optimization function for CLI execution.
| PARAMETER | DESCRIPTION |
|---|---|
args
|
The arguments for the optimization
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
The final results of the optimization |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/main.py
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | |
Genetic Algorithm Functions#
toop_engine_topology_optimizer.dc.genetic_functions.genotype
#
Dataclass for the genotype used in the genetic algorithm.
Genotype
#
Bases: Module
A single genome in the repertoire representing a topology.
disconnections
instance-attribute
#
The disconnections to apply, padded with int_max for disconnection slots that are unused. These are indices into the disconnectable branches set.
nodal_injections_optimized
instance-attribute
#
The results of the nodal injection optimization, if any was performed.
deduplicate_genotypes
#
Deduplicate the genotypes in the repertoire.
This version is jittable because we set the size
| PARAMETER | DESCRIPTION |
|---|---|
genotypes
|
The genotypes to deduplicate. These should be sorted by action id already.
TYPE:
|
desired_size
|
How many unique values you are expecting. If not given, this is not jittable
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Genotype
|
The deduplicated genotypes |
Int[Array, ' n_unique']
|
The indices of the unique genotypes |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/genotype.py
fix_dtypes
#
Fix the dtypes of the genotypes to their native type.
For some reason, qdax aggressively converts everything to float
| PARAMETER | DESCRIPTION |
|---|---|
genotypes
|
The genotypes to fix
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Genotype
|
The genotypes with fixed dtypes |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/genotype.py
empty_repertoire
#
empty_repertoire(
batch_size,
max_num_splits,
max_num_disconnections,
n_timesteps,
starting_taps=None,
)
Create an initial genotype repertoire with all zeros for all entries and int_max for all subs.
| PARAMETER | DESCRIPTION |
|---|---|
batch_size
|
The batch size
TYPE:
|
max_num_splits
|
The maximum number of splits per topology
TYPE:
|
max_num_disconnections
|
The maximum number of disconnections as topological measures per topology
TYPE:
|
n_timesteps
|
The number of timesteps in the optimization horizon, used for the nodal injection optimization results
TYPE:
|
starting_taps
|
The starting taps for the psts. If None, no nodal inj optimization will be enabled and nodal_injections_optimized will be set to None. If provided, nodal_injections_optimized will be initialized with these starting taps.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Genotype
|
The initial genotype |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/genotype.py
toop_engine_topology_optimizer.dc.genetic_functions.initialization
#
Initialization of the genetic algorithm for branch and injection choice optimization.
JaxOptimizerData
#
Bases: Module
The part of the optimizer data that lives on GPU.
If distributed is enabled, every item will have a leading device dimension.
update_max_mw_flows_according_to_double_limits
#
update_max_mw_flows_according_to_double_limits(
dynamic_informations,
solver_configs,
lower_limit,
upper_limit,
)
Update all dynamic informations max mw loads.
Runs an initial n-1 analysis to determine limits in mw.
| PARAMETER | DESCRIPTION |
|---|---|
dynamic_informations
|
List of static informations to calculate with max_mw_flow limits set at 1.0
TYPE:
|
solver_configs
|
List of solver configurations to use for the loadflow
TYPE:
|
lower_limit
|
The relative lower limit to set, for branches whose n-1 flows are below the lower limit
TYPE:
|
upper_limit
|
The relative upper_limit determining at what relative load a branch is considered overloaded. Branches in the band between lower and upper limit are considered overloaded if more load is added.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple[DynamicInformation, ...]
|
The updated dynamic informations with new limits set. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
verify_static_information
#
Verify the static information.
This function will be called after loading the static information. It should be used to verify that the static information is correct and can be used for the optimization run.
| PARAMETER | DESCRIPTION |
|---|---|
static_informations
|
The static information to verify
TYPE:
|
max_num_disconnections
|
The maximum number of disconnections that can be made
TYPE:
|
enable_nodal_inj_optim
|
Whether to enable the nodal injection optimization. If so, all static informations are verified to contain nodal injection information with at least one controllable PST.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
AssertionError
|
If the static information is not correct |
| RETURNS | DESCRIPTION |
|---|---|
None
|
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 | |
update_static_information
#
update_static_information(
static_informations,
batch_size,
enable_nodal_inj_optim,
enable_bb_outage,
bb_outage_as_nminus1,
clip_bb_outage_penalty,
bb_outage_more_islands_penalty,
)
Perform any necessary preprocessing on the static information.
This mainly applies updated optimization parameters such as batch size, busbar settings, etc.
| PARAMETER | DESCRIPTION |
|---|---|
static_informations
|
The list of static informations to preprocess
TYPE:
|
batch_size
|
The batch size to use, will replace the batch size in the solver config
TYPE:
|
enable_nodal_inj_optim
|
Whether to enable the nodal injection optimization, if False, nodal_inj_optim related information will be removed from the dynamic information to save GPU memory.
TYPE:
|
enable_bb_outage
|
Whether the optimizer should include busbar outage effects. This is only enabled when the loaded static information contains busbar outage data.
TYPE:
|
bb_outage_as_nminus1
|
Whether busbar outages are handled as additional N-1 cases. This value is always written into the solver config.
TYPE:
|
clip_bb_outage_penalty
|
Whether busbar outage penalties are clipped at 0. This value is always written into the solver config.
TYPE:
|
bb_outage_more_islands_penalty
|
The islanding penalty stored in the busbar outage baseline. This value is always written into the loaded baseline analysis when present.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple[StaticInformation, ...]
|
The updated static informations |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
update_single_pair_branch_limit_information
#
update_single_pair_branch_limit_information(
solver_config,
dynamic_information,
batch_size,
enable_nodal_inj_optim,
)
Normalize branch-limit and nodal-injection data for one timestep.
This helper applies the optimizer batch size to the solver config and fills branch-limit fields that the optimizer assumes are always present at runtime. It also drops nodal injection payloads when nodal injection optimization is disabled to avoid carrying unused GPU data.
| PARAMETER | DESCRIPTION |
|---|---|
solver_config
|
The solver configuration for one static information object.
TYPE:
|
dynamic_information
|
The runtime data paired with
TYPE:
|
batch_size
|
The batch size to write into both batch dimensions of the solver config.
TYPE:
|
enable_nodal_inj_optim
|
Whether nodal injection optimization is enabled.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple[SolverConfig, DynamicInformation]
|
The updated solver config and dynamic information pair. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
update_single_pair_bb_outage_information
#
update_single_pair_bb_outage_information(
solver_config,
dynamic_information,
enable_bb_outage,
bb_outage_as_nminus1,
clip_bb_outage_penalty,
bb_outage_more_islands_penalty,
)
Apply runtime busbar-outage configuration for one timestep.
Busbar outage data is persisted during preprocessing so it can be reused at optimization time. This helper decides whether that payload is actually needed for the current run. When busbar outages are disabled, the associated runtime data is stripped from the dynamic information to reduce memory use. When enabled, the solver config is updated and the baseline penalty analysis is refreshed to match the requested islanding penalty.
| PARAMETER | DESCRIPTION |
|---|---|
solver_config
|
The solver configuration for one static information object.
TYPE:
|
dynamic_information
|
The runtime data paired with
TYPE:
|
enable_bb_outage
|
Whether the optimizer should use busbar outage data when available.
TYPE:
|
bb_outage_as_nminus1
|
Whether busbar outages should be treated as additional N-1 contingencies.
TYPE:
|
clip_bb_outage_penalty
|
Whether the busbar outage penalty should be clipped at zero.
TYPE:
|
bb_outage_more_islands_penalty
|
Penalty applied when a busbar outage creates more islands than the unsplit baseline.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
tuple[SolverConfig, DynamicInformation]
|
The updated solver config and dynamic information pair. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 | |
initialize_genetic_algorithm
#
initialize_genetic_algorithm(
batch_size,
max_num_splits,
max_num_disconnections,
static_informations,
target_metrics,
mutation_config,
action_set,
proportion_crossover,
crossover_mutation_ratio,
random_seed,
observed_metrics,
me_descriptors,
distributed,
devices=None,
cell_depth=1,
n_worst_contingencies=10,
)
Initialize the mapelites algorithm.
| PARAMETER | DESCRIPTION |
|---|---|
batch_size
|
The batch size to use
TYPE:
|
max_num_splits
|
The maximum number of substations that can be split
TYPE:
|
max_num_disconnections
|
The maximum number of disconnections that can be made
TYPE:
|
static_informations
|
The static information to use for the optimization run
TYPE:
|
target_metrics
|
The target metrics to use for the optimization run
TYPE:
|
mutation_config
|
The mutation configuration to use for the optimization run
TYPE:
|
action_set
|
The action set to use for mutations
TYPE:
|
proportion_crossover
|
The proportion of crossover to mutation
TYPE:
|
crossover_mutation_ratio
|
The ratio of crossover to mutation
TYPE:
|
random_seed
|
The random seed to use for reproducibility
TYPE:
|
observed_metrics
|
The observed metrics, i.e. which metrics are to be computed for logging purposes.
TYPE:
|
me_descriptors
|
The descriptors to use for map elites
TYPE:
|
distributed
|
Whether to run the optimization on multiple devices
TYPE:
|
devices
|
The devices to run the optimization on, if distributed
TYPE:
|
cell_depth
|
The cell depth to use if applicable
TYPE:
|
n_worst_contingencies
|
The number of worst contingencies to consider in the scoring function for calculating top_k_overloads_n_1.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DiscreteMapElites
|
The genetic algorithm object including scoring, mutate and crossover functions |
JaxOptimizerData
|
The initialized jax dataclass |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 | |
get_repertoire_metrics
#
Get the metrics of the best individual in the Mapelites repertoire.
| PARAMETER | DESCRIPTION |
|---|---|
repertoire
|
The repertoire |
observed_metrics
|
The metrics to observe (max_flow_n_0, median_flow_n_0 ...)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
float
|
The fitness |
dict[MetricType, float]
|
The metrics as defined in METRICS |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
algo_setup
#
Set up the genetic algorithm run.
| PARAMETER | DESCRIPTION |
|---|---|
ga_args
|
The genetic algorithm parameters
TYPE:
|
lf_args
|
The loadflow solver parameters
TYPE:
|
double_limits
|
The lower and upper limit for the relative max mw flow if double limits are used
TYPE:
|
static_information_files
|
A list of files with static information to load
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DiscreteMapElites
|
The initialized genetic algorithm object, can be used to update the optimization run |
JaxOptimizerData
|
The jax dataclass of all GPU data including dynamic information and the GA data |
tuple[SolverConfig, ...]
|
The solver configurations for every timestep (the dynamic information is part of the jax dataclass) |
float
|
The initial fitness, for logging purposes |
dict
|
The initial metrics, for logging purposes |
list[StaticInformationDescription]
|
Some statistics on the static information dataclasses that were loaded |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/initialization.py
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 | |
toop_engine_topology_optimizer.dc.genetic_functions.scoring_functions
#
Create scoring functions for the genetic algorithm.
METRICS
module-attribute
#
METRICS = {
"max_flow_n_0": maximum,
"median_flow_n_0": maximum,
"overload_energy_n_0": add,
"overload_energy_limited_n_0": add,
"underload_energy_n_0": add,
"transport_n_0": add,
"exponential_overload_energy_n_0": add,
"exponential_overload_energy_limited_n_0": add,
"critical_branch_count_n_0": maximum,
"critical_branch_count_limited_n_0": maximum,
"max_flow_n_1": maximum,
"median_flow_n_1": maximum,
"overload_energy_n_1": add,
"overload_energy_limited_n_1": add,
"underload_energy_n_1": add,
"transport_n_1": add,
"exponential_overload_energy_n_1": add,
"exponential_overload_energy_limited_n_1": add,
"critical_branch_count_n_1": maximum,
"critical_branch_count_limited_n_1": maximum,
"n0_n1_delta": add,
"cross_coupler_flow": add,
"switching_distance": maximum,
"split_subs": maximum,
"n_2_penalty": add,
"pst_switching_distance": maximum,
"pst_switching_distance_squared": maximum,
"pst_activated": maximum,
}
compute_overloads
#
compute_overloads(
topologies,
dynamic_information,
solver_config,
observed_metrics,
n_worst_contingencies=10,
)
Compute the overloads for a single timestep by invoking the solver and aggregating the results.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to score, where the first max_num_splits entries are the substations, the second max_num_splits entries are the branch topos and the last max_num_splits entries are the injection topos
TYPE:
|
dynamic_information
|
The dynamic information of the grid
TYPE:
|
solver_config
|
The static solver configuration
TYPE:
|
observed_metrics
|
The metrics to observe
TYPE:
|
n_worst_contingencies
|
The number of worst contingencies to return, by default 10
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict[str, Float[Array, ' batch_size']]
|
A dictionary with the overload energy, transport, max flow and other metrics, from aggregate_to_metric_batched |
NodalInjOptimResults
|
The results of the nodal injection optimization |
Bool[Array, ' batch_size']
|
Whether the topologies were successfully solved |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py
scoring_function
#
scoring_function(
topologies,
random_key,
dynamic_informations,
solver_configs,
target_metrics,
observed_metrics,
descriptor_metrics,
n_worst_contingencies=10,
)
Create scoring function for the genetic algorithm.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to score
TYPE:
|
random_key
|
The random key to use for the scoring (currently not used)
TYPE:
|
dynamic_informations
|
The dynamic information of the grid for every timestep
TYPE:
|
solver_configs
|
The solver configuration for every timestep
TYPE:
|
target_metrics
|
The list of metrics to optimize for with their weights
TYPE:
|
observed_metrics
|
The observed metrics
TYPE:
|
descriptor_metrics
|
The metrics to use as descriptors
TYPE:
|
n_worst_contingencies
|
The number of worst contingencies to consider for calculating top_k_overloads_n_1
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Float[Array, ' batch_size']
|
The fitness of the topologies, calculated as the weighted sum of the target metrics |
Int[Array, ' batch_size n_dims']
|
The descriptors of the topologies |
dict
|
The metrics of the topologies, including the target metrics and any other observed metrics |
ExtraScores
|
Emitter Information |
PRNGKeyArray
|
The random key that was passed in, unused |
Genotype
|
The genotypes that were passed in, but updated to account for in-the-loop optimizations such as the nodal injection optimization. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | |
translate_topology
#
Translate the topology into the format used by the solver.
| PARAMETER | DESCRIPTION |
|---|---|
topology
|
The topology in genotype form
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
ActionIndexComputations
|
The topology computations |
Int[Array, ' batch_size max_num_disconnections']
|
The branch disconnections to apply |
NodalInjStartOptions | None
|
The nodal injection optimization start options containing pst taps, or None if no PST optimization |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py
filter_repo
#
Reduce the repertoire to only valid and deduplicated topologies.
This will not return any topologies that are worse than the initial fitness and deduplicate the topologies. The function is currently not jax jit compatible.
| PARAMETER | DESCRIPTION |
|---|---|
repertoire
|
The repertoire to reduce |
initial_fitness
|
The initial fitness of the grid. This is used to filter out topologies that are worse than this fitness.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DiscreteMapElitesRepertoire
|
The reduced repertoire with only valid and deduplicated topologies. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py
convert_to_topologies
#
Take a repertoire and convert it to a list of kafka-sendable topologies.
| PARAMETER | DESCRIPTION |
|---|---|
repertoire
|
The repertoire to convert. You might want to filter it using filter_repo first. |
contingency_ids
|
The contingency IDs for each topology
TYPE:
|
grid_model_low_tap
|
The lowest tap value in the grid model, used to convert the relative tap values in the genotype to absolute tap values that can be sent to the kafka topics. This will only be read if nodal_injection results are present in the genotype.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[Topology]
|
The list of topologies in the format used by the kafka topics. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py
summarize_repo
#
Summarize the repertoire into a list of topologies.
| PARAMETER | DESCRIPTION |
|---|---|
repertoire
|
The repertoire to summarize |
initial_fitness
|
The initial fitness of the grid
TYPE:
|
contingency_ids
|
The contingency IDs for each topology. Here we assume that this list is common for all the topologies in the repertoire. TODO: Fix me to have per topology contingency ids if needed
TYPE:
|
grid_model_low_tap
|
The lowest tap value in the grid model, from nodal_injection_information.grid_model_low_tap.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[Topology]
|
The summarized topologies |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py
summarize
#
summarize(
repertoire,
emitter_state,
initial_fitness,
initial_metrics,
contingency_ids,
grid_model_low_tap=None,
)
Summarize the repertoire and emitter state into a serializable dictionary.
| PARAMETER | DESCRIPTION |
|---|---|
repertoire
|
The repertoire to summarize |
emitter_state
|
The emitter state to summarize
TYPE:
|
initial_fitness
|
The initial fitness of the grid
TYPE:
|
initial_metrics
|
The initial metrics of the grid
TYPE:
|
contingency_ids
|
A list of contingency ids. Here we assume that the list of contingency ids is common for all the topologies
TYPE:
|
grid_model_low_tap
|
The lowest tap value in the grid model, from nodal_injection_information.grid_model_low_tap.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict
|
The summarized dictionary, json serializable |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py
toop_engine_topology_optimizer.dc.genetic_functions.crossover
#
Contains the genetic operations for the topologies.
This module contains the functions to perform the genetic operations of mutation and crossover on the topologies of the grid. The topologies are represented as Genotype dataclasses, which contain the substation ids, the branch topology, the injection topology and the disconnections.
sample_unique_from_array
#
Sample n unique elements from an array (returning indices), counting int_max as always unique.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the sampling
TYPE:
|
sample_pool
|
The array to sample from. Only unique elements are sampled, however int_max entries are not checked for uniqueness
TYPE:
|
sample_probs
|
The probabilities to sample each element
TYPE:
|
n_samples
|
The number of samples to take, should be less than the number of non-int_max entries in array.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' n_samples']
|
The sampled indices into sample_pool |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/crossover.py
crossover_unbatched
#
Crossover two topologies while making sure that no substation is present twice.
This version is unbatched, i.e. it only works on a single topology. Use crossover for batched inputs.
| PARAMETER | DESCRIPTION |
|---|---|
topologies_a
|
The first topology
TYPE:
|
topologies_b
|
The second topology
TYPE:
|
random_key
|
The random key to use for the crossover
TYPE:
|
action_set
|
The branch action set containing available actions on a per-substation basis. This is needed to resolve the sub_ids for the branch actions
TYPE:
|
prob_take_a
|
The probability to take the value from topology_a, otherwise the value from topology_b is taken
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Genotype
|
The new topology |
PRNGKeyArray
|
The new random key |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/crossover.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
crossover
#
Crossover two topologies while making sure that no substation is present twice.
| PARAMETER | DESCRIPTION |
|---|---|
topologies_a
|
The first topology
TYPE:
|
topologies_b
|
The second topology
TYPE:
|
random_key
|
The random key to use for the crossover
TYPE:
|
action_set
|
The branch action set containing available actions on a per-substation basis.
TYPE:
|
prob_take_a
|
The probability to take the value from topology_a, otherwise the value from topology_b is taken
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Genotype
|
The new topology |
PRNGKeyArray
|
The new random key |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/crossover.py
Mutation#
toop_engine_topology_optimizer.dc.genetic_functions.mutation.config
#
Mutation configuration classes for the genetic algorithm.
SubstationMutationConfig
#
Bases: Module
Configuration for the substation mutation operation.
The sum of all probabilities should be <= 1.0, the remaining probability will be used for no mutation. If all substations are already split, the add_split_prob will be ignored and the probabilities will be renormalized to sum to 1.
n_subs_mutated_lambda
class-attribute
instance-attribute
#
add_split_prob
class-attribute
instance-attribute
#
The probability to split an additional substation. In case all substations are already split, this probability is ignored.
change_split_prob
class-attribute
instance-attribute
#
The probability to change an already split substation to a different split in the same or another substation.
remove_split_prob
class-attribute
instance-attribute
#
The probability to reset a substation to the unsplit state.
n_rel_subs
class-attribute
instance-attribute
#
The number of substations in the topology, used to determine the valid range of substation ids.
DisconnectionMutationConfig
#
Bases: Module
Configuration for the disconnection mutation operation.
Holds the random parameters used during the mutation of the disconnections, which are applied after the substation mutation.
add_disconnection_prob
class-attribute
instance-attribute
#
The probability to disconnect an additional branch.
change_disconnection_prob
class-attribute
instance-attribute
#
The probability to change a disconnected branch to another one.
remove_disconnection_prob
class-attribute
instance-attribute
#
The probability to remove a reconnect a disconnected branch.
n_disconnectable_branches
class-attribute
instance-attribute
#
The number of disconnectable branches in the topology, used to determine the valid range of branch ids.
NodalInjectionMutationConfig
#
Bases: Module
Configuration for the nodal injection mutation operation.
Holds the random parameters used during the mutation of the nodal injection optimization results, which are applied after the substation mutation.
pst_mutation_sigma
class-attribute
instance-attribute
#
The sigma to use for the normal distribution to sample the PST tap mutation from.
pst_mutation_probability
class-attribute
instance-attribute
#
The probability for an individual PST to be selected for mutation.
pst_reset_probability
class-attribute
instance-attribute
#
The probability for an individual PST to be reverted to its initial set point. A value of 0.0 means no reset. A value of 1.0 means all PSTs will be reset.
pst_n_taps
instance-attribute
#
The number of taps for each PST, used to determine the valid range of tap positions for mutation.
pst_start_tap_idx
instance-attribute
#
The starting tap position as an index into the tap range of each controllable PST
MutationConfig
#
Bases: Module
Configuration for the mutation operation.
mutation_repetition
class-attribute
instance-attribute
#
More chance to get unique mutations by mutating mutation_repetition copies of the repertoire. The repertoire is repeated x times before mutation and deduplicated after mutation.
random_topo_prob
class-attribute
instance-attribute
#
The probability to apply a completely random topology, instead of mutating. This is added to increase the exploration capabilities of the mutation operator, but should be used with care as it can easily lead to a decrease in performance if the random topologies are of low quality.
This does not include PSTs for now.
substation_mutation_config
class-attribute
instance-attribute
#
The configuration for the substation mutation operation.
disconnection_mutation_config
class-attribute
instance-attribute
#
The configuration for the disconnection mutation operation.
nodal_injection_mutation_config
instance-attribute
#
The configuration for the nodal injection mutation operation.
toop_engine_topology_optimizer.dc.genetic_functions.mutation.mutate
#
Mutation functions for the genetic algorithm.
mutate_topology
#
Mutate the topology by changing the substation splits and disconnections according to the mutation configuration.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
sub_ids
|
The substation ids before the mutation
TYPE:
|
disconnections_topo
|
The disconnections before the mutation
TYPE:
|
action
|
The actions before the mutation
TYPE:
|
mutate_config
|
The mutation configuration
TYPE:
|
action_set
|
The set of possible actions
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
(Int[Array, ' max_num_splits'],)
|
The splits substation ids after the mutation |
(Int[Array, ' max_num_splits'],)
|
The action ids after the mutation |
(Int[Array, ' max_num_disconnections'],)
|
The disconnections after the mutation |
PRNGKeyArray
|
The mutated substation ids, actions, disconnections, and the updated random key |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate.py
create_random_topology
#
create_random_topology(
random_key,
sub_ids,
disconnections,
action_set,
n_rel_subs,
n_disconnectable_branches,
)
Create a random topology by sampling random substation splits, branch topologies and disconnections.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
sub_ids
|
The substation ids before the mutation, used to determine the number of splits to sample
TYPE:
|
disconnections
|
The disconnections before the mutation, used to determine the number of disconnections to sample
TYPE:
|
action_set
|
The set of possible actions, used to sample valid actions for the new topology
TYPE:
|
n_rel_subs
|
The number of relevant substations in the grid, used to determine the valid range of substation ids for mutation.
TYPE:
|
n_disconnectable_branches
|
The number of disconnectable branches in the grid, used to determine the valid range of branch ids for mutation.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
(Int[Array, ' max_num_splits'],)
|
The splits substation ids after the random mutation |
(Int[Array, ' max_num_splits'],)
|
The action ids after the random mutation |
(Int[Array, ' max_num_disconnections'],)
|
The disconnections after the random mutation |
PRNGKeyArray
|
The mutated substation ids, actions, disconnections, and the updated random key |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate.py
mutate
#
Mutate the topologies by splitting substations, disconnecting branches and mutating nodal injections (PSTs).
Makes sure that at all times, a substation is split at most once and that all branch actions are in range of the available actions for the substation. If a substation is not split, this is indicated by the value int_max in the substation, branch.
We mutate mutation_repetition copies of the initial repertoire to increase the chance of getting unique mutations.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to mutate
TYPE:
|
random_key
|
The random key to use for the mutation
TYPE:
|
mutation_config
|
The mutation configuration containing the probabilities for the different mutation operations and their parameters
TYPE:
|
action_set
|
The action set containing available actions on a per-substation basis.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Genotype
|
The mutated topologies |
PRNGKeyArray
|
The new random key |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate.py
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | |
repeat_topologies
#
Repeat the topologies mutation_repetition times to increase the chance of getting unique mutations.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies to repeat
TYPE:
|
batch_size
|
The batch size of the original topologies, used to determine the total size after repetition
TYPE:
|
mutation_repetition
|
The number of times to repeat the topologies
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Genotype
|
The repeated topologies |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate.py
toop_engine_topology_optimizer.dc.genetic_functions.mutation.mutate_substations
#
Mutation functions for substations in the genetic algorithm.
change_split_substation
#
Change a split to a different one.
Either in the same substation or in a different substation. This assumes, that there is a split already.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
sub_ids
|
The substation ids before mutation
TYPE:
|
n_rel_subs
|
Number of relevant substations that may be selected.
TYPE:
|
int_max_value
|
The value that indicates an unsplit substation, used to determine which substations are currently split and to sample a new substation id from the valid range
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' max_num_splits']
|
The mutated substation ids, where one split substation is changed to a different one. If there are no split substations, the input sub_ids are returned unchanged |
Int[Array, ' ']
|
The index of the substation that was mutated. If no substation was mutated, this is set to int_max |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_substations.py
unsplit_substation
#
Reset a split substation to the unsplit state, with a certain probability.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the reset
TYPE:
|
sub_ids
|
The substation ids before the reset
TYPE:
|
int_max_value
|
The value that indicates an unsplit substation, used to determine which substations are currently split and to sample a new substation id from the valid range
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' max_num_splits']
|
The substation ids after the reset. If a reset occurred, the substation id at split_idx will be set to int_max |
Int[Array, ' max_num_splits']
|
The topology action after the reset. If a reset occurred, the topology at split_idx will be set to int_max |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_substations.py
split_additional_sub
#
Mutate the substation ids of a single topology.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
sub_ids
|
The substation ids before mutation
TYPE:
|
n_rel_subs
|
Number of relevant substations that may be selected.
TYPE:
|
int_max_value
|
The value to use for the mutation, which should be the maximum integer value used to indicate an empty slot in the genotype.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' max_num_splits']
|
The mutated substation ids |
Int[Array, ' ']
|
The index of the substation that was mutated. If no substation was mutated, this is set to a random substation that was already split, so branch and injection mutations can still happen despite no new split. If no substation was split yet and no split happened, this is set to int_max |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_substations.py
mutate_sub_splits
#
Mutate a single substation, changing the sub_ids, branch and inj topos.
The sub-ids are implicit to the branch topo action index, however we pass them explicitely to aid substation mutation. Impossible mutations (e.g. adding a split when there is no room to add one, or removing a split when there are none) are handled by setting the probabilities for these mutations to zero, and normalising the remaining probabilities to sum to 1.
| PARAMETER | DESCRIPTION |
|---|---|
sub_ids
|
The substation ids before mutation
TYPE:
|
action
|
The branch topology before mutation
TYPE:
|
random_key
|
The random key to use for the mutation
TYPE:
|
sub_mutate_config
|
The configuration for the substation mutation, containing the probabilities for the different mutation types and the number of relevant substations in the grid, which is needed to determine the valid range of substation ids for mutation.
TYPE:
|
action_set
|
The actions for every substation. If not provided, will sample from all possible actions per substation
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
sub_ids
|
The substation ids after mutation
TYPE:
|
action
|
The branch topology after mutation
TYPE:
|
random_key
|
The random key used for the mutation
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_substations.py
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
toop_engine_topology_optimizer.dc.genetic_functions.mutation.mutate_disconnections
#
Mutation functions for the disconnections in the genetic algorithm.
change_disconnected_branch
#
Change a disconnected branch in the topology to a different one.
This assumes, that one branch is already disconnected, otherwise there would be nothing to change.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
disconnections
|
The disconnections before mutation of one individual
TYPE:
|
n_disconnectable_branches
|
The number of disconnectable branches in the action set. It is not necessary to know the contents of the action set here because we only sample an index into the action set.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' ']
|
The index that is changed |
Int[Array, ' ']
|
The new disconnection that is added. If no disconnection was changed, this is set to int_max |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_disconnections.py
reconnect_disconnected_branch
#
Reconnect a disconnected branch in the topology.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
disconnections
|
The disconnections before mutation of one individual
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' ']
|
The index that is changed |
Int[Array, ' ']
|
The new disconnection that is added. This is always int_max to indicate that the slot is now empty |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_disconnections.py
disconnect_additional_branch
#
Add a new disconnection to the topology.
This assumes, that there is still room to add a disconnection, otherwise there would be no valid branch to add.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
disconnections
|
The disconnections before mutation of one individual
TYPE:
|
n_disconnectable_branches
|
The number of disconnectable branches in the action set. It is not necessary to know the contents of the action set here because we only sample an index into the action set.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' ']
|
The index that is changed |
Int[Array, ' ']
|
The new disconnection that is added. If no disconnection was added, this is set to int_max |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_disconnections.py
mutate_disconnections
#
Mutate the disconnections of a single topology.
Impossible mutations (e.g. adding a disconnection when there is no room to add one, or removing a disconnection when there are none) are handled by setting the probabilities for these mutations to zero, and adding them to the remain probability.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
sub_ids
|
The substation ids of the topology, which are needed to determine whether certain disconnection mutations are allowed
TYPE:
|
disconnections
|
The disconnections before mutation of one individual
TYPE:
|
disconnection_mutation_config
|
The configuration for the disconnection mutation, containing the probabilities for the different mutation types and the number of disconnectable branches in the grid, which is needed to determine the valid range of branch ids for mutation. |
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' max_num_disconnections']
|
The mutated disconnections |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_disconnections.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | |
toop_engine_topology_optimizer.dc.genetic_functions.mutation.mutate_nodal_inj
#
Mutation functions for the nodal injections in the genetic algorithm.
mutate_psts
#
mutate_psts(
random_key,
pst_taps,
pst_n_taps,
pst_starting_taps,
pst_mutation_sigma,
pst_mutation_probability=0.2,
pst_reset_probability=0.1,
)
Mutate the PST taps of a single topology.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
pst_taps
|
The PST tap positions before mutation
TYPE:
|
pst_n_taps
|
The number of taps for each PST. If a PST has N taps in this array, then it is assumed that all taps from 0 to N-1 are valid tap positions. Output taps will be clipped to this range.
TYPE:
|
pst_starting_taps
|
The initial PST taps of each controllable PST.
TYPE:
|
pst_mutation_sigma
|
The sigma to use for the normal distribution to sample the mutation from. The mutation will be sampled as an integer from a normal distribution with mean 0 and sigma pst_mutation_sigma.
TYPE:
|
pst_mutation_probability
|
The probability for an individual PST to be selected for mutation. 1.0 indicates that all PSTs will be mutated, 0.0 indicates that no PSTs will be mutated. Default 0.2
TYPE:
|
pst_reset_probability
|
The probability for an individual PST to be reverted to its initial set point. A value of 0.0 means no reset. A value of 1.0 means all PSTs will be reset. Default 0.1
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' n_controllable_pst']
|
The mutated PST tap positions, clipped to the valid range of taps for each PST. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_nodal_inj.py
mutate_nodal_injections
#
Mutate the nodal injection optimization results, currently only the PST taps.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the mutation
TYPE:
|
nodal_inj_info
|
The nodal injection optimization results before mutation. If None, no mutation is performed and None is returned.
TYPE:
|
nodal_mutation_config
|
The configuration for the nodal injection mutation. If None, no mutation is performed
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Optional[NodalInjOptimResults]
|
The mutated nodal injection optimization results. If nodal_inj_info was None, returns None. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate_nodal_inj.py
toop_engine_topology_optimizer.dc.genetic_functions.mutation.utils
#
Mutation utility functions for the genetic algorithm.
sample_new_id
#
Sample a relevant id that is not already used in the active split slots.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
Random key used for sampling.
TYPE:
|
already_used_ids
|
Current ids that should not be sampled again.
TYPE:
|
n_available_ids
|
Number of available ids that may be selected.
TYPE:
|
ignored_idx
|
Index in
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' ']
|
A valid new substation id, or |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/utils.py
get_random_true_idx
#
Return random index of a True entry, or int_max_value if none are True.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
The random key to use for the sampling
TYPE:
|
boolean_array
|
The boolean array to sample from. Should have shape (n_possibilities,). Is true where the index is a valid choice to sample, and false where it is not. If all entries are false, int_max_value is returned.
TYPE:
|
int_max_value
|
The value to return if all entries in boolean_array are False. This should be the maximum integer value used to indicate an empty slot in the genotype.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' ']
|
A random index of a True entry in boolean_array, or int_max_value if all entries are False. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/utils.py
do_nothing
#
Return a no-op mutation index and value.
| PARAMETER | DESCRIPTION |
|---|---|
int_max_value
|
The value to use for the no-op mutation, which should be the maximum integer value used to indicate an empty slot in the genotype.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Int[Array, ' ']
|
The index that is changed. This is set to int_max_value to indicate that no index is changed. |
Int[Array, ' ']
|
The new value that is added. This is set to int_max_value to indicate that no value is added. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/utils.py
Repertoire#
toop_engine_topology_optimizer.dc.repertoire.discrete_map_elites
#
Core components of the MAP-Elites algorithm.
Adapted from QDax (https://github.com/adaptive-intelligent-robotics/QDax)
DiscreteMapElites
#
DiscreteMapElites(
scoring_function,
emitter,
metrics_function,
n_cells_per_dim,
cell_depth=1,
distributed=False,
)
Discrete MAP-Elites algorithm.
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_map_elites.py
init
#
Initialize a Map-Elites repertoire with an initial population of genotypes.
Requires the definition of centroids that can be computed with any method such as CVT or Euclidean mapping.
Before the repertoire is initialised, individuals are gathered from all the devices.
Args: genotypes: initial genotypes, pytree in which leaves have shape (batch_size, num_features) random_key: a random key used for stochastic operations. n_cells_per_dim: number of cells per dimension in the repertoire
| RETURNS | DESCRIPTION |
|---|---|
An initialized MAP-Elite repertoire with the initial state of the emitter,
|
and a random key. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_map_elites.py
update
#
Perform one iteration of the MAP-Elites algorithm.
- A batch of genotypes is sampled in the repertoire and the genotypes are copied.
- The copies are mutated and crossed-over
- The obtained offsprings are scored and then added to the repertoire.
Before the repertoire is updated, individuals are gathered from all the devices.
Args: repertoire: the MAP-Elites repertoire emitter_state: state of the emitter random_key: a jax PRNG random key
| RETURNS | DESCRIPTION |
|---|---|
the updated MAP-Elites repertoire
|
the updated (if needed) emitter state metrics about the updated repertoire a new jax PRNG key |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_map_elites.py
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
toop_engine_topology_optimizer.dc.repertoire.discrete_me_repertoire
#
Contains the DiscreteMapElitesRepertoire class and utility functions.
This file contains util functions and a class to define a repertoire, used to store individuals in the MAP-Elites algorithm as well as several variants. Adapted from QDax (https://github.com/adaptive-intelligent-robotics/QDax)
DiscreteMapElitesRepertoire
#
Bases: Module
A class to store the MAP-Elites repertoire.
genotypes
instance-attribute
#
The genotypes in the repertoire.
The PyTree can be a simple Jax array or a more complex nested structure such as to represent parameters of neural network in Flax.
descriptors
instance-attribute
#
The descriptors of solutions in each cell of the repertoire.
extra_scores
instance-attribute
#
The extra scores of solutions in each cell of the repertoire. Usually the metrics
n_cells_per_dim
class-attribute
instance-attribute
#
The number of cells per dimension.
cell_depth
class-attribute
instance-attribute
#
Each cell contains cell_depth unique individuals
sample
#
Sample elements in the repertoire.
| PARAMETER | DESCRIPTION |
|---|---|
random_key
|
the random key to be used for sampling
TYPE:
|
num_samples
|
the number of samples to be drawn from the repertoire
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
samples
|
the sampled genotypes
TYPE:
|
random_key
|
the updated random key
TYPE:
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
__getitem__
#
Get a slice of the repertoire.
| PARAMETER | DESCRIPTION |
|---|---|
index
|
the index of the elements to be selected
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
a new repertoire with the selected elements
|
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
get_cells_indices
#
Compute the index for many descriptors at once.
Args: descriptors: an array that contains the descriptors of the solutions. Its shape is (batch_size, num_descriptors) n_cells_per_dim: the number of cells per dimension
| RETURNS | DESCRIPTION |
|---|---|
The index of the cell in which each descriptor belongs.
|
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
get_cell_index
#
Compute the index of the cell in which each descriptor belongs.
The index is effectively like the reshape operation, spreading multiple dimensions to a flat single dimension.
Args: descriptor: an array that contains the descriptors. There is one descriptor per dimension n_cells_per_dim: the number of cells per dimension
| RETURNS | DESCRIPTION |
|---|---|
The index of the cell in which each descriptor belongs.
|
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
add_to_repertoire
#
add_to_repertoire(
repertoire,
batch_of_genotypes,
batch_of_descriptors,
batch_of_fitnesses,
batch_of_extra_scores=None,
)
Add a batch of elements to the repertoire.
Args: repertoire: the MAP-Elites repertoire to which the elements will be added. batch_of_genotypes: a batch of genotypes to be added to the repertoire. Similarly to the repertoire.genotypes argument, this is a PyTree in which the leaves have a shape (batch_size, num_features) batch_of_descriptors: an array that contains the descriptors of the aforementioned genotypes. Its shape is (batch_size, num_descriptors). This will determine the cell in which the genotype will be stored, all descriptors are clipped to be within the bounds of n_cells_per_dim. batch_of_fitnesses: an array that contains the fitnesses of the aforementioned genotypes. Its shape is (batch_size,) batch_of_extra_scores: tree that contains the extra_scores of aforementioned genotypes.
| RETURNS | DESCRIPTION |
|---|---|
The updated MAP-Elites repertoire.
|
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
add_to_repertoire_without_cell_depth
#
add_to_repertoire_without_cell_depth(
repertoire,
batch_of_genotypes,
batch_of_descriptors,
batch_of_fitnesses,
batch_of_extra_scores=None,
)
Add a batch of elements to the repertoire.
| PARAMETER | DESCRIPTION |
|---|---|
repertoire
|
the MAP-Elites repertoire to which the elements will be added. |
batch_of_genotypes
|
a batch of genotypes to be added to the repertoire.
TYPE:
|
batch_of_descriptors
|
an array that contains the descriptors of the genotypes.
TYPE:
|
batch_of_fitnesses
|
an array that contains the fitnesses of the genotypes.
TYPE:
|
batch_of_extra_scores
|
tree that contains the extra_scores of genotypes.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DiscreteMapElitesRepertoire
|
The updated MAP-Elites repertoire. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 | |
add_to_repertoire_with_cell_depth
#
add_to_repertoire_with_cell_depth(
repertoire,
batch_of_genotypes,
batch_of_descriptors,
batch_of_fitnesses,
batch_of_extra_scores=None,
)
Add a batch of elements to a repertoire with depth.
Assumes the repertoire puts elements on a same depth level next to another (layer1 layer1 layer2 layer2 ...) Manipulates abstract indices instead of moving genotypes directly.
| PARAMETER | DESCRIPTION |
|---|---|
repertoire
|
the MAP-Elites repertoire to which the elements will be added. |
batch_of_genotypes
|
a batch of genotypes to be added to the repertoire.
TYPE:
|
batch_of_descriptors
|
an array that contains the descriptors of the genotypes.
TYPE:
|
batch_of_fitnesses
|
an array that contains the fitnesses of the genotypes.
TYPE:
|
batch_of_extra_scores
|
tree that contains the extra_scores of genotypes.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
DiscreteMapElitesRepertoire
|
The updated MAP-Elites repertoire. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 | |
init_repertoire
#
Initialize a Map-Elites repertoire with an initial population of genotypes.
Requires the definition of centroids that can be computed with any method such as CVT or Euclidean mapping.
Note: this function has been kept outside of the object MapElites, so it can be called easily called from other modules.
Args: genotypes: initial genotypes, pytree in which leaves have shape (batch_size, num_features) fitnesses: fitness of the initial genotypes of shape (batch_size,) descriptors: descriptors of the initial genotypes of shape (batch_size, num_descriptors) extra_scores: the observed load flow metrics n_cells_per_dim: the number of cells per dimension cell_depth: the number of topologies per cell
| RETURNS | DESCRIPTION |
|---|---|
an initialized MAP-Elite repertoire
|
|
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/discrete_me_repertoire.py
toop_engine_topology_optimizer.dc.repertoire.plotting
#
Plotting functions for the Map-Elites algorithm.
plot_repertoire_1d
#
Plot a bar chart of the repertoire's fitnesses.
| PARAMETER | DESCRIPTION |
|---|---|
fitnesses
|
The fitnesses of the repertoire
TYPE:
|
n_cells_per_dim
|
The number of cells per dimension
TYPE:
|
descriptor_metrics
|
The descriptor metrics
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Figure
|
The plot |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/plotting.py
plot_repertoire_2d
#
Plot a heatmap of the repertoire's fitnesses.
| PARAMETER | DESCRIPTION |
|---|---|
fitnesses
|
The fitnesses of the repertoire
TYPE:
|
n_cells_per_dim
|
The number of cells per dimension
TYPE:
|
descriptor_metrics
|
The descriptor metrics
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Axes
|
The plot |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/plotting.py
plot_repertoire
#
Plot the repertoire (1D or 2D) and saves the figure.
| PARAMETER | DESCRIPTION |
|---|---|
fitnesses
|
The fitnesses of the repertoire
TYPE:
|
iteration
|
The current iteration number
TYPE:
|
folder
|
The folder to save the plot. Will create a "plots" folder inside.
TYPE:
|
n_cells_per_dim
|
The number of cells per dimension
TYPE:
|
descriptor_metrics
|
The descriptor metrics
TYPE:
|
save_plot
|
Whether to save the plot
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Axes | Figure
|
The plot. Axes for heatmap, plt.Figure for barchart. |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/repertoire/plotting.py
Worker#
toop_engine_topology_optimizer.dc.worker.optimizer
#
Callable functions for the optimizer worker.
OptimizerData
dataclass
#
OptimizerData(
start_params,
optimization_id,
solver_configs,
algo,
initial_fitness,
initial_metrics,
jax_data,
start_time,
sent_topologies,
)
A wrapper dataclass for all the data stored by the optimizer.
Because this dataclass holds irrelevant information for the GPU optimization, it is split into two dataclasses. The parent (this one) is used to store all the information and the child (JaxOptimizerData) is used to store the information that is needed on the GPU.
jax_data
instance-attribute
#
Everything that needs to live on GPU. This dataclass is updated per-iteration while OptimizerData is only updated per-epoch, hence there are points in the command flow where this variable is out of sync. At the end of an epoch, this dataclass is updated to match the state in the optimization.
sent_topologies
instance-attribute
#
A set of strategy hashes that have already been sent to the results topic, to avoid sending duplicates.
initialize_optimization
#
initialize_optimization(
params,
optimization_id,
static_information_files,
processed_gridfile_fs,
)
Initialize the optimization run.
This function will be called at the start of the optimization run. It should be used to load the static information files and set up the optimization run.
| PARAMETER | DESCRIPTION |
|---|---|
params
|
The parameters for the optimization run
TYPE:
|
optimization_id
|
The id of the optimization run, used to annotate results and heartbeats
TYPE:
|
static_information_files
|
The paths to the static information files to load
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
OptimizerData
|
The data to store for the optimization run |
list[StaticInformationStats]
|
The static information descriptions, will be sent via the heartbeats channel |
Strategy
|
The initial strategy (unsplit) for the grid, including the initial fitness and metrics |
| RAISES | DESCRIPTION |
|---|---|
Exception
|
If an error occurs during the initialization. It will be caught by the worker and sent back to the results topic |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/optimizer.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | |
convert_metrics
#
Convert a metrics dictionary to a Metrics dataclass.
| PARAMETER | DESCRIPTION |
|---|---|
fitness
|
The fitness value
TYPE:
|
metrics_dict
|
The metrics dictionary
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Metrics
|
The metrics dataclass |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/optimizer.py
run_single_iteration
#
Run a single iteration of the optimization.
This involves updating the genetic algorithm and calling the metrics callback
| PARAMETER | DESCRIPTION | ||
|---|---|---|---|
_i
|
The iteration number, will be ignored. Its only purpose is to make the function signature compatible with lax.fori_loop
TYPE:
|
||
jax_data
|
The data stored for the optimization run from the last epoch or from initialize_optimization
TYPE:
|
||
update_fn
|
The update function of the genetic algorithm
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
JaxOptimizerData
|
The updated data for the optimization run |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/optimizer.py
run_single_device_epoch
#
Run one epoch of the optimization on a single device.
Basically this is just a fori loop over the iterations_per_epoch, calling run_single_iteration This can be used to pass to pmap
| PARAMETER | DESCRIPTION | ||
|---|---|---|---|
jax_data
|
The data stored for the optimization run from the last epoch or from initialize_optimization
TYPE:
|
||
iterations_per_epoch
|
The number of iterations to run in this epoch
TYPE:
|
||
update_fn
|
The update function of the genetic algorithm
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
JaxOptimizerData
|
The updated data for the optimization run |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/optimizer.py
run_epoch
#
Run one epoch of the optimization.
This function will be called repeatedly by the worker. It should include multiple iterations, according to the configuration of the optimizer. Furthermore it should call the metrics_callback during the epoch, at least at the beginning. This could happen through a jax callback to not block the main thread.
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The data stored for the optimization run from the last epoch or from initialize_optimization
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
OptimizerData
|
The updated data for the optimization run |
| RAISES | DESCRIPTION |
|---|---|
Exception
|
If an error occurs during the epoch. It will be caught by the worker and sent back to the results topic |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/optimizer.py
extract_topologies
#
Extract unique and not sent topologies from the repertoire.
Will return a list of topologies that have not been sent to the results topic yet. Also it will update the optimizer data sent set in place to include those topologies.
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The data stored for the optimization run, the sent_topologies set will be updated in place
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[Topology]
|
The topologies to send to the results topic, in message topo format |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/optimizer.py
convert_topologies_to_messages
#
Convert a list of topologies in message format to a list of TopologyPushResult.
| PARAMETER | DESCRIPTION |
|---|---|
topologies
|
The topologies in message format
TYPE:
|
epoch
|
The epoch number, used to annotate the results
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
list[TopologyPushResult]
|
The topologies in TopologyPushResult format, ready to be sent to the results topic |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/optimizer.py
toop_engine_topology_optimizer.dc.worker.worker
#
Kafka worker for the genetic algorithm optimization.
Args
#
Bases: BaseModel
Launch arguments for the worker, which can not be changed during the optimization run.
kafka_broker
class-attribute
instance-attribute
#
The Kafka broker to connect to.
optimizer_command_topic
class-attribute
instance-attribute
#
The Kafka topic to listen for commands on.
optimizer_results_topic
class-attribute
instance-attribute
#
The topic to push results to.
optimizer_heartbeat_topic
class-attribute
instance-attribute
#
The topic to push heartbeats to.
heartbeat_interval_ms
class-attribute
instance-attribute
#
The interval in milliseconds to send heartbeats.
max_command_age_hours
class-attribute
instance-attribute
#
The maximum age of a command in hours. If a command is received that is older than this, the command will be ignored.
idle_loop
#
idle_loop(
consumer,
send_heartbeat_fn,
send_result_fn,
heartbeat_interval_ms,
max_command_age_hours,
)
Run idle loop of the worker.
This will be running when the worker is currently not optimizing This will wait until a StartOptimizationCommand is received and return it. In case a ShutdownCommand is received, the worker will exit with the exit code provided in the command.
| PARAMETER | DESCRIPTION |
|---|---|
consumer
|
The initialized Kafka consumer to listen for commands on.
TYPE:
|
send_heartbeat_fn
|
A function to call when there were no messages received for a while.
TYPE:
|
send_result_fn
|
A function to call to send results back to the results topic, used to send a message in case a command is too old.
TYPE:
|
heartbeat_interval_ms
|
The time to wait for a new command in milliseconds. If no command has been received, a heartbeat will be sent and then the receiver will wait for commands again.
TYPE:
|
max_command_age_hours
|
The maximum age of a command in hours. If a command is received that is older than this, the command will be ignored and a message will be sent to the results topic.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
(StartOptimizationCommand,)
|
The start optimization command to start the optimization run with |
| RAISES | DESCRIPTION |
|---|---|
SystemExit
|
If a ShutdownCommand is received |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/worker.py
push_topologies
#
Push topologies to the results topic.
| PARAMETER | DESCRIPTION |
|---|---|
optimizer_data
|
The data of the optimizer, containing the repertoire with topologies to push.
TYPE:
|
epoch
|
The current epoch, used for logging and to include in the messages.
TYPE:
|
send_result_fn
|
A function to call to send results back to the results topic.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
int
|
The number of topologies pushed |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/worker.py
optimization_loop
#
optimization_loop(
dc_params,
grid_files,
send_result_fn,
flush_result_fn,
send_heartbeat_fn,
optimization_id,
processed_gridfile_fs,
)
Run an optimization until the optimization has converged
| PARAMETER | DESCRIPTION |
|---|---|
dc_params
|
The parameters for the optimization run, usually from the start command
TYPE:
|
grid_files
|
The grid files to load, where each gridfile represents one timestep.
TYPE:
|
send_result_fn
|
A function to queue results for the results topic. This callback is not expected to flush and will be called multiple times in every epoch, for every topology discovered. After all topologies have been sent, the flush_result_fn will be called to flush the results to Kafka.
TYPE:
|
flush_result_fn
|
A function to flush queued results to Kafka after one or more calls to
TYPE:
|
send_heartbeat_fn
|
A function to call after every epoch to signal that the worker is still alive.
TYPE:
|
optimization_id
|
The id of the optimization run. This will be used to identify the optimization run in the results. Should stay the same for the whole optimization run and should be equal to the kafka event key.
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
SystemExit
|
If a ShutdownCommand is received |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/worker.py
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | |
main
#
Run the main DC worker loop.
| PARAMETER | DESCRIPTION |
|---|---|
args
|
The command line arguments
TYPE:
|
processed_gridfile_fs
|
The target filesystem for the preprocessing worker. This contains all processed grid files. During the import job, a new folder import_results.data_folder was created which will be completed with the preprocess call to this function. Internally, only the data folder is passed around as a dirfs. Note that the unprocessed_gridfile_fs is not needed here anymore, as all preprocessing steps that need the unprocessed gridfiles were already done.
TYPE:
|
producer
|
The Kafka producer to send results and heartbeats with.
TYPE:
|
command_consumer
|
The Kafka consumer to receive commands with.
TYPE:
|
| RAISES | DESCRIPTION |
|---|---|
SystemExit
|
If the worker receives a ShutdownCommand |
Source code in packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/worker/worker.py
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | |