From fbd0bd5ec441ae6f89fd1af813fc8abf28936af6 Mon Sep 17 00:00:00 2001 From: "Frank T. Bergmann" Date: Fri, 14 Apr 2023 15:36:24 +0200 Subject: [PATCH] - add support for advanced event flags --- basico/model_info.py | 54 ++++++++++++++++++++++++++++++++++++--- tests/test_basico_info.py | 6 ++++- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/basico/model_info.py b/basico/model_info.py index 9e4b995..bcc9b1a 100644 --- a/basico/model_info.py +++ b/basico/model_info.py @@ -457,6 +457,10 @@ def get_events(name=None, exact=False, **kwargs): 'trigger': _replace_cns_with_names(event.getTriggerExpression(), model=dm), 'delay': _replace_cns_with_names(event.getDelayExpression(), model=dm), 'assignments': assignments, + 'priority': _replace_cns_with_names(event.getPriorityExpression(), model=dm), + 'fire_at_initial_time': event.getFireAtInitialTime(), + 'persistent': event.getPersistentTrigger(), + 'delay_calculation': event.getDelayAssignment(), 'key': event.getKey(), 'sbml_id': event.getSBMLId() } @@ -1933,6 +1937,12 @@ def add_event(name, trigger, assignments, **kwargs): * | `model`: to specify the data model to be used (if not specified | the one from :func:`.get_current_model` will be taken) + * 'new_name': the new name for the event + * 'delay': the delay expression + * 'priority': the priority expression + * 'persistent': boolean indicating if the event is persistent + * 'delay_calculation': boolean indicating whether just the assignment is delayed, or the calculation as well + * 'fire_at_initial_time': boolean indicating if the event should fire at the initial time :return: the newly created event """ @@ -1947,7 +1957,7 @@ def add_event(name, trigger, assignments, **kwargs): raise ValueError('An Event named ' + name + ' already exists') assert (isinstance(event, COPASI.CEvent)) - _set_event(event, dm, trigger=trigger, assignments=assignments) + _set_event(event, dm, trigger=trigger, assignments=assignments, **kwargs) return event @@ -1975,6 +1985,12 @@ def set_event(name, exact=False, trigger=None, assignments=None, **kwargs): * | `model`: to specify the data model to be used (if not specified | the one from :func:`.get_current_model` will be taken) + * 'new_name': the new name for the event + * 'delay': the delay expression + * 'priority': the priority expression + * 'persistent': boolean indicating if the event is persistent + * 'delay_calculation': boolean indicating whether just the assignment is delayed, or the calculation as well + * 'fire_at_initial_time': boolean indicating if the event should fire at the initial time :return: """ @@ -2016,20 +2032,46 @@ def _set_event(event, dm, assignments, trigger, **kwargs): :param assignments: dictionary of event assignments :param trigger: trigger expression :param kwargs: other attributes + - 'new_name': the new name for the event + - 'delay': the delay expression + - 'priority': the priority expression + - 'persistent': boolean indicating if the event is persistent + - 'delay_calculation': boolean indicating whether just the assignment is delayed, or the calculation as well + - 'fire_at_initial_time': boolean indicating if the event should fire at the initial time + - 'model': the model to use :return: """ if not event or not dm: return + need_compile = False if 'new_name' in kwargs and not event.setObjectName(kwargs['new_name']): logging.warning('could not rename event') + if 'delay' in kwargs: + event.setDelayExpression(_replace_names_with_cns(kwargs['delay'], model=dm)) + need_compile = True + + if 'priority' in kwargs: + event.setPriorityExpression(_replace_names_with_cns(kwargs['priority'], model=dm)) + need_compile = True + + if 'persistent' in kwargs: + event.setPersistentTrigger(bool(kwargs['persistent'])) + need_compile = True + + if 'delay_calculation' in kwargs: + event.setDelayAssignment(bool(kwargs['delay_calculation'])) + need_compile = True + + if 'fire_at_initial_time' in kwargs: + event.setFireAtInitialTime(bool(kwargs['fire_at_initial_time'])) + need_compile = True + if trigger: event.setTriggerExpression(_replace_names_with_cns(trigger, model=dm)) - l = COPASI.ContainerList() - l.push_back(dm) - event.compile(l) + need_compile = True if assignments: for assignment in assignments: @@ -2044,12 +2086,16 @@ def _set_event(event, dm, assignments, trigger, **kwargs): ea.setTargetCN(target.getCN()) ea.setExpression(_replace_names_with_cns(assignment[1], model=dm)) + need_compile = True + + if need_compile: l = COPASI.ContainerList() l.push_back(dm) event.compile(l) dm.getModel().compileIfNecessary() + def add_event_assignment(name, assignment, exact=False, **kwargs): """Adds an event assignment to the named event diff --git a/tests/test_basico_info.py b/tests/test_basico_info.py index 715c0d9..95290ad 100644 --- a/tests/test_basico_info.py +++ b/tests/test_basico_info.py @@ -377,12 +377,16 @@ def test_functions(self): def test_events(self): basico.add_parameter('p0', initial_value=10) - basico.add_event('e0', trigger='Time > 10', assignments=[('Values[p0]', 1)]) + basico.add_event('e0', trigger='Time > 10', assignments=[('Values[p0]', 1)], + fire_at_initial_time=True, persistent=True, delay_calculation=False) e = basico.as_dict(basico.get_events('e0', exact=True)) self.assertIsNotNone(e) self.assertEqual(e['trigger'], 'Time > 10') self.assertEqual(e['assignments'][0]['target'], 'Values[p0]') self.assertEqual(e['assignments'][0]['expression'], '1') + self.assertEqual(e['fire_at_initial_time'], True) + self.assertEqual(e['persistent'], True) + self.assertEqual(e['delay_calculation'], False) basico.remove_event('e0', exact=True) e = basico.as_dict(basico.get_events('e0', exact=True)) self.assertIsNone(e)