Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions gillespy/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
from .gillespy import *
import os
os.environ["PATH"] += os.pathsep + "/usr/local/stochss/StochKit/"
os.environ["PATH"] += os.pathsep + "/usr/local/stochss/ode/"
83 changes: 55 additions & 28 deletions gillespy/gillespy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
import matplotlib.pyplot as plt
import tempfile
import uuid
import subprocess
import subprocess32 as subprocess
import types
import random
import os
import signal
import psutil

try:
import lxml.etree as etree
Expand Down Expand Up @@ -239,14 +242,14 @@ def delete_reaction(self, obj):
def delete_all_reactions(self):
self.listOfReactions.clear()

def run(self, number_of_trajectories=1, seed=None, report_level=0, solver=None, stochkit_home=None, debug=False):
def run(self, number_of_trajectories=1, seed=None, report_level=0, solver=None, stochkit_home=None, debug=False,timeout=None):
if solver is not None:
if isinstance(solver, (type, types.ClassType)) and issubclass(solver, GillesPySolver):
return solver.run(self,t=self.tspan[-1],increment=self.tspan[-1]-self.tspan[-2],seed=seed,number_of_trajectories=number_of_trajectories, stochkit_home=stochkit_home, debug=debug)
return solver.run(self,t=self.tspan[-1],increment=self.tspan[-1]-self.tspan[-2],seed=seed,number_of_trajectories=number_of_trajectories, stochkit_home=stochkit_home, debug=debug,timeout=timeout)
else:
raise SimuliationError('argument "solver" to run() must be a subclass of GillesPySolver')
else:
return StochKitSolver.run(self,t=self.tspan[-1],increment=self.tspan[-1]-self.tspan[-2],seed=seed,number_of_trajectories=number_of_trajectories, stochkit_home=stochkit_home, debug=debug)
return StochKitSolver.run(self,t=self.tspan[-1],increment=self.tspan[-1]-self.tspan[-2],seed=seed,number_of_trajectories=number_of_trajectories, stochkit_home=stochkit_home, debug=debug,timeout=timeout)


class Species():
Expand Down Expand Up @@ -318,7 +321,7 @@ class Reaction():
"""

def __init__(self, name = "", reactants = {}, products = {},
propensity_function = None, massaction = False,
propensity_function = None, massaction = True,
rate=None, annotation=None):
"""
Initializes the reaction using short-hand notation.
Expand All @@ -343,8 +346,8 @@ def __init__(self, name = "", reactants = {}, products = {},
self.name = name
self.annotation = ""

if rate is None and propensity_function is None:
raise ReactionError("You must specify either a mass-action rate or a propensity function")
#if rate is None and propensity_function is None:
# raise ReactionError("You must specify either a mass-action rate or a propensity function")

# We might use this flag in the future to automatically generate
# the propensity function if set to True.
Expand Down Expand Up @@ -378,10 +381,12 @@ def __init__(self, name = "", reactants = {}, products = {},
if self.massaction:
self.type = "mass-action"
if rate is None:
raise ReactionError("Reaction : A mass-action propensity has\
to have a rate.")
self.marate = rate
self.create_mass_action()
self.marate=None
# raise ReactionError("Reaction : A mass-action propensity has\
# to have a rate.")
else:
self.marate = rate
self.create_mass_action()
else:
self.type = "customized"

Expand Down Expand Up @@ -642,6 +647,9 @@ def to_model(self,name):
type = reac.find('Type').text
except:
raise InvalidStochMLError("No reaction type specified.")

#reaction = Reaction(name,{},{},None,False,0.0,None)


reactants = reac.find('Reactants')
try:
Expand Down Expand Up @@ -820,7 +828,7 @@ class GillesPySolver():

def run(self, model, t=20, number_of_trajectories=1,
increment=0.05, seed=None, stochkit_home=None, algorithm=None,
job_id=None, extra_args='', debug=False):
job_id=None, extra_args='', debug=False,timeout=None):
"""
Call out and run the solver. Collect the results.
"""
Expand Down Expand Up @@ -873,6 +881,7 @@ def run(self, model, t=20, number_of_trajectories=1,
algorithm)):
executable = os.path.join(os.environ.get('STOCHKIT_HOME'),
algorithm)

if executable is None:
# try to find the executable in the path
if os.environ.get('PATH') is not None:
Expand Down Expand Up @@ -910,22 +919,37 @@ def run(self, model, t=20, number_of_trajectories=1,
print "cmd: {0}".format(cmd)

# Execute
try:
#try:
#print "CMD: {0}".format(cmd)
handle = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
return_code = handle.wait()
except OSError as e:
raise SimuliationError("Solver execution failed: \
{0}\n{1}".format(cmd, e))

#handle = subprocess.Popen(cmd, stdout = subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
handle = subprocess.Popen(cmd,shell=True, preexec_fn=os.setsid)
#return_code = handle.wait()
try:
stderr = handle.stderr.read()
except Exception as e:
stderr = 'Error reading stderr: {0}'.format(e)
try:
stdout = handle.stdout.read()
except Exception as e:
stdout = 'Error reading stdout: {0}'.format(e)
outs, errs = handle.communicate(timeout=timeout)
return_code = 0
except subprocess.TimeoutExpired:
#os.killpg(os.getpgid(handle.pid),signal.SIGTERM)
#print os.getpgid(handle.pid)
parent = psutil.Process(handle.pid)
for child in parent.children(recursive=True): # or parent.children() for recursive=False
child.kill()
handle.kill()
outs, errs = handle.communicate(timeout=timeout)
return_code=-1
raise SolverTimeoutError("Solver timed out")

#except OSError as e:
# raise SimuliationError("Solver execution failed: \
# {0}\n{1}".format(cmd, e))

#try:
# stderr = handle.stderr.read()
#except Exception as e:
# stderr = 'Error reading stderr: {0}'.format(e)
#try:
# stdout = handle.stdout.read()
#except Exception as e:
# stdout = 'Error reading stdout: {0}'.format(e)

if return_code != 0:
#print stdout
Expand Down Expand Up @@ -961,7 +985,7 @@ class StochKitSolver(GillesPySolver):
@classmethod
def run(cls, model, t=20, number_of_trajectories=1,
increment=0.05, seed=None, stochkit_home=None, algorithm='ssa',
job_id=None, method=None,debug=False):
job_id=None, method=None,debug=False,timeout=None):

# all this is specific to StochKit
if model.units == "concentration":
Expand Down Expand Up @@ -993,7 +1017,7 @@ def run(cls, model, t=20, number_of_trajectories=1,


self = StochKitSolver()
return GillesPySolver.run(self, model,t, number_of_trajectories, increment, seed, stochkit_home, algorithm, job_id, extra_args=args, debug=debug)
return GillesPySolver.run(self, model,t, number_of_trajectories, increment, seed, stochkit_home, algorithm, job_id, extra_args=args, debug=debug,timeout=timeout)

def get_trajectories(self, outdir, debug=False):
# Collect all the output data
Expand Down Expand Up @@ -1048,6 +1072,9 @@ class InvalidStochMLError(Exception):
class InvalidModelError(Exception):
pass

class SolverTimeoutError(Exception):
pass

class SimulationError(Exception):
pass

Expand Down