Skip to content

Commit

Permalink
Merge pull request #1139 from StochSS/gillespy2-160-release
Browse files Browse the repository at this point in the history
Gillespy2 v1.6.3 release
  • Loading branch information
seanebum authored Jul 23, 2021
2 parents 6068e51 + 41fc3b5 commit d548031
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 217 deletions.
2 changes: 1 addition & 1 deletion public_models/3D_Cylinder/3D_cylinder.smdl

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
python-libsbml==5.18.0
python-libsedml==2.0.9
python-libcombine==0.2.7
gillespy2==1.5.11
gillespy2==1.6.3
sciope==0.4
pygmsh==5.0.2
meshio==2.3.10
Expand Down
2 changes: 1 addition & 1 deletion stochss/handlers/util/stochss_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ def __create_reaction_strings(self, model, pad):
if reac['reactionType'] == 'custom-propensity':
reac_str += f'propensity_function="{reac["propensity"]}")'
else:
reac_str += f'rate=self.listOfParameters["{reac["rate"]["name"]}"])'
reac_str += f'rate="{reac["rate"]["name"]}")'
if not self.s_model['is_spatial']:
reac_str += ")"
reactions.append(reac_str)
Expand Down
218 changes: 4 additions & 214 deletions stochss/handlers/util/stochss_sbml.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
import traceback

from gillespy2.sbml.SBMLimport import convert
from gillespy2.sbml.SBMLimport import __read_sbml_model as _read_sbml_model
from gillespy2.sbml.SBMLimport import __get_math as _get_math
from gillespy2.stochss.StochSSexport import export

from .stochss_base import StochSSBase
from .stochss_errors import StochSSFileNotFoundError
Expand Down Expand Up @@ -57,205 +56,6 @@ def __init__(self, path, new=False, document=None):
sbml_file.write(document)


@classmethod
def __build_element(cls, stoich_species):
if not stoich_species:
return "\\emptyset"

elements = []
for species in stoich_species:
name = species['specie']['name']
ratio = species['ratio']
element = f"{ratio}{name}" if ratio > 1 else name
elements.append(element)
return '+'.join(elements)


@classmethod
def __convert_assignments(cls, model, event, assignments):
for assignment in assignments:
name = assignment.variable.name
try:
variable = cls.__get_species(species=model['species'], name=name)
except IndexError:
variable = cls.__get_parameter(parameters=model['parameters'], name=name)

s_assignment = {"variable": variable,
"expression": assignment.expression}
event['eventAssignments'].append(s_assignment)


@classmethod
def __convert_events(cls, model, events):
for name, event in events.items():
s_event = {"compID":model['defaultID'],
"name": name,
"annotation": "",
"delay": event.delay,
"priority": event.priority,
"triggerExpression": event.trigger.expression,
"initialValue": event.trigger.value,
"persistent": event.trigger.persistent,
"useValuesFromTriggerTime": event.use_values_from_trigger_time,
"eventAssignments": []}

cls.__convert_assignments(model=model, event=s_event, assignments=event.assignments)

model['eventsCollection'].append(s_event)
model['defaultID'] += 1


@classmethod
def __convert_function_definition(cls, model, function_definitions):
for function_definition in function_definitions:
name = function_definition["name"]
variables = ', '.join(function_definition["args"])
expression = function_definition["function"]
function = "lambda({0}, {1})".format(variables, expression)
signature = "{0}({1})".format(name, variables)

s_function_definition = {"compID":model['defaultID'],
"name":name,
"function":function,
"expression":expression,
"variables":variables,
"signature":signature,
"annotation": ""}
model['functionDefinitions'].append(s_function_definition)
model['defaultID'] += 1


@classmethod
def __convert_parameters(cls, model, parameters):
for name, parameter in parameters.items():
s_parameter = {"compID":model['defaultID'],
"name":name,
"expression":str(parameter.expression),
"annotation": ""}
model['parameters'].append(s_parameter)
model['defaultID'] += 1


@classmethod
def __convert_stoich_species(cls, s_reaction, reaction, key, species):
source = reaction.reactants if key == "reactants" else reaction.products
for specie, ratio in source.items():
stoich_species = {"ratio":ratio,
"specie":cls.__get_species(species=species, name=specie.name)}
s_reaction[key].append(stoich_species)


@classmethod
def __convert_reactions(cls, model, reactions):
for name, reaction in reactions.items():
s_reaction = {"compID":model['defaultID'],
"name":name,
"reactionType": "custom-propensity",
"massaction": False,
"propensity": reaction.propensity_function,
"annotation": "",
"rate": {},
"subdomains": [
"subdomain 1: ",
"subdomain 2: "
],
"reactants": [],
"products": []}

for key in ['reactants', 'products']:
cls.__convert_stoich_species(s_reaction=s_reaction, reaction=reaction,
key=key, species=model['species'])
cls.__get_summary(reaction=s_reaction)

model['reactions'].append(s_reaction)
model['defaultID'] += 1


@classmethod
def __convert_rules(cls, model, r_type, rules):
for name, rule in rules.items():
try:
variable = cls.__get_species(species=model['species'], name=rule.variable)
except IndexError:
variable = cls.__get_parameter(parameters=model['parameters'], name=rule.variable)

s_rule = {"compID":model['defaultID'],
"name":name,
"expression":rule.formula,
"type":r_type,
"variable":variable,
"annotation": ""}
model['rules'].append(s_rule)
model['defaultID'] += 1


@classmethod
def __convert_species(cls, model, species):
mode = "dynamic"

# Get the model for all species
for _, specie in species.items():
if specie.mode != mode:
mode = "continuous"
break

for name, specie in species.items():
s_species = {"compID":model['defaultID'],
"name":name,
"value":specie.initial_value,
"mode":mode,
"switchTol": 0.03,
"switchMin": 100,
"isSwitchTol": True,
"annotation": "",
"diffusionConst":0,
"subdomains": [
"subdomain 1: ",
"subdomain 2: "
]}
model['species'].append(s_species)
model['defaultID'] += 1

model['defaultMode'] = mode


def __get_function_definitions(self):
path = self.get_path(full=True)
sb_model = _read_sbml_model(path)[0]
function_definitions = []

for i in range(sb_model.getNumFunctionDefinitions()):
function = sb_model.getFunctionDefinition(i)
function_name = function.getId()
function_tree = function.getMath()
num_nodes = function_tree.getNumChildren()
function_args = [function_tree.getChild(i).getName() for i in range(num_nodes-1)]
function_string = _get_math(function_tree.getChild(num_nodes-1))
s_function_definition = {"name":function_name,
"function":function_string,
"args":function_args}
function_definitions.append(s_function_definition)

return function_definitions


@classmethod
def __get_parameter(cls, parameters, name):
return list(filter(lambda parameter: parameter['name'] == name, parameters))[0]


@classmethod
def __get_summary(cls, reaction):
r_summary = cls.__build_element(reaction['reactants'])
p_summary = cls.__build_element(reaction['products'])
reaction['summary'] = f"{r_summary} \\rightarrow {p_summary}"


@classmethod
def __get_species(cls, species, name):
return list(filter(lambda specie: specie['name'] == name, species))[0]


def convert_to_gillespy(self):
'''
Convert the sbml model to a gillespy model and return it
Expand All @@ -282,14 +82,14 @@ def convert_to_model(self, name=None, wkgp=False):
Attributes
----------
'''
s_model = self.get_model_template() # StochSS Model in json format
self.log("debug", f"Model template: \n{json.dumps(s_model)}")

g_model, errors = self.convert_to_gillespy() # GillesPy2 Model object
if g_model is None:
message = "ERROR! We were unable to convert the SBML Model into a StochSS Model."
return {"message":message, "errors":errors, "model":None}

s_model = export(model=g_model, return_stochss_model=True) # StochSS Model in json format
self.log("debug", f"Model: \n{json.dumps(s_model)}")

s_file = f"{g_model.name}.mdl" if name is None else f"{name}.mdl"
if wkgp:
wkgp_path, changed = self.get_unique_path(name=f"{self.get_name(path=s_file)}.wkgp",
Expand All @@ -300,15 +100,5 @@ def convert_to_model(self, name=None, wkgp=False):
else:
s_path = os.path.join(self.get_dir_name(), s_file)

self.__convert_species(model=s_model, species=g_model.get_all_species())
self.__convert_parameters(model=s_model, parameters=g_model.get_all_parameters())
self.__convert_reactions(model=s_model, reactions=g_model.get_all_reactions())
self.__convert_events(model=s_model, events=g_model.get_all_events())
self.__convert_rules(model=s_model, r_type='Rate Rule', rules=g_model.get_all_rate_rules())
self.__convert_rules(model=s_model, r_type='Assignment Rule',
rules=g_model.get_all_assignment_rules())
self.__convert_function_definition(model=s_model,
function_definitions=self.__get_function_definitions())

message = "The SBML Model was successfully converted to a StochSS Model."
return {"message":message, "errors":errors, "model":s_model, "path":s_path}

0 comments on commit d548031

Please sign in to comment.