interfaces

The interfaces module defines common interfaces for the major classes in the pydsol framework. The use of interfaces (aka abstract base classes in Python) avoids circular references in the import of modules.

As an example, the Simulator class refers to a Replication and a Model in its initialize method. Both the Replication classes and the Model class have references to, and use methods from the Simulator class. The interfaces module that defines the core ‘contract’ for the Simulator, Model, Experiment, Replication and Statistics helps to avoid circular references, but also defines the core functionalities of these central classes in the pydscol framework.

Instead of combining all classes in one huge pydsol module with thousands of lines of code, the interfaces nicely decouple the definition of the classes and their implementation, and they avoid circular referencing of modules to each other. Think of the use of this particular interface module as the .h files in C++.

class pydsol.core.interfaces.SimulatorInterface[source]

Bases: ABC, Generic[TIME]

The SimulatorInterface defines the key methods for any Simulator to be used in the pydsol-framework. Different types of Simulators can be used, e.g., fixed time increment simulators (time ticks) for ABM and for solving differential equations, and variable time increments for discrete-event models. Simulators can run as-fast-as-possible or be synchronized with the wall clock time, etc.

Event Types:
  • STARTING_EVENT (EventType) – Will be fired when the simulator has been instructed to start. The actual start might not have happened yet.

  • START_EVENT (EventType) – Will be fired when the simulator has actually started.

  • STOPPING_EVENT (EventType) – Will be fired when the simulator has been instructed to stop or pause. The actual stop might not have happened yet.

  • START_EVENT (EventType) – Will be fired when the simulator has actually paused or stopped.

  • TIME_CHANGED_EVENT (EventType) – Will be fired when the time of the simulation has changed. This event can be very useful, for instance, to draw time-dependent graphs.

abstract property name: str

Return the name of the simulator.

abstract property time_type: type

Return the time type of the simulator.

abstract property simulator_time: TIME

Return the current absolute time of the simulator.

abstract property replication: ReplicationInterface

Return the replication with which the simulator has been initialized, or None when initialize has not yet been called.

abstract property model: ModelInterface

Return the model that is being simulated, or None when initialize for a model has not yet been called.

abstract initialize(model: ModelInterface, replication: ReplicationInterface)[source]

Initialize the simulator with a replication for a model.

abstract add_initial_method(target, method: str, **kwargs)[source]

Add a method call that has to be performed at the end if initialize, and before the model starts. This can, for instance, be used to schedule the execution of simulation events before initialize has been called, and solved the problem that, for discrete event simulators, the scheduleEvent(…) methods cannot be called before initialize().

abstract cleanup()[source]

Clean up after a replication has finished, and prepare for the next replication to run.

abstract start()[source]

Starts the simulator, and fire a START_EVENT when the simulator is started. The start method uses the RunUntil property with a value of the end time of the replication when starting the simulator.

Note

Note that when the simulator was already started, an exception will be raised, and no event will be fired.

abstract step()[source]

Steps the simulator, and fire a START_EVENT before the execution of the event, and a STOP_EVENT after the execution of the event to indicate the simulator made a step.

Note

Note that when the simulator is already running, an exception will be raised, and no event will be fired.

abstract stop()[source]

Stops or pauses the simulator, and fire a STOP_EVENT when the simulator is stopped.

Note

Note that when the simulator was already stopped, an exception will be raised, and no event will be fired.

abstract run_up_to(stop_time: TIME)[source]

Runs the simulator up to a certain time; any events at that time, or the solving of the differential equation at that timestep, will not yet be executed.

abstract run_up_to_including(stop_time: TIME)[source]

Runs the simulator up to a certain time; all events at that time, or the solving of the differential equation at that timestep, will be executed.

abstract is_initialized() bool[source]

Return whether the simulator has been initialized with a replication for a model.

abstract is_starting_or_running() bool[source]

Return whether the simulator is starting or has started.

abstract is_stopping_or_stopped() bool[source]

Return whether the simulator is stopping or has been stopped. This method also returns True when the simulator has not yet been initialized, or when the model has not yet started.

class pydsol.core.interfaces.ReplicationInterface[source]

Bases: ABC, Generic[TIME]

The ReplicationInterface defines the method that an Replication needs to implement. It also defines the events that will be fired to indicate that the execution of a replication on the simulator has started, and that a replication on the simulator has ended. A replication provides a start time, warmup time, and duration to the simulator and model, and it is related to a unique set of seed values for the random streams used in the stochastic simulation.

Event Types:
  • START_REPLICATION_EVENT (EventType) – Will be fired when the execution of the replication has started.

  • END_REPLICATION_EVENT (EventType) – Will be fired when the execution of the replication has completed.

  • WARMUP_EVENT (EventType) – Will be fired when the warmup period has been reached, and the defined statistics in the model will be cleared.

abstract property start_sim_time: TIME

Return the absolute start time of the replication

abstract property warmup_sim_time: TIME

Return the absolute warmup time of the replication

abstract property end_sim_time: TIME

Return the absolute end time of the replication

class pydsol.core.interfaces.ExperimentInterface[source]

Bases: ABC, Generic[TIME]

The ExperimentInterface defines the method that an Experiment needs to implement. It also defines the events that will be fired to indicate that the execution of an experiment on the simulator has started, and that an experiment on the simulator has ended. An experiment consists of a number of replications for the model that will be executed with the same start time, warmup time, and duration.

Event Types:
  • START_EXPERIMENT_EVENT (EventType) – Will be fired when the execution of the experiment has started.

  • END_EXPERIMENT_EVENT (EventType) – Will be fired when the execution of the experiment has completed.

class pydsol.core.interfaces.InputParameterInterface[source]

Bases: ABC

Input parameters describe different types of input parameters for the model. All parameters for a model are contained in a hierarchical map where successive keys can be retrieved using a dot-notation between the key elements. Suppose a model has two servers: server1 and server2. Each of the servers has an average service time and a number of resources. This can be coded using keys ‘server1.avg_serice_time’, ‘server1.nr_resources’, ‘server2.avg_serice_time’, ‘server2.nr_resources’. This means that the key ‘server1’ contains an InputParameterMap with an instance of InputParameterFloat for the service time, and InputParameterInt for the number of resources. Readers for the input parameter map can read the model parameters, e.g., from the screen, a web page, an Excel file, a properties file, or a JSON file.

This generic interface describes the minimum set of methods and properties that an InputParameter should have. The definition of the interface avoids circular references.

abstract property key: str

Return the key of the parameter that can be a part of the dot-notation to uniquely identify the model parameter. The key does not contain the name of the parent. The key is set at time of construction and it is immutable.

abstract extended_key()[source]

Return the extended key of this InputParameter including parents with a dot-notation. The name of this parameter is the last entry in the dot notation.

abstract property name: str

Returns the concise description of the input parameter, which can be used in a GUI to identify the parameter to the user.

abstract property description: str

Returns description or explanation of the InputParameter. For instance, an indication of the bounds or the type. This value is purely there for the user interface.

abstract property default_value: object

Returns the default (initial) value of the parameter. The actual return type will be defined in subclasses of InputParameter. The default value is immutable.

abstract property value: object

Returns the actual value of the parameter. The value is initialized with default_value and is updated based on user input or data input. The actual type will be defined in subclasses of InputParameter.

abstract set_value(value: object)[source]

Provides a new value for the parameter. The actual type of value will be defined in subclasses of InputParameter. This is actually a method and not a setter property because it can raise errors based on the validity of the value.

abstract property display_priority: float

Return the number indicating the order of display of the parameter in the parent parameter map. Floats make it easy to insert an extra parameter between parameters that have already been allocated subsequent integer values.

abstract property read_only: bool

Return whether a user is prohibited from changing the value of the parameter or not.

abstract property parent

Return the parent map in which the parameter can be retrieved using its key. Typically, only the root InputParameterMap has no parent, and all other parameters have an InputParameterMap as parent.

class pydsol.core.interfaces.ModelInterface[source]

Bases: ABC

The ModelInterface defines the minimum set of methods that a simulation model in the pydsol-framework should implement. Every model consists of the business logic (state transitions initialized in the construct_model method), input parameters, output statistics, and a reference to the simulator that executes the model.

The most important method for the Model is the construct_model method. This method is called for each replication to initialize the model to its initial state. The state of the model should be the same every time after the construct_model method has been called. Constant parts of the model that might be expensive to calculate (e.g., maps, large graphs, information from databases) does not have to be calculated every time in the construct_model method, but can be defined once in the __init__ method instead.

abstract construct_model()[source]

Code to construct the model logic for each replication. This method is called for each replication to initialize the model to its initial state. The state of the model should be the same every time after the construct_model method has been called. Constant parts of the model that might be expensive to calculate (e.g., maps, large graphs, information from databases) does not have to be calculated every time in the construct_model method, but can be defined once in the __init__ method instead.

abstract property simulator: SimulatorInterface

Return the simulator for this model.

abstract add_parameter(input_parameter)[source]

Add an input parameter to the input parameter map.

abstract set_parameter(key: str, value: object)[source]

set the parameter value of an input parameter.

abstract get_parameter(key: str) object[source]

return the value of an input parameter.

abstract output_statistics() Dict[str, StatisticsInterface][source]

return the output statistics map.

abstract add_output_statistic(key: str, statistic: StatisticsInterface)[source]

add an output statistic to the output statistics map.

abstract get_output_statistic(key: str) StatisticsInterface[source]

retrieve an output statistic from the output statistics map.

class pydsol.core.interfaces.StatisticsInterface[source]

Bases: ABC

The StatisticsInterface is a tagging interface for statistics classes. It defines the minimum set of method that any statistic in the pydsol-framework needs to implement.

abstract initialize() None[source]

Initialize the statistic. This can happen at a the start and/or at a simulation replication warmup event.

abstract property name: str

Return the descriptive name of the statistic.

abstract n() int[source]

Return the number of observations.

class pydsol.core.interfaces.SimStatisticsInterface[source]

Bases: StatisticsInterface

The SimStatisticsInterface is a tagging interface for statistics classes that are aware of the Simulator, and that can listen to events such as the WARMUP_EVENT to (re)initialize the statistics.

abstract notify(event) None[source]

EventListener behavior, so the statistic can be subscribed to events like WARMUP_EVENT and END_REPLICATION_EVENT.

abstract property simulator: SimulatorInterface

Return the simulator.

abstract initialize() None

Initialize the statistic. This can happen at a the start and/or at a simulation replication warmup event.

abstract n() int

Return the number of observations.

abstract property name: str

Return the descriptive name of the statistic.

class pydsol.core.interfaces.StatEvents[source]

Bases: object

StatEvents contains the set of events that different statistics in the statistics module can fire. To avoid circular references between the statistics module that fires the events, and modules that listen to events, all events are defines in one place as StatEvents.XXX_EVENT.

The events that can be used are listed below.

DATA_EVENT: EventType = EventType[StatEvents.DATA_EVENT metadata={self._metadata}]

The DATA_EVENT is the incoming event for EventBased statistics that contains a new value for the statistics. The payload is a single float. This event can be used by the EventBasedCounter and EventBasedTally and its subclasses. The event is fired from outside to these statistics.

WEIGHT_DATA_EVENT: EventType = EventType[StatEvents.WEIGHT_DATA_EVENT metadata={self._metadata}]

The WEIGHT_DATA_EVENT is the incoming event for weighted EventBased statistics that contains a new weight-value pair for the statistics. The payload is a tuple (weight, value). This event can be used by the EventBasedWeightedTally and its subclasses.The event is fired from outside to the statistics.

TIMESTAMP_DATA_EVENT: EventType = EventType[StatEvents.TIMESTAMP_DATA_EVENT metadata={self._metadata}]

The TIMESTAMP_DATA_EVENT is the incoming event for weighted EventBased statistics that contains a new timestamp-value pair for the statistics. The payload is a tuple (timestamp, value). This event can be used by the EventBasedTimestampWeightedTally and its subclasses.The event is fired from outside to the statistics.

INITIALIZED_EVENT: EventType = EventType[StatEvents.INITIALIZED_EVENT metadata={self._metadata}]

INITIALIZED_EVENT indicates that the statistic has been (re)initialized, and all counters have been reset to the original values. The event is fired by the statistic to its listeners.

OBSERVATION_ADDED_EVENT: EventType = EventType[StatEvents.OBSERVATION_ADDED_EVENT metadata={self._metadata}]

OBSERVATION_ADDED_EVENT indicates that an observation has been received, and contains the value of the observation as the payload. For weight-bsaed and timestamp-based observations, the payload is a tuple. For value-based statistics, the payload is just the (float) value. The event is fired by the statistic to its listeners.

N_EVENT: EventType = EventType[StatEvents.N_EVENT metadata={self._metadata}]

N_EVENT indicates that the number of observations has been increased, and contains the new number of observation as the payload. The event is fired by the statistic to its listeners.

COUNT_EVENT: EventType = EventType[StatEvents.COUNT_EVENT metadata={self._metadata}]

COUNT_EVENT is an event of the Counter statistic and is subclasses. The event indicates that the count has changed, and contains the new count as the payload. The event is fired by the statistic to its listeners.

MIN_EVENT: EventType = EventType[StatEvents.MIN_EVENT metadata={self._metadata}]

MIN_EVENT indicates that the minimum of the observations has changed, and contains the new minimum as the payload. This event is fired by the EventBasedTally, its Weighted and Timestamped variant, and its subclasses to the listeners.

MAX_EVENT: EventType = EventType[StatEvents.MAX_EVENT metadata={self._metadata}]

MAX_EVENT indicates that the maximum of the observations has changed, and contains the new maximum as the payload. This event is fired by the EventBasedTally, its Weighted and Timestamped variants, and their subclasses to the listeners.

SUM_EVENT: EventType = EventType[StatEvents.SUM_EVENT metadata={self._metadata}]

SUM_EVENT indicates that the sum of the observations has changed, and contains the new sum as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

MEAN_EVENT: EventType = EventType[StatEvents.MEAN_EVENT metadata={self._metadata}]

MEAN_EVENT indicates that the mean of the observations has changed, and contains the new mean as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

POPULATION_STDEV_EVENT: EventType = EventType[StatEvents.POPULATION_STDEV_EVENT metadata={self._metadata}]

POPULATION_STDEV_EVENT indicates that the population standard deviation of the observations has changed, and contains the new standard deviation as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

POPULATION_VARIANCE_EVENT: EventType = EventType[StatEvents.POPULATION_VARIANCE_EVENT metadata={self._metadata}]

POPULATION_VARIANCE_EVENT indicates that the population variance of the observations has changed, and contains the new variance as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

POPULATION_SKEWNESS_EVENT: EventType = EventType[StatEvents.POPULATION_SKEWNESS_EVENT metadata={self._metadata}]

POPULATION_SKEWNESS_EVENT indicates that the population skewness of the observations has changed, and contains the new skewness as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

POPULATION_KURTOSIS_EVENT: EventType = EventType[StatEvents.POPULATION_KURTOSIS_EVENT metadata={self._metadata}]

POPULATION_KURTOSIS_EVENT indicates that the population kurtosis of the observations has changed, and contains the new kurtosis as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

POPULATION_EXCESS_K_EVENT: EventType = EventType[StatEvents.POPULATION_EXCESS_K_EVENT metadata={self._metadata}]

POPULATION_EXCESS_K_EVENT indicates that the population exces kurtosis of the observations has changed, and contains the new excess kurtosis as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

SAMPLE_STDEV_EVENT: EventType = EventType[StatEvents.SAMPLE_STDEV_EVENT metadata={self._metadata}]

SAMPLE_STDEV_EVENT indicates that the sample standard deviation of the observations has changed, and contains the new standard deviation as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

SAMPLE_VARIANCE_EVENT: EventType = EventType[StatEvents.SAMPLE_VARIANCE_EVENT metadata={self._metadata}]

SAMPLE_VARIANCE_EVENT indicates that the sample variance of the observations has changed, and contains the new variance as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

SAMPLE_SKEWNESS_EVENT: EventType = EventType[StatEvents.SAMPLE_SKEWNESS_EVENT metadata={self._metadata}]

SAMPLE_SKEWNESS_EVENT indicates that the sample skewness of the observations has changed, and contains the new skewness as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

SAMPLE_KURTOSIS_EVENT: EventType = EventType[StatEvents.SAMPLE_KURTOSIS_EVENT metadata={self._metadata}]

SAMPLE_KURTOSIS_EVENT indicates that the sample kurtosis of the observations has changed, and contains the new kurtosis as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

SAMPLE_EXCESS_K_EVENT: EventType = EventType[StatEvents.SAMPLE_EXCESS_K_EVENT metadata={self._metadata}]

SAMPLE_EXCESS_K_EVENT indicates that the sample excess kurtosis of the observations has changed, and contains the new excess kurtosis as the payload. This event is fired by the EventBasedTally and its subclasses to the listeners.

WEIGHTED_SUM_EVENT: EventType = EventType[StatEvents.WEIGHTED_SUM_EVENT metadata={self._metadata}]

WEIGHTED_SUM_EVENT indicates that the weighted sum of the observations has changed, and contains the new weighted sum as the payload. This event is fired by the EventBasedWeightedTally and its subclasses to the listeners.

WEIGHTED_MEAN_EVENT: EventType = EventType[StatEvents.WEIGHTED_MEAN_EVENT metadata={self._metadata}]

WEIGHTED_MEAN_EVENT indicates that the weighted mean of the observations has changed, and contains the new weighted mean as the payload. This event is fired by the EventBasedWeightedTally and its subclasses to the listeners.

WEIGHTED_POPULATION_STDEV_EVENT: EventType = EventType[StatEvents.WEIGHTED_POPULATION_STDEV_EVENT metadata={self._metadata}]

WEIGHTED_POPULATION_STDEV_EVENT indicates that the weighted population standard deviation of the observations has changed, and contains the new weighted standard deviation as the payload. This event is fired by the EventBasedWeightedTally and its subclasses to the listeners.

WEIGHTED_POPULATION_VARIANCE_EVENT: EventType = EventType[StatEvents.WEIGHTED_POPULATION_VARIANCE_EVENT metadata={self._metadata}]

WEIGHTED_POPULATION_VARIANCE_EVENT indicates that the weighted population variance of the observations has changed, and contains the new weighted variance as the payload. This event is fired by the EventBasedWeightedTally and its subclasses to the listeners.

WEIGHTED_SAMPLE_STDEV_EVENT: EventType = EventType[StatEvents.WEIGHTED_SAMPLE_STDEV_EVENT metadata={self._metadata}]

WEIGHTED_SAMPLE_STDEV_EVENT indicates that the weighted sample standard deviation of the observations has changed, and contains the new weighted standard deviation as the payload. This event is fired by the EventBasedWeightedTally and its subclasses to the listeners.

WEIGHTED_SAMPLE_VARIANCE_EVENT: EventType = EventType[StatEvents.WEIGHTED_SAMPLE_VARIANCE_EVENT metadata={self._metadata}]

WEIGHTED_SAMPLE_VARIANCE_EVENT indicates that the weighted sample variance of the observations has changed, and contains the new weighted variance as the payload. This event is fired by the EventBasedWeightedTally and its subclasses to the listeners.