Callbacks
SRToolkit.evaluation.callbacks
Event-driven callback system for monitoring and controlling SR evaluation.
Provides event dataclasses fired during evaluation, the SRCallbacks base class for implementing custom callbacks, a CallbackDispatcher for managing multiple callbacks, and built-in implementations for progress display, early stopping, and logging.
ExprEvaluated
dataclass
ExprEvaluated(expression: str, error: float, evaluation_number: int, experiment_id: str, is_new_best: bool)
Fired after each expression is evaluated by evaluate_expr.
Attributes:
| Name | Type | Description |
|---|---|---|
expression |
str
|
String representation of the evaluated expression. |
error |
float
|
Error value returned by the ranking function (RMSE or BED). |
evaluation_number |
int
|
Total number of evaluate_expr calls made so far, including cache hits. |
experiment_id |
str
|
Identifier of the current experiment. |
is_new_best |
bool
|
|
BestExpressionFound
dataclass
Fired when a new best expression is found during evaluation.
Attributes:
| Name | Type | Description |
|---|---|---|
experiment_id |
str
|
Identifier of the current experiment. |
expression |
str
|
String representation of the new best expression. |
error |
float
|
Error value of the new best expression. |
evaluation_number |
int
|
Total number of evaluate_expr calls made at the time this event is fired. |
ExperimentEvent
dataclass
ExperimentEvent(dataset_name: str, approach_name: str, max_evaluations: Optional[int], success_threshold: Optional[float], seed: Optional[int])
Fired at experiment start and end.
Attributes:
| Name | Type | Description |
|---|---|---|
dataset_name |
str
|
Name of the dataset being evaluated. |
approach_name |
str
|
Name of the SR approach being run. |
max_evaluations |
Optional[int]
|
Maximum number of evaluations allowed for this experiment. |
success_threshold |
Optional[float]
|
Error threshold for success, or |
seed |
Optional[int]
|
Random seed used for this experiment, or |
SRCallbacks
Bases: ABC
Abstract base class for SR evaluation callbacks.
Implement only the methods you need. Return False from
on_expr_evaluated or
on_best_expression
to request early stopping; return True or None to continue.
Examples:
>>> class PrintBestCallback(SRCallbacks):
... def on_best_expression(self, event):
... print(f"New best: {event.expression} (error={event.error:.4g})")
>>> cb = PrintBestCallback()
>>> cb.on_best_expression(BestExpressionFound("", "X_0+C", 0.01, 5))
New best: X_0+C (error=0.01)
on_expr_evaluated
Called after each expression is evaluated.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ExprEvaluated
|
Data about the evaluated expression. |
required |
Returns:
| Type | Description |
|---|---|
Optional[bool]
|
|
Source code in SRToolkit/evaluation/callbacks.py
on_best_expression
Called when a new best expression is found.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BestExpressionFound
|
Data about the new best expression. |
required |
Returns:
| Type | Description |
|---|---|
Optional[bool]
|
|
Source code in SRToolkit/evaluation/callbacks.py
on_experiment_start
Called before an experiment starts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ExperimentEvent
|
Data about the experiment that is about to begin. |
required |
on_experiment_end
Called after an experiment completes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ExperimentEvent
|
Data about the experiment that just ended. |
required |
results
|
EvalResult
|
Final EvalResult for this experiment. |
required |
Source code in SRToolkit/evaluation/callbacks.py
to_dict
Serialise this callback to a JSON-safe dictionary.
The default implementation stores only the fully-qualified class path. Override in subclasses to include constructor parameters so that from_dict can reconstruct a functionally identical instance.
Returns:
| Type | Description |
|---|---|
dict
|
A JSON-safe dict with at least a |
Source code in SRToolkit/evaluation/callbacks.py
from_dict
classmethod
Reconstruct a callback from a serialised dictionary.
The default implementation calls cls() with no arguments. Override in
subclasses that require constructor parameters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
dict
|
Dictionary produced by to_dict. |
required |
Returns:
| Type | Description |
|---|---|
SRCallbacks
|
A new instance of this callback class. |
Source code in SRToolkit/evaluation/callbacks.py
CallbackDispatcher
Manages multiple SRCallbacks instances and dispatches events to all of them.
Examples:
>>> dispatcher = CallbackDispatcher()
>>> dispatcher.add(EarlyStoppingCallback(threshold=1e-6))
>>> len(dispatcher._callbacks)
1
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callbacks
|
Optional[List[SRCallbacks]]
|
Initial list of callbacks. Defaults to an empty list. |
None
|
Source code in SRToolkit/evaluation/callbacks.py
get_callbacks
Returns the list of callbacks.
Returns:
| Type | Description |
|---|---|
List[SRCallbacks]
|
A list of SRCallbacks instances in this dispatcher. |
add
Add a callback to the dispatcher.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
SRCallbacks
|
The SRCallbacks instance to add. |
required |
remove
Remove a callback from the dispatcher.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
callback
|
SRCallbacks
|
The SRCallbacks instance to remove. |
required |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in SRToolkit/evaluation/callbacks.py
on_expr_evaluated
Dispatch to all callbacks and aggregate the stop signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ExprEvaluated
|
Data about the evaluated expression. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in SRToolkit/evaluation/callbacks.py
on_best_expression
Dispatch to all callbacks and aggregate the stop signal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
BestExpressionFound
|
Data about the new best expression. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in SRToolkit/evaluation/callbacks.py
on_experiment_start
Dispatch to all callbacks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ExperimentEvent
|
Data about the experiment that is about to begin. |
required |
Source code in SRToolkit/evaluation/callbacks.py
on_experiment_end
Dispatch to all callbacks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
ExperimentEvent
|
Data about the experiment that just ended. |
required |
results
|
EvalResult
|
Final EvalResult for this experiment. |
required |
Source code in SRToolkit/evaluation/callbacks.py
ProgressBarCallback
Bases: SRCallbacks
Displays a tqdm progress bar that updates after each expression evaluation.
Examples:
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
desc
|
Optional[str]
|
Description label shown on the progress bar. If |
None
|
Source code in SRToolkit/evaluation/callbacks.py
EarlyStoppingCallback
Bases: SRCallbacks
Stops the search when the best expression error falls below a threshold.
Examples:
>>> cb = EarlyStoppingCallback(threshold=1e-6)
>>> cb.on_best_expression(BestExpressionFound("", "X_0", 1e-7, 42))
False
>>> cb.on_best_expression(BestExpressionFound("", "X_0", 1e-5, 43))
True
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
threshold
|
Optional[float]
|
Error value below which the search is stopped. |
required |
Source code in SRToolkit/evaluation/callbacks.py
LoggingCallback
Bases: SRCallbacks
Logs each new best expression to stdout or a file.
log_file may contain placeholders that are resolved at experiment start
using fields from ExperimentEvent.
Available placeholders: {dataset_name},{approach_name}, {seed}. Using
per-experiment placeholders (e.g. {seed}) gives each job its own file, which is
the recommended approach for parallel execution.
When multiple jobs share the same resolved file path, writes are protected
by fcntl.flock (POSIX advisory locking) so concurrent processes on
Linux / macOS do not corrupt each other's output. On Windows or network
filesystems where flock is unavailable the lock is silently skipped.
Examples:
>>> cb = LoggingCallback()
>>> cb.on_best_expression(BestExpressionFound("Nguyen-1_ProGED_42", "X_0+C", 0.001, 10))
[Experiment Nguyen-1_ProGED_42] New best: X_0+C (error=1.000000e-03)
>>> cb = LoggingCallback(log_file="logs/{dataset_name}_{seed}.log")
>>> cb.on_experiment_start(ExperimentEvent(dataset_name="test", max_evaluations=10, seed=1,
... success_threshold=0, approach_name="ta"))
>>> cb._resolved_log_file
'logs/test_1.log'
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
log_file
|
Optional[str]
|
Destination for log messages. If |
None
|