Steering – changing Python parameters using Graphical User Interface.¶
In the previous section we outlined how to programmatically change CC3DML parameters. In this section we will show you how to create a graphical panel where you can use sliders and or pull down list to control parameters defined in the Python scripts. this type of interaction is very desirable because you can try different values of parameters without writing complicated procedural code that alters the parameters. It also provides you with a very convenient way to create truly interactive simulations.
In our demo suite we have included examples (e.g. Demos/SteeringPanel/steering_panel_demo
) that
demonstrate how to setup such interactive simulations. In this section we will explain all coding that is necessary
to accomplish this task.
When you run open Demos/SteeringPanel/steering_panel_demo
in CC3D and run it
the screen will look as follows:
All the code that is necessary to get steering panel for Python parameters working will reside in Python steppable file.
To specify steering panel we have to define add_steering_panel
function to our steppable (the function has to be
called exactly that):
class VolumeSteeringSteppable(SteppableBasePy):
def __init__(self, _simulator, _frequency=10):
SteppableBasePy.__init__(self, _simulator, _frequency)
def add_steering_panel(self):
self.add_steering_param(name='target_vol', val=25, min_val=0, max_val=100, widget_name='slider')
self.add_steering_param(name='lambda_vol', val=2.0, min_val=0, max_val=10.0, decimal_precision=2, widget_name='slider')
self.add_steering_param(name='lam_vol_enum', val=2.0, min_val=0, max_val=10.0, decimal_precision=2,widget_name='slider')
The add_steering_panel
function requires several arguments:
name
- specifies the label of the parameters to be displayed in the guival
- specifies current value of the python parametermin_val
andmax_val
- specify range of parameters. those are optional and by default CC3D will pick some reasonable range given theval
parameter. However, we recommend that you specify the allowable parameters rangewidget_name
- a string that specifies the widget via which you will be changing the parameter. The allowed options are:slider
- it wil create a slider,combobox
,pulldown
,pull-down
will pull-down list for discrete values, and no argument will resort to a editable field where you have to type the parameterdecimal_precision
- specifies how many decimal places are to be displayed when changing parameters. Default value is0
Once you add such function to the steppable and start the simulation the steering panel will pop-up but it will have no functionality. Panel will have just 3 entries as show below:
IMPORTANT : you can add steering panel from multiple steppables. In such a case CC3D will gather all parameters
you defined in the add_steering_panel
function and display them in a single panel. For example, if our code has
two steppables and we add steering parameters in both of them:
class VolumeSteeringSteppable(SteppableBasePy):
def __init__(self, _simulator, _frequency=10):
SteppableBasePy.__init__(self, _simulator, _frequency)
def add_steering_panel(self):
self.add_steering_param(name='target_vol', val=25, min_val=0, max_val=100, widget_name='slider')
self.add_steering_param(name='lambda_vol', val=2.0, min_val=0, max_val=10.0, decimal_precision=2, widget_name='slider')
self.add_steering_param(name='lam_vol_enum', val=2.0, min_val=0, max_val=10.0, decimal_precision=2,widget_name='slider')
class SurfaceSteeringSteppable(SteppableBasePy):
def __init__(self, _simulator, _frequency=10):
SteppableBasePy.__init__(self, _simulator, _frequency)
def add_steering_panel(self):
#adding slider
self.add_steering_param(name='lambda_surface', val=0.2, min_val=0, max_val=10.0, decimal_precision=2,
widget_name='slider')
# adding combobox
self.add_steering_param(name='target_surface', val=20, enum=[10,20,30,40,50,60,70,80,90,100],
widget_name='combobox')
we will end up with a panel that looks as follows :
Notice that the last parameter target_surface
uses combobox
and appropriately the widget displayed is
a pull-down-list
Now that we know how to specify steering panel let’s learn how to implement interactivity. All we need to do
is to implement another function in the steppable - process_steering_panel_data
. Let’s look at the example:
class VolumeSteeringSteppable(SteppableBasePy):
def __init__(self, _simulator, _frequency=10):
SteppableBasePy.__init__(self, _simulator, _frequency)
def add_steering_panel(self):
self.add_steering_param(name='target_vol', val=25, min_val=0, max_val=100, widget_name='slider')
self.add_steering_param(name='lambda_vol', val=2.0, min_val=0, max_val=10.0, decimal_precision=2, widget_name='slider')
self.add_steering_param(name='lam_vol_enum', val=2.0, min_val=0, max_val=10.0, decimal_precision=2,widget_name='slider')
def process_steering_panel_data(self):
target_vol = self.get_steering_param('target_vol')
lambda_vol = self.get_steering_param('lambda_vol')
for cell in self.cellList:
cell.targetVolume = target_vol
cell.lambdaVolume = lambda_vol
Inside process_steering_panel_data
(the function has to be called exactly that) we read the current value indicated
in the steering panel using convenience function get_steering_param
. In our example we are reading
two parameter values from the panel -target_val
and lambda_val
. Once we fetched the values from the panel
we iterate over all cells and modify targetVolume
and lambdaVolume
parameters of every cell.
Important: process_steering_panel_data
gets called only when the user modified the values in the steering panel by
either moving a slider, changing entry in the pull-down list or changing the parameter value using text field. This means
that potentially expensive loops that alter parameters are not executed every MCS but only if panel entries have changed.
you can manually check if the panel values have changed by adding to your code steppable’s convenience function
steering_param_dirty()
. You do not have to do that but just in case you would like to get a flag indicating whether
panel has change or not all that’s required is simple code like that:
def process_steering_panel_data(self):
print 'all dirty flag=', self.steering_param_dirty()
As you can see by adding two functions to the steppable - add_steering_panel
and process_steering_panel_data
you
can create truly interactive simulations where you can have a direct control over simulations. Tool like that
can be especially useful in the exploratory phases of your model building where you want to quickly see what impact a
given parameter has on the overall simulation.
IMPORTANT . You can simplify setting up of interactive steering using Twedit Python helpers menu. Simply, go to
CC3D Python -> Steering Panel
menu and choose 1. Setup Steering Panel
option: