Difference between revisions of "Team:EPF Lausanne/Software"

Line 358: Line 358:
 
         <h2>ODE Solver</h2>
 
         <h2>ODE Solver</h2>
  
         <p>The Python class Solver simplify the solution of a given system of non-linear ODEs. The user has to provide the function representing the system, the desired integration domain, the initial condition and the time step. The class takes care of solving the system and returns the solution at given time points and the time points themselves (ready to analyze/plot). </p>
+
         <p>The Python class Solver simplify the solution of a given system of non-linear ODEs. The user has to provide the function representing the system, the desired integration domain, the initial condition and the time step. The class takes care of solving the system and returns the solution at given time points and the time points themselves (ready to analyze/plot).</p>
  
 
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
 
<div class="highlight"><pre><span class="kn">import</span> <span class="nn">numpy</span> <span class="kn">as</span> <span class="nn">np</span>
Line 457: Line 457:
 
       </center>
 
       </center>
  
 +
      <p>The Solver class has been tested extensively. In the following lines we can find a test function of biological interest: three chemical species interconverting between one another, with two fast and a slow step [1]. </p>
  
 +
      <p>In this example the system of ODEs is coded in two ways: it is written directly as a Python function or the Python function is compiled from a string. This second method is very useful for us, because the ODE Generator output the ODE function as a string, that has to be compiled into a Python function. </p>
 +
 +
<div class="highlight"><pre><span class="sd">&quot;&quot;&quot;</span>
 +
<span class="sd">Test functions for the ODE solver</span>
 +
<span class="sd">&quot;&quot;&quot;</span>
 +
 +
<span class="k">def</span> <span class="nf">rapid_equilibrium</span><span class="p">(</span><span class="n">t</span><span class="p">,</span><span class="n">y</span><span class="p">,</span><span class="n">k</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span><span class="n">eps</span><span class="o">=</span><span class="mf">0.01</span><span class="p">):</span>
 +
    <span class="sd">&quot;&quot;&quot;</span>
 +
<span class="sd">    Three chemical species interconverting between one another, with two fast and a slow step.</span>
 +
 +
<span class="sd">    Example inspired from:</span>
 +
 +
<span class="sd">        R. Phillips et al., Physical Biology of the Cell, Second Edition, Garland Science, 2013.</span>
 +
<span class="sd">    &quot;&quot;&quot;</span>
 +
    <span class="n">dy</span> <span class="o">=</span> <span class="p">[]</span>
 +
 +
    <span class="n">dy</span><span class="o">.</span><span class="n">append</span><span class="p">(</span> <span class="o">-</span><span class="n">k</span><span class="o">*</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">)</span>
 +
    <span class="n">dy</span><span class="o">.</span><span class="n">append</span><span class="p">(</span> <span class="n">k</span><span class="o">*</span><span class="n">y</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="p">(</span><span class="mi">1</span> <span class="o">+</span> <span class="n">eps</span><span class="p">)</span><span class="o">*</span><span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">)</span>
 +
    <span class="n">dy</span><span class="o">.</span><span class="n">append</span><span class="p">(</span> <span class="n">eps</span><span class="o">*</span><span class="n">y</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="p">)</span>
 +
 +
    <span class="k">return</span> <span class="n">dy</span>
 +
 +
<span class="k">def</span> <span class="nf">rapid_equilibrium_from_string</span><span class="p">():</span>
 +
    <span class="sd">&quot;&quot;&quot;</span>
 +
<span class="sd">    Three chemical species interconverting between one another, with two fast and a slow step.</span>
 +
 +
<span class="sd">    Example inspired from:</span>
 +
 +
<span class="sd">        R. Phillips et al., Physical Biology of the Cell, Second Edition, Garland Science, 2013.</span>
 +
 +
<span class="sd">    System of ODEs compiled from a string.</span>
 +
<span class="sd">    &quot;&quot;&quot;</span>
 +
 +
    <span class="c"># Creation of the string coding a Python function</span>
 +
    <span class="n">ode</span> <span class="o">=</span> <span class="s">&quot;def rapid_equilibrium_fs(t,y,k=1,eps=0.01):</span><span class="se">\n</span><span class="s">&quot;</span>
 +
    <span class="n">ode</span> <span class="o">+=</span> <span class="s">&quot;    dy = []</span><span class="se">\n</span><span class="s">&quot;</span>
 +
    <span class="n">ode</span> <span class="o">+=</span> <span class="s">&quot;    dy.append( -k*y[0] + y[1] )</span><span class="se">\n</span><span class="s">&quot;</span>
 +
    <span class="n">ode</span> <span class="o">+=</span> <span class="s">&quot;    dy.append( k*y[0] - (1 + eps)*y[1] )</span><span class="se">\n</span><span class="s">&quot;</span>
 +
    <span class="n">ode</span> <span class="o">+=</span> <span class="s">&quot;    dy.append( eps*y[1] )</span><span class="se">\n</span><span class="s">&quot;</span>
 +
    <span class="n">ode</span> <span class="o">+=</span> <span class="s">&quot;    return dy&quot;</span>
 +
 +
    <span class="c"># Compiling a string into a real Python function</span>
 +
    <span class="n">code</span> <span class="o">=</span> <span class="nb">compile</span><span class="p">(</span><span class="n">ode</span><span class="p">,</span><span class="s">&#39;string&#39;</span><span class="p">,</span><span class="s">&#39;exec&#39;</span><span class="p">)</span>
 +
 +
    <span class="c"># Execute the compiled code, in order to make the function available</span>
 +
    <span class="k">exec</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
 +
 +
    <span class="k">return</span> <span class="n">rapid_equilibrium_fs</span>
 +
</pre></div>
 +
 +
 +
 +
      <p>[1] R. Phillips et al., Physical Biology of the Cell, Second Edition, Garland Science, 2013.</p>
  
 
       </div>
 
       </div>

Revision as of 11:26, 25 August 2015

EPFL 2015 iGEM bioLogic Logic Orthogonal gRNA Implemented Circuits EPFL 2015 iGEM bioLogic Logic Orthogonal gRNA Implemented Circuits

Software

Name Description
code2html Script creating automatically HTML and CSS code from source files in Python, C++ or BASH. Download
ODEs Generator Program generating automatically the ODEs governing our system from the circuit structure.
ODEs Solver Class solving a system of non-linear ODEs given the initial condition. Download

code2html

The following Python script allows to generate HTML (and CSS) code from source files in C++ and Python languages. It is based on Pygment, a Python syntax highlighter. All code in our Wiki is formatted using this script.

This script accepts two command line arguments: the first argument is the name of the file to convert, the second one (optional) is to ask separate HTML and CSS files.

The style is hard coded, but it can be changed easily by modifying the style string. Pygment documentation lists available themes and explains how to create new ones.

"""
Command:

######################################

    python code2html INPUTFILE [CSS]

######################################

INPUTFILE: name (with path) of the file to convert to html
CSS: write "true" (ot "t", "yes", "y") in order to obtain separate .html and .css files ("false" by default)
"""

from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.lexers import CppLexer
from pygments.lexers import BashLexer
from pygments.formatters import HtmlFormatter

# Code formatting style
style = "monokai"

# C++ extensions
cpp = ["cpp","cxx","cc","h"]

# Python extensions
py = ["py"]

# Bash extensions
bash = ["sh","bash"]

def load_file_as_sting(fname):
    """
    Open the file FNAME and save all its content in an unformatted string
    """

    content = ""

    with open(fname,'r') as f: # Open the file (read only)
        content = f.read() # Read file and store it in an unformatted string
        # The file is automatically closed

    return content

def save_string_as_file(fname,string):
    """
    Save the unformatted string STRING into the file FNAME
    """

    with open(fname,'w') as f: # Open the file (write only)
        f.write(string)
        # The file is automatically closed

def lexer_formatter(language,css=False):
    """
    Return the lexer for the appropriate language and the HTML formatter
    """

    L = None

    if language in py:
        # Python Lexer
        L = PythonLexer()

    elif language in cpp:
        # C++ Lexer
        L = CppLexer()

    elif language in bash:
        # Bash Lexer
        L = BashLexer()

    else:
        raise NameError("Invalid language.")

    HF = HtmlFormatter(full=not css,style=style)

    return L, HF


def code_to_htmlcss(code,language):
    """
    Transform CODE into html and css (separate files)
    """

    # Obtain lexer and HtmlFormatter
    L, HF = lexer_formatter(language,css=True)

    # Create html code
    html = highlight(code,L,HF)

    # Create css code
    css = HF.get_style_defs('.highlight')

    return html,css

def code_to_html(code,language):
    """
    Transform CODE into html and css (all in the same file)
    """

    # Obtain lexer and HtmlFormatter
    L, HF = lexer_formatter(language)

    # Create fill html code
    html = highlight(code,L,HF)

    return html

import sys

if __name__ == "__main__":
    """
    Command:

    ######################################

        python code2html INPUTFILE [CSS]

    ######################################

    INPUTFILE: name (with path) of the file to convert to html
    CSS: write "true" (ot "t", "yes", "y") in order to obtain separate .html and .css files ("false" by default)
    """

    # Command line arguments
    args = sys.argv

    # Check command line arguments
    ncla = len(args) # number of command line arguments

    if ncla != 2 and ncla != 3 :
        raise TypeError("Invalid number of command line arguments.")

    css_bool = False

    if ncla == 3 and args[-1].lower() in ["true",'t',"yes",'y']:
        css_bool = True # Export css separately

    # Input file
    fname_code = sys.argv[1] # Name of the file containing the code to convert in html

    # Input file extension
    language = fname_code.split('.')[-1]

    # Output files
    fname_html = fname_code.split('.')[0] + ".html" # Name of the file where the html code will be stored
    fname_css = fname_code.split('.')[0] + ".css" # Name of the file where the css code will be stored

    # Save code into a unformatted string
    code = load_file_as_sting(fname_code)

    if css_bool == False: # Convert to standalone html
        html = code_to_html(code,language)
    else: # Convert to html and css separately
        html,css = code_to_htmlcss(code,language)

    # Save html
    save_string_as_file(fname_html,html)

    if css_bool == True:
        # Save css
        save_string_as_file(fname_css,css)

ODE Generator

ODE Solver

The Python class Solver simplify the solution of a given system of non-linear ODEs. The user has to provide the function representing the system, the desired integration domain, the initial condition and the time step. The class takes care of solving the system and returns the solution at given time points and the time points themselves (ready to analyze/plot).

import numpy as np
from scipy.integrate import *
import matplotlib.pylab as plt

class Solver:
    """
    Class that allows the solution of a system of non-linear ODEs. The system is specified by the function fun

        dy/dt = fun(t,y)

    where t is a number and y and dy/dt are numpy arrays or lists.

    The solution is performed with the dopri5 method, an explicit runge-kutta method of order (4)5.
    The method is due to Dormand & Prince, and is implemented by E. Hairer and G. Wanner.

    See
        http://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.integrate.ode.html
    for more details.

    NOTE:
    Our Solver need a function of the type fun(t,y).
    In cases where the fun takes additional arguments funArgs(t,y,arg1,...) it is possible to create an alias:

        fun = lambda t,y: funArgs(t,y,arg1,...)

    The additional arguments are now contained in the alias and fun is of the type fun(t,y).
    """

    def __init__(self,dt,fun,t0,T,y0):
        self.dt = dt # Time step
        self.fun = fun # Function representing the ODE
        self.t0 = t0 # Initial time
        self.T = T # Final time
        self.y0 = y0 # Initial condition

    def solve(self):
        """
        Solve the system of ODEs

            dy/dt = fun(t,y)

        on the interval [t0,T], with the initial condition y(0)=y0.

        Returns two lists, solution and time, containing time points and the solution at these time points.
        """

        # Choose integrator type: dopri5 in this case
        r = ode(self.fun).set_integrator('dopri5')

        # Initialize the integrator
        r.set_initial_value(self.y0, self.t0)

        # Initialize solution list and time points list
        solution = np.asarray(self.y0)
        time = np.asarray(self.t0)

        while r.successful() and r.t < self.T:
            r.integrate(r.t + self.dt) # Perform one integration step, i.e. obtain the solution y at time t+dt

            time = np.append(time,r.t) # Append the new time
            solution = np.vstack((solution,r.y)) # Append the new solution

        return time, solution # Return time and solution vectors

if __name__ == "__main__":
    from test import * # Import test functions for the ODE integrator

    # Our test functions:
    #   rapid_equilibrium (standard function)
    #   rapid_equilibrium_from_string() (returns a function compiled from a string)

    dt = 0.1

    t0 = 0
    T = 100
    y0 = [1,0,0]

    # Store the compiled function
    rapid_equilibrium_s = rapid_equilibrium_from_string()

    mysolver = Solver(dt,rapid_equilibrium,t0,T,y0)
    mysolver_string = Solver(dt,rapid_equilibrium_s,t0,T,y0)

    t,y = mysolver.solve()
    ts,ys = mysolver_string.solve()

    plt.plot(t,y)
    plt.plot(ts,ys)
    plt.show()

The Solver class has been tested extensively. In the following lines we can find a test function of biological interest: three chemical species interconverting between one another, with two fast and a slow step [1].

In this example the system of ODEs is coded in two ways: it is written directly as a Python function or the Python function is compiled from a string. This second method is very useful for us, because the ODE Generator output the ODE function as a string, that has to be compiled into a Python function.

"""
Test functions for the ODE solver
"""

def rapid_equilibrium(t,y,k=1,eps=0.01):
    """
    Three chemical species interconverting between one another, with two fast and a slow step.

    Example inspired from:

        R. Phillips et al., Physical Biology of the Cell, Second Edition, Garland Science, 2013.
    """
    dy = []

    dy.append( -k*y[0] + y[1] )
    dy.append( k*y[0] - (1 + eps)*y[1] )
    dy.append( eps*y[1] )

    return dy

def rapid_equilibrium_from_string():
    """
    Three chemical species interconverting between one another, with two fast and a slow step.

    Example inspired from:

        R. Phillips et al., Physical Biology of the Cell, Second Edition, Garland Science, 2013.

    System of ODEs compiled from a string.
    """

    # Creation of the string coding a Python function
    ode = "def rapid_equilibrium_fs(t,y,k=1,eps=0.01):\n"
    ode += "    dy = []\n"
    ode += "    dy.append( -k*y[0] + y[1] )\n"
    ode += "    dy.append( k*y[0] - (1 + eps)*y[1] )\n"
    ode += "    dy.append( eps*y[1] )\n"
    ode += "    return dy"

    # Compiling a string into a real Python function
    code = compile(ode,'string','exec')

    # Execute the compiled code, in order to make the function available
    exec(code)

    return rapid_equilibrium_fs

[1] R. Phillips et al., Physical Biology of the Cell, Second Edition, Garland Science, 2013.

EPFL 2015 iGEM bioLogic Logic Orthogonal gRNA Implemented Circuits

NOT PROOFREAD