Skip to content

Commit

Permalink
Merge pull request #190 from indralab/hackathon
Browse files Browse the repository at this point in the history
Improvements and hackathon scenario
  • Loading branch information
bgyori committed Jul 6, 2023
2 parents 82421e4 + 6b08945 commit 36994e1
Show file tree
Hide file tree
Showing 13 changed files with 1,054 additions and 16 deletions.
4 changes: 3 additions & 1 deletion mira/metamodel/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import json
import sympy
from .template_model import TemplateModel
from .template_model import TemplateModel, SympyExprStr


def model_from_json_file(fname) -> TemplateModel:
Expand Down Expand Up @@ -42,6 +42,8 @@ def expression_to_mathml(expression: sympy.Expr, *args, **kwargs) -> str:
Here we pay attention to not style underscores and numeric suffixes
in special ways.
"""
if isinstance(expression, SympyExprStr):
expression = expression.args[0]
mappings = {}
for sym in expression.atoms(sympy.Symbol):
name = '|' + str(sym).replace('_', 'QQQ') + '|'
Expand Down
18 changes: 16 additions & 2 deletions mira/metamodel/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
"description": "The name of the concept.",
"type": "string"
},
"display_name": {
"title": "Display Name",
"description": "An optional display name for the concept. If not provided, the name can be used for display purposes.",
"type": "string"
},
"description": {
"title": "Description",
"description": "An optional description of the concept.",
Expand Down Expand Up @@ -470,6 +475,11 @@
"description": "The name of the concept.",
"type": "string"
},
"display_name": {
"title": "Display Name",
"description": "An optional display name for the concept. If not provided, the name can be used for display purposes.",
"type": "string"
},
"description": {
"title": "Description",
"description": "An optional description of the concept.",
Expand Down Expand Up @@ -516,8 +526,7 @@
}
},
"required": [
"name",
"value"
"name"
]
},
"Initial": {
Expand Down Expand Up @@ -548,6 +557,11 @@
"description": "The name of the concept.",
"type": "string"
},
"display_name": {
"title": "Display Name",
"description": "An optional display name for the concept. If not provided, the name can be used for display purposes.",
"type": "string"
},
"description": {
"title": "Description",
"description": "An optional description of the concept.",
Expand Down
2 changes: 1 addition & 1 deletion mira/metamodel/template_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Distribution(BaseModel):

class Parameter(Concept):
"""A Parameter is a special type of Concept that carries a value."""
value: float = Field(
value: Optional[float] = Field(
default_factory=None, description="Value of the parameter.")

distribution: Optional[Distribution] = Field(
Expand Down
4 changes: 4 additions & 0 deletions mira/metamodel/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ class Concept(BaseModel):
"""

name: str = Field(..., description="The name of the concept.")
display_name: str = \
Field(None, description="An optional display name for the concept. "
"If not provided, the name can be used for "
"display purposes.")
description: Optional[str] = \
Field(None, description="An optional description of the concept.")
identifiers: Mapping[str, str] = Field(
Expand Down
8 changes: 4 additions & 4 deletions mira/modeling/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ def assemble_variable(
return var

def assemble_parameter(self, template: Template, tkey) -> ModelParameter:
rate_parameters = self.template_model.get_parameters_from_rate_law(
template.rate_law)
rate_parameters = sorted(
self.template_model.get_parameters_from_rate_law(template.rate_law))

if rate_parameters:
model_parameters = []
Expand All @@ -133,8 +133,8 @@ def assemble_parameter(self, template: Template, tkey) -> ModelParameter:

def make_model(self):
for name, observable in self.template_model.observables.items():
params = observable.get_parameter_names(
self.template_model.parameters)
params = sorted(
observable.get_parameter_names(self.template_model.parameters))
self.observables[observable.name] = \
ModelObservable(observable, params)
for key in params:
Expand Down
6 changes: 4 additions & 2 deletions mira/modeling/askenet/petrinet.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ def __init__(self, model: Model):
# Use the variable's concept name if possible but fall back
# on the key otherwise
vmap[key] = name = var.concept.name or str(key)
display_name = var.concept.display_name or name
# State structure
# {
# 'id': str,
Expand All @@ -63,7 +64,7 @@ def __init__(self, model: Model):
# }
states_dict = {
'id': name,
'name': name,
'name': display_name,
'grounding': {
'identifiers': {k: v for k, v in
var.concept.identifiers.items()
Expand Down Expand Up @@ -258,10 +259,11 @@ def to_json_file(self, fname, name=None, description=None,
kwargs :
Additional keyword arguments to pass to :func:`json.dump`.
"""
indent = kwargs.pop('indent', 1)
js = self.to_json(name=name, description=description,
model_version=model_version)
with open(fname, 'w') as fh:
json.dump(js, fh, **kwargs)
json.dump(js, fh, indent=indent, **kwargs)


class Initial(BaseModel):
Expand Down
7 changes: 6 additions & 1 deletion mira/sources/askenet/petrinet.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ def state_to_concept(state):
# }
# }
# }
name = state.get('name') or state['id']
# Note that in the shared representation we have id and name
# whereas for Concepts in MIRA we have names and display
# names
name = state['id']
display_name = state.get('name')
grounding = state.get('grounding', {})
identifiers = grounding.get('identifiers', {})
context = grounding.get('modifiers', {})
Expand All @@ -239,6 +243,7 @@ def state_to_concept(state):
units_expr = sympy.parse_expr(expr, local_dict=UNIT_SYMBOLS)
units_obj = Unit(expression=units_expr)
return Concept(name=name,
display_name=display_name,
identifiers=identifiers,
context=context,
units=units_obj)
Expand Down
8 changes: 8 additions & 0 deletions mira/sources/sbml/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ def _lookup_concepts_filtered(species_ids) -> List[Concept]:
product_species = [species.species for species in reaction.products]

rate_law = reaction.getKineticLaw()
# Some rate laws define parameters locally and so we need to
# extract them and add them to the global parameter list
for parameter in rate_law.parameters:
all_parameters[parameter.id] = {'value': parameter.value,
'description': parameter.name if parameter.name else None,
'units': self.get_object_units(parameter)}
parameter_symbols[clean_formula(parameter.id)] = \
sympy.Symbol(clean_formula(parameter.id))

rate_expr = sympy.parse_expr(clean_formula(rate_law.formula),
local_dict=all_locals)
Expand Down
Loading

0 comments on commit 36994e1

Please sign in to comment.