SimPy Classic Simulation with Event Stepping¶
Authors: |
|
---|---|
Release: | 2.3.4 |
Web-site: | |
Python Version: | 2.7+ |
Date: | December 2011 |
Updated: | January 2018 |
Contents
This manual describes SimulationStep, a SimPy module which supports stepping through a simulation model event by event.
Introduction¶
SimulationStep can assist with debugging models, interacting with them on an event-by-event basis, getting event-by-event output from a model (e.g. for plotting purposes), etc.
SimulationStep is a derivative of the Simulation module. Over and above the capabilities provided by Simulation, SimulationStep supports stepping through a simulation model event by event. It caters for:
- running a simulation model, with calling a user-defined procedure after every event,
- running a simulation model one event at a time by repeated calls,
- starting and stopping the event stepping mode under program control.
SimulationStep overview¶
Here is a simple program which shows basic event stepping capabilities:
# simstep_stepping1.py
import SimPy.SimulationStep as SimulationStep # (1)
def callbackTimeTrace(): # (2)
"""Prints event times
"""
print("at time=%s" % SimulationStep.now())
class Man(SimulationStep.Process):
def walk(self):
print("got up")
yield SimulationStep.hold, self, 1
print("got to door")
yield SimulationStep.hold, self, 10
print("got to mail box")
yield SimulationStep.hold, self, 10
print("got home again")
# trace event times
SimulationStep.initialize()
otto = Man()
SimulationStep.activate(otto, otto.walk())
SimulationStep.startStepping() # (3)
SimulationStep.simulate(callback=callbackTimeTrace, until=100) # (4)
A trivial simulation model, but with event stepping:
- import the stepping version of Simulation
- define a procedure which gets called after every event
- switch into event stepping mode
- run the model with event callback to the procedure defined at (2);
simulate
in SimulationStep has an extra named parameter,callback
.
Running it produces this output:
got up
at time=0
got to door
at time=1
got to mail box
at time=11
got home again
at time=21
The callback outputs the simulation time after every event.
Here is another example, the same model, but now with the user getting control back after every event:
# simstep_stepping2.py
import SimPy.SimulationStep as SimulationStep
def callbackUserControl():
"""Allows user to control stepping
"""
# In python 2.7 you need to make this raw_input
a = input("[Time=%s] Select one: End run (e), Continue stepping (s), "
"Run to end (r)= " % SimulationStep.now())
if a == "e":
SimulationStep.stopSimulation()
elif a == "s":
return
else:
SimulationStep.stopStepping()
class Man(SimulationStep.Process):
def walk(self):
print("got up")
yield SimulationStep.hold, self, 1
print("got to door")
yield SimulationStep.hold, self, 10
print("got to mail box")
yield SimulationStep.hold, self, 10
print("got home again")
# allow user control
SimulationStep.initialize()
otto = Man()
SimulationStep.activate(otto, otto.walk())
SimulationStep.startStepping()
SimulationStep.simulate(callback=callbackUserControl, until=100)
Its interactive output looks like this:
got up
[Time=0] Select one: End run (e), Continue stepping (s), Run to end (r)= s
got to door
[Time=1] Select one: End run (e), Continue stepping (s), Run to end (r)= s
got to mail box
[Time=11] Select one: End run (e), Continue stepping (s), Run to end (r)= s
got home again
[Time=21] Select one: End run (e), Continue stepping (s), Run to end (r)= s
[Time=21] Select one: End run (e), Continue stepping (s), Run to end (r)= s
or this (the user stopped stepping mode at time=1):
got up
[Time=0] Select one: End run (e), Continue stepping (s), Run to end (r)= s
got to door
[Time=1] Select one: End run (e), Continue stepping (s), Run to end (r)= r
got to mail box
got home again
If one wants to run a tested/debugged model full speed, i.e. without stepping, one can write a program as follows:
# simstep_stepping2fast.py
if __debug__:
import SimPy.SimulationStep as Simulation
else:
import SimPy.Simulation as Simulation
def callbackUserControl():
"""Allows user to control stepping
"""
if __debug__:
# In python 2.7 you need to make this raw_input
a = input("[Time=%s] Select one: End run (e), Continue stepping (s),"
"Run to end (r)= " % Simulation.now())
if a == "e":
Simulation.stopSimulation()
elif a == "s":
return
else:
Simulation.stopStepping()
class Man(Simulation.Process):
def walk(self):
print("got up")
yield Simulation.hold, self, 1
print("got to door")
yield Simulation.hold, self, 10
print("got to mail box")
yield Simulation.hold, self, 10
print("got home again")
# allow user control if debugging
Simulation.initialize()
otto = Man()
Simulation.activate(otto, otto.walk())
if __debug__:
Simulation.startStepping()
Simulation.simulate(callback=callbackUserControl, until=100)
else:
Simulation.simulate(until=100)
If one runs this with the Python command line option ‘-O’, any
statement starting with if __debug__:
is ignored/skipped by the
Python interpreter.
The SimulationStep API¶
Structure¶
Basically, SimulationStep has the same API as Simulation, but with the following additions and changes:
def startStepping() **new**
def stopStepping() **new**
def simulate() **changed**
def simulateStep() **new**
startStepping¶
Starts the event-stepping.
Call:
startStepping()
- Mandatory parameters:
- None.
- Optional parameters:
- None
- Return value:
- None.
stopStepping¶
Stops event-stepping.
- Call:
- stopStepping()
- Mandatory parameters:
- None
- Optional parameters:
- None
- Return value:
- None
simulate¶
Runs a simulation with callback to a user-defined function after each event, if stepping is turned on. By default, stepping is switched off.
- Call:
- simulate(callback=<proc>,until=<endtime>)
- Mandatory parameters:
- None
- Optional parameters:
- until = 0: the simulation time until which the simulation is to run (positive floating point or integer number)
- callback = lambda:None: the function to be called after every event (function reference)
- Return value:
- The simulation status at exit (string)
simulateStep¶
Runs a simulation for one event, with (optional) callback to a user-defined function after the event, if stepping is turned on. By default, stepping is switched off. Thus, to execute the model to completion, simulateStep must be called repeatedly.
Note: it is not yet clear to the developers whether this part of the API offers any advantages or capabilities over and above the *simulate* function. The survival of this function in future versions depends on the feedback from the user community.
- Call:
- simulateStep(callback=<proc>,until=<endtime>)
- Mandatory parameters:
- None
- Optional parameters:
- until = 0: the simulation time until which the simulation is to run (positive floating point or integer number)
- callback = lambda:None: the function to be called after every event (function reference)
- Return value:
- The tuple (simulation status at exit (string),<resumability flag>). <resumability flag> can have one of two string values: “resumable” if there are more events to be executed, and “notResumable” if all events have been exhausted or an error has occurred. simulateStep should normally only be called if “resumable” is returned.