GENESIS: Documentation

Related Documentation:

Python Primer

Introduction

Python is a dynamic programming language that started from conception in the 80’s. It boasts a clean readable syntax, support for several programming paradigms, high level of extensibility, and a huge standard library. The high extensibility of the language has allowed Python to spread into several areas of computing such as web development, scientific computing, and enterprise application development. Thanks to its readability, Python is an excellent language for beginning programmers, but it’s still powerful enough for just about any task. Thanks to the small learning curve, Python has gained a large community of developers. The Python community is different from other communities in that they see ”right” and ”wrong” ways to code solutions to certain problems, and how certain features are to be used.

Extensibility

One of the main motivations behind creating a scripting language layer for a software library, is to take advantage of all of the resources of that scripting language. Python boasts arguably the largest and most diverse collection of modules of any scripting language. Python is able to interface with many languages such as C, C++, and Java; thus it can provide a scripting layer to any software libraries written in a compatible language. The core of the major components for GENESIS3: the model container, heccer, chemesis 3, and experiment protocols, are written in C. An abstraction layer encapsulates the functional aspects of the C code, which makes the Python representation take advantage of an object oriented approach. Available python packages for G3 are:

Many other software tools have Python modules that allow you to interface with them via their API such as the aforementioned wxPython (based on wxWidgets written in C++), PyQT (based on Qt written in C++), PyYaml, SciPy, NumPy, and Matplotlib. Thanks to G3 having a presence in this scripting format, it’s possible to interface with any python module available.

Packaging

Python and it’s modules are extremely portable. A Python interpreter can be embedded into other programs and has given interpretive capabilities to large software packages such as Blender, GIMP, and Abaqus. Library modules can also be distributed as Python ’eggs’, which are zipped library files that can be placed in the Python executables library paths; allowing you to import them and use them in your own scripts. An egg built for Python 2.6 can be imported and run on any matching version for the same operating system.

An online repository of Python eggs known as PyPi, the Python Package Index, allows users to create modules and upload them for others to download and install with a single command.

Structure

Off-side rule

Unlike most languages Python does not use brackets or any sort of paired delimiter to indicate the start and end of a block of code. Python uses indentation, otherwise known as the ”off-side rule.” A definition such as a function declaration defines it’s scope as everything that is indented once following it and scope ends when it encounters a line that is at the same indentation level as the definition.

The following is a function simple definition:

 
def my_function(i):  
 
  print "The number I have is %i" % i  
 
print "Hello!"  

The line of code that prints ”Hello!” is not part of the function definition since it is now out of scope.

Here is an example of a loop:

 
for i in range(0,100):  
 
  print "%i" % i  
 
print "Done!"

Again,the first print statement will print every value between 0 and 100, but the final line that prints out ”Done!” will not print since it is out of scope of the loop.

Functions

Functions, as shown before can be declared with the ’def’ declaration, a parameter list, and everything indented in its scope. Here’s an example:

 
def max(value1, value2):  
 
  if value1 == value2:  
 
    return "they’re equal"  
 
  elif value1 > value2:  
 
    return value1  
 
  elif value2 > value1:  
 
    return value2  
 
print "Max between 4 and 4 is ’%s’" % max(4, 4)  
print "Max between 10 and 2 is ’%s’" % max(10, 2)  
print "Max between 60 and 3000 is ’%s’" % max(60, 3000)  

The output of the script is:

Max between 4 and 4 is ’they’re equal’  
Max between 10 and 2 is ’10’  
Max between 60 and 3000 is ’3000’

Classes

Classes in python allow you to create objects that encapsule complex operations. To create a class it’s very simple:

 
 
class MyObject:  
 
  # my constructor  
 
  def __init__(self, value):  
 
    self.my_value = value  
 
  def get_value(self):  
 
    return self.my_value  
 
 
my_obj = MyObject(100)  
 
print "The value of my object is %s" % my_obj.get_value()  

The output of the program is: ”The value of my object is 100”

Inheritence

Like most object oriented languages, Python allows you to inherit a class. Inheriting is very simple, taking the simple object from the previous example:

 
class MyObject:  
 
  # constructor  
 
  def __init__(self, value):  
 
    self.my_value = value  
 
  def get_value(self):  
 
    return self.my_value  
 
 
class MyChildObject(MyObject):  
 
  # constructor  
 
  def __init__(self, value, value2):  
 
    MyObject.__init__(self, value)  
 
    self.value2 = value2  
 
  def get_value_2(self):  
 
    return self.value2  
 
 
my_obj = MyChildObject(20, 50)  
 
print "Value 1 is %s" % my_obj.get_value()  
print "Value 2 is %s" % my_obj.get_value_2()  
 
 

The output of the program is:

Value 1 is 20  
Value 2 is 50

Common Data Types

Strings

Strings in Python are objects, and have accompanying methods like the previous objects shown do.

Here’s some examples of string manipulation:

 
my_string = "  This is my string!  "  
 
print "The string is ’%s’" % my_string.rstrip()  
 
print "The string is ’%s’" % my_string.lstrip()  
 
print "The string is ’%s’" % my_string.replace(’my’, ’the’)  
 
string_parts = my_string.split()  
 
print "String parts are: ’%s’" % ’, ’.join(string_parts)  

The output from this script is:

The string is ’  This is my string!’  
The string is ’This is my string!  ’  
The string is ’  This is the string!  ’  
String parts are: ’This, is, my, string!’

Strings can also be concatenated via the ’+’ operator or using a join like the previous example:

string1 = "This is "  
 
string2 = "my string"  
 
string3 = string1 + string2  
 
print string3  
 
print ’’.join([string1, string2])

The output from this script is:

This is my string  
This is my string

Lists

Lists are arrays of objects, they are used to store consecutive sequences of data. GENESIS3, and many other pieces of scientific computing software output data lists for analysis in the form of a python list.

 
my_list = ["one", "two", "three"]  
 
print "There are %s items in this list" % len(my_list)  
for l in my_list:  
 
  print "%s" % l  
 
my_list.append("four")  
 
print "\nThere are now %s items in this list" % len(my_list)  
for l in my_list:  
 
  print "%s" % l  
 
print "\nThe third element is %s\n" % my_list[2]  
 
print "The elements and their indexes are"  
 
for i, l in enumerate(my_list):  
 
  print "’%s’ is at position ’%i’" % (l,i)  

The output for the script is:

There are 3 items in this list  
one  
two  
three  
 
There are now 4 items in this list  
one  
two  
three  
four  
 
The third element is three  
 
The elements and their indexes are  
’one’ is at position ’0’  
’two’ is at position ’1’  
’three’ is at position ’2’  
’four’ is at position ’3’  

Dictionaries

A dictionary is a relational data structure that allows you to use keywords to hash to values. GENESIS3 uses some dict structures for input formats.

 
 
my_dict = { ’key1’ : 100, ’key2’ : 500, ’key3’ : 10}  
 
print "The keys are: "  
 
 
 
for k in my_dict.keys():  
 
    print "key ’%s’ holds value ’%s’" % (k, my_dict[k])  
 
print "\n"  
 
 
my_dict[’key4’] = 600  
 
for k in my_dict.keys():  
 
    print "key ’%s’ holds value ’%s’" % (k, my_dict[k])  
 
print "\n"  
 
 
print "Removing the entry at ’key2’\n"  
 
my_dict.pop(’key2’)  
 
for k in my_dict.keys():  
 
    print "key ’%s’ holds value ’%s’" % (k, my_dict[k])  
 
print "\n"  
 
if my_dict.has_key(’key3’):  
 
    print "An entry with ’key3’ is present"  

Quick Examples

Running a simple simulation in sspy

GENESIS3 has a scheduler in Python called SSPy (simple scheduler in python), that is used to drive simulations and allow the user to interface with Python. Below is an example

from sspy import SSPy  
 
 
scheduler = SSPy(verbose=True)  
 
my_model_container = None  
#  
# Create a model container service and load an ndf file  
#  
 
my_model_container = scheduler.CreateService(name="My Model Container",  
                                             type="model_container",  
                                             verbose=True)  
 
my_model_container.Load(’tests/cells/purk_test.ndf’)  
 
my_model_container.SetParameter(’/purk_test/segments/soma’,  
                                ’INJECT’,  
                                2e-09)  
 
#  
# Must create solver.  
#  
my_heccer = scheduler.CreateSolver(’My solver’, ’heccer’, verbose=True)  
 
# Sets the segment of the model to run from  
my_heccer.SetModelName(’/purk_test’)  
 
# set the timestep for the entire scheduler (solvers, inputs and outputs)  
my_heccer.SetTimeStep(2e-05)  
 
 
#  
# Create Outputs  
#  
my_output = scheduler.CreateOutput(’My output object’, ’live_output’)  
 
my_output.AddOutput(’/purk_test/segments/soma’, ’Vm’)  
my_output.AddOutput(’/purk_test/segments/soma/ca_pool’, ’Ca’)  
 
scheduler.Run(steps=2500, finish=True)  
 
output_data = my_output.GetData()  
 
# you can put some sort of data manipulation here for the output_data  
 
print "Data at step 1, time ’%f’ is %s" % (output_data[1][0], ’,’.join(map(str, output_data[1][1:])))  
 
print "Done!"

At the end of this simulation, the ’my_output’ object holds a python list with all of the data from the simulation that can be obtained via its GetData() method and can be used to feed data into plotters, spreadsheets, and other analysis tools.