Skip to content

Commit

Permalink
Fixed issues with expressions for adding state and updated unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
nanglo123 committed Sep 12, 2023
1 parent dff4db6 commit a961483
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 28 deletions.
39 changes: 21 additions & 18 deletions mira/modeling/askenet/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,30 +178,29 @@ def remove_state(tm, state_id):


@amr_to_mira
def add_state(tm, state_id: str, value: float, name: str = None, units_mathml: str = None, grounding_ido=None):
def add_state(tm, state_id: str, value: float, name: str = None, units_mathml: str = None, grounding_ido: str = None,
context_str: str = None):
if grounding_ido:
grounding = {
'identifiers': {'ido': grounding_ido}
}
grounding = {'ido': grounding_ido}
else:
grounding = {}
if context_str:
context = {'context_key': context_str}
else:
context = {}
if units_mathml:
units = {
'expression': sstr(mathml_to_expression(units_mathml)),
'expression_mathml': units_mathml
}
units = Unit(expression=SympyExprStr(mathml_to_expression(units_mathml)))
else:
units = {}
data = {
'id': state_id,
'name': name if name else state_id,
'grounding': grounding,
'units': units
}
new_concept = state_to_concept(data)
new_state = Initial(concept=new_concept, value=value)
units = None

new_concept_new = Concept(name=state_id,
display_name=name,
identifiers=grounding,
units=units,
context=context)
new_state = Initial(concept=new_concept_new, value=value)
tm.initials[state_id] = new_state
static_template = StaticConcept(subject=new_concept)
static_template = StaticConcept(subject=new_concept_new)
tm.templates.append(static_template)
return tm

Expand All @@ -221,6 +220,10 @@ def add_transition(tm, new_transition_id, src_id=None, tgt_id=None,
# that aren't already present
# option 2, reverse engineer rate law and find parameters and states within
# the rate law and add to model

# each transition has inputs such as subjects and controllers and those appear in rate laws as states
# look at sympy expression and get free symbols, take out ones that represent the inputs and controllers (states)
# whatever remains are parameters for models
if src_id is None and tgt_id is None:
ValueError("You must pass in at least one of source and target id")
rate_law_sympy = SympyExprStr(mathml_to_expression(rate_law_mathml)) \
Expand Down
27 changes: 17 additions & 10 deletions tests/test_modeling/test_askenet_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from copy import deepcopy as _d
from mira.modeling.askenet.ops import *
from sympy import *
from mira.metamodel.io import mathml_to_expression
from mira.metamodel.io import mathml_to_expression, expression_to_mathml
from mira.metamodel.templates import Concept

try:
Expand Down Expand Up @@ -322,25 +322,23 @@ def test_remove_state(self):
self.assertNotIn(removed_state_id, new_observable['expression_mathml'])

@SBMLMATH_REQUIRED
# Some xml strings do not pass the checks
# (e.g. replacing the state X for 'E' argument xml string will fail that test, output will be
# 'expression_mathml': '<apply><times/><exponentiale/><ci>delta</ci></apply>')
def test_add_state(self):
amr = _d(self.sir_amr)
new_state_id = 'TEST'
new_state_display_name = 'TEST_DISPLAY_NAME'
new_state_grounding_ido = '5555'
new_state_grounding = {'identifiers': {
'ido': new_state_grounding_ido
},
'modifiers': {}}
new_state_units = "<apply><times/><ci>X</ci><ci>delta</ci></apply>"
context_str = 'TEST_CONTEXT'
new_state_grounding = {'identifiers': {'ido': new_state_grounding_ido},
'modifiers': {'context_key': context_str}}
new_state_units = "<apply><times/><ci>E</ci><ci>delta</ci></apply>"
value = 5
value_ml = '<cn>5.0</cn>'

new_amr = add_state(amr, state_id=new_state_id, name=new_state_display_name,
units_mathml=new_state_units,
grounding_ido=new_state_grounding_ido,
value=value)
value=value,
context_str=context_str)
state_dict = {}
for state in new_amr['model']['states']:
name = state.pop('id')
Expand All @@ -352,6 +350,15 @@ def test_add_state(self):
self.assertEqual(state_dict[new_state_id]['units']['expression'], sstr(mathml_to_expression(new_state_units)))
self.assertEqual(state_dict[new_state_id]['units']['expression_mathml'], new_state_units)

initials_dict = {}
for initial in new_amr['semantics']['ode']['initials']:
name = initial.pop('target')
initials_dict[name] = initial

self.assertIn(new_state_id, initials_dict)
self.assertEqual(float(initials_dict[new_state_id]['expression']), value)
self.assertEqual(initials_dict[new_state_id]['expression_mathml'], value_ml)

def test_remove_transition(self):
removed_transition = 'inf'
amr = _d(self.sir_amr)
Expand Down

0 comments on commit a961483

Please sign in to comment.