5.3. Writing E-Cell Session Script

The syntax of ESS is a full set of Python language with some convenient features.

5.3.1. Using Session methods

5.3.1.1. General rules

In ESS, an instance of Session is given, and any methods defined in the class can be used as if it is defined in the global namespace.

For example, to run the simulation for 10 seconds, use run method of the Session object.

self.run( 10 )

where self. points to the current Session object given by the system. Alternatively, you can use theSession in place of the self.

theSession.run( 10 )

Unlike usual Python script, you can omit the object on which the method is called if the method is for the current Session.

run( 10 )

5.3.1.2. Loading a model

Let's try this in the interactive mode of the ecell3-session command. On the prompt of the command, load an EML file by using loadModel() method.

ecell3-session>>> loadModel( 'simple.eml' )

Then the prompt changes from ecell3-session>>> to model_name, t=current time>>>

simple.eml, t=0>>> 

5.3.1.3. Running the simulation

To proceed the time by executing the simulation, step() and run() methods are used.

simple.eml, t=0>>> step()
simple.eml, t=0>>> step()
simple.eml, t=7.67306e-07>>> run( 10 )
simple.eml, t=10.0032>>> 

step( n ) conducts n steps of the simulation. The default value of n is 1.

Note

In above example you may notice that the first call of step() does not cause the time to change. The simulator updates the time at the beginning of the step, and calculates a tentative step size after that. The initial value of the step size is zero. Thus it needs to call step() twice to actually proceed the time. See chapter 6 for details of the simulation mechanism.

To execute the simulation for some seconds, call run method with a duration in seconds. (e.g. run( 10 ) for 10 seconds.) run method steps the simulation repeatedly, and stops when the time is proceeded for the given seconds. In other words, the meaning of run( 10 ) is to run the simulation at least 10 seconds. It always overrun the specified length of time to a greater or less.

The system supports run without an argument to run forever, if and only if both event checker and event handler are set. If not, it raises an exception. See setEventChecker() in the method list of Session class.

5.3.1.4. Getting current time

To get the current time of the simulator, getCurrentTime() method can be used.


simple.eml, t=10.0032>>> getCurrentTime()
10.003221620379463

5.3.1.5. Printing messages

You may want to print some messages in your ESS. Use message( message ) method, where message argument is a string to be outputed.

By default the message is handled in a way the same as the Python's print statement; it is printed out to the standard out with a trailing new line. This behavior can be changed by using setMessageMethod() method.

5.3.1.6. An example of using Session methods

Here is a tiny example of using Session methods which loads a model, run a hundred seconds, and print a short message.

Example 5-1. A simple ESS example.

    loadModel( 'simple.eml' )
    run( 100 )
    message( 'stopped at %f seconds.' % getCurrentTime() )
    

5.3.2. Getting Session Parameters.

Session parameters are given to an ESS as global variables. Therefore usage of the session parameters is very simple. For example, if you can assume a session parameter MODELFILE is given, just use it as a variable:

loadModel( MODELFILE )

To check what parameters are given to ESS, use dir() or globals() built-in functions. Session parameters are listed as well as other available methods and variables. To check if a certain ESS parameter or a global variable is given, write an if statement like this:

if 'MODELFILE' in globals():
    # MODELFILE is given
else:
    # not given

Note

Currently there is no way to distinguish the Session parameters from other global variables from ESS.

5.3.3. Observing and Manipulating the Model with ObjectStubs

5.3.3.1. What is ObjectStub?

ObjectStub is a proxy object in the frontend side of the system which corresponds to an internal object in the simulator. Any operations on the simulator's internal objects should be done via the ObjectStub.

There are three types of ObjectStub:

  • EntityStub

  • StepperStub

  • LoggerStub

each correspond to Entity, Stepper, and Logger classes in the simulator, respectively.

5.3.3.2. Why ObjectStub is needed

ObjectStub classes are actually thin wrappers over the ecell.ecs.Simulator class of the E-Cell Python Library, which provides object-oriented appearance to the flat procedure-oriented API of the class. Although Simulator object can be accessed directly via theSimulator property of Session class, use of ObjectStub is encouraged.

This backend / frontend isolation is needed because lifetimes of backend objects are not the same as that of frontend objects, nor are their state transitions necessarily synchronous. If the frontend directly manipulates the internal objects of the simulator, consistency of the lifetime and the state of the objects can easily be violated, which must not happen, without some complicated and tricky software mechanism.

5.3.3.3. Creating an ObjectStub by ID

To get an ObjectStub object, createEntityStub(), createStepperStub(), and createLoggerStub() methods of Session class are used.

For example, to get an EntityStub, call the createEntityStub() method with a FullID string:

anADPStub = createEntityStub( 'Variable:/CELL/MT1:ADP' )

Similarly, a StepperStub object and a LoggerStub object can be retrieved with a StepperID and a FullPN, respectively.

aStepperStub = createStepperStub( 'STEPPER_01' )
aLoggerStub = createLoggerStub( 'Variable:/CELL/MT1:GLUCOSE:Concentration'  )

5.3.3.4. Creating and checking existence of the backend object

Creating an ObjectStub does not necessarily mean a corresponding object in the simulator backend exists, or is created. In other words, creation of the ObjectStub is purely a frontend operation. After creating an ObjectStub, you may want to check if the corresponding backend object exists, and/or to command the backend to create the backend object.

To check if a corresponding object to an ObjectStub exists in the simulator, use exists() method. For example, the following if statement checks if a Stepper whose ID is STEPPER_01 exists:

aStepperStub = createStepperStub( 'STEPPER_01' )
if aStepperStub.exists():
    # it already exists
else:
    # it is not created yet

To create the backend object, just call create() method.

aStepperStub.create()# Stepper 'STEPPER_01' is created here

5.3.3.5. Getting the name and a class name from an ObjectStub

To get the name (or an ID) of an ObjectStub, use getName() method.

To get the class name of an EntityStub or a StepperStub, call getClassName() method. This operation is not applicable to LoggerStub.

5.3.3.6. Setting and getting properties

As described in the previous chapters, Entity and Stepper objects has properties. This section describes how to access the object properties via ObjectStubs. This section is not applicable to LoggerStubs.

To get a property value from a backend object by using an EntityStub or a StepperStub, invoke getProperty() method or access an object attribute with a property name:

aValue = aStub.getProperty( 'Activity' )

or equivalently,

aValue = aStub[ 'Activity' ]

To set a new property value to an Entity or a Stepper, call setProperty() method or mutate an object attribute with a property name and the new value:

aStub.getProperty( 'Activity', aNewValue )

or equivalently,

aStub[ 'Activity' ] = aNewValue

List of all the properties can be gotten by using getPropertyList method, which returns a list of property names as a Python tuple containing string objects.

aStub.getPropertyList()

To know if a property is getable (accessible) or setable (mutable), call getPropertyAttribute() with the name of the property. The method returns a Python tuple whose first element is true if the property is setable, and the second element is true if it is getable. Attempts to get a value from an inaccessible property and to set a value to a immutable property result in exceptions.

aStub.getPropertyAttribute( 'Activity' )[0] # true if setable
aStub.getPropertyAttribute( 'Activity' )[1] # true if getable

5.3.3.7. Getting Logger data

To get logged data from a LoggerStub, use getData() method.

getData() method has three forms according to requested range and time resolution of the data:

  • getData()

    Get the whole data.

  • getData( starttime [, endtime] )

    Get a slice of the data from starttime to endtime. If endtime is omitted, the slice includes the tail of the data.

  • getData( starttime, endtime, interval )

    Get a slice of the data from starttime to endtime. This omits data points if a time interval between two datapoints is smaller than interval. This is not suitable for scientific data analysis, but optimized for speed.

getData() method returns a rank-2 (matrix) array object of Numeric Python module. The array has either one of the following forms:

[ [ time value average min max ]
  [ time value average min max ]
... ] 

or

[ [ time value ]
  [ time value ]
... ] 

The first five-tuple data format has five values in a single datapoint:

  • time

    The time of the data point.

  • value

    The value at the time point.

  • average

    The time-weighted average of the value after the last data point to the time of this data point.

  • min

    The minimum value after the last data point to the time of this data point.

  • max

    The maximum value after the last data point to the time of this data point.

The two-tuple data format has only time and value.

To know the start time, the end time, and the size of the logged data before getting data, use getStartTime(), getEndTime(), and getSize() methods of LoggerStub. getSize() returns the number of data points stored in the Logger.

5.3.3.8. Getting and changing logging interval

Logging interval of a Logger can be checked and changed by using getMinimumInterval() and setMinimumInterval( interval ) methods of LoggerStub. interval must be a zero or positive number in second. If interval is a non-zero positive number, the Logger skips logging if a simulation step occurs before interval second past the last logging time point. If interval is zero, the Logger logs at every simulation step.

5.3.3.9. An example usage of an EntityStub

The following example loads an EML file, and prints the value of ATP Variable in System /CELL every 10 seconds. If the value is below 1000, it stops the simulation.

Example 5-2. An ESS to check ATP level every 10 seconds

    loadModel( 'simple.eml' )
    
    ATP = createEntityStub( 'Variable:/CELL:ATP' )
    
  5 while 1:
    
        ATPValue = ATP[ 'Value' ]
    
        message( 'ATP value = %s' % ATPValue )
 10 
        if ATPValue <= 1000:
            break
    
        run( 10 )
 15 
    message( 'Stopped at %s.' % getCurrentTime() )