Skip to content

Commit 0903eb9

Browse files
Merge pull request #8 from ROBACON/update_model_implementation
Update model implementation
2 parents b2238a2 + 8f11ab1 commit 0903eb9

23 files changed

+857
-75
lines changed

debugging_script.py

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from test_script import *
2+
3+
# This is here because pytest is too slow - so it's a faster test that avoid the collection step.
4+
# Pytest is used in the GitHub while pushing
5+
# This script is oriented towards fast debugging and development
6+
# Also in the future, it might be nice to add an automated way to get the test names
7+
test_list = [test_model_1, test_model_2, test_model_3, test_model_4, test_model_5, test_model_6, test_model_7,
8+
test_orthogonal_spaces, test_average_value, test_hybrid_sim, test_concatenated_simulation,
9+
test_event_type, test_reacting_species_event, test_unit_event_test, test_reaction_deactivation,
10+
test_double_rate, test_single_rate, test_triple_rate, test_stochastic_event_duration,
11+
test_logic_operator_syntax, test_stack_position, test_empty_arguments,
12+
test_conditional_between_meta_species, test_conditional_between_meta_species_2,
13+
test_event_reaction_not_allowed, all_test, all_test_2, test_error_mult, test_set_counts,
14+
test_bool_error, test_event_all, test_one_value_concatenation_sim, test_crash_after_modification,
15+
test_unit_bi_dimension, test_bi_dimensional_rates, test_dimension_in_function_only,
16+
test_multiple_simulation_counts, test_string_events_assignment, test_plotting,
17+
test_volume_after_sim, test_parameters_with_sbml, test_shared_parameter_name,
18+
test_set_counts_parameters, test_repeated_parameters, initial_expression_test,
19+
test_wrong_dimension_error, test_more_than_used, zero_rate_test, test_wrong_rate,
20+
test_conversion_outside, test_first_characteristic_in_reacting_species, test_model_reference,
21+
test_sbml_generation, test_multi_sim_sbml, test_inline_comment,
22+
test_with_statement_any_and_species_characteristics, test_with_statement_on_any_and_event,
23+
test_matching_characteristic_rate, test_changes_after_compilation, test_proper_unit_context_exit,
24+
test_run_args, test_unit_args, test_multi_parameters_in_run, test_output_concentration_in_multi_sim,
25+
test_parameter_operation_in_rate, test_multi_parameter_with_expression, test_double_parameters_with_units,
26+
test_parameters_with_units, test_convert_back_parameter,
27+
test_numpy_in_expression_function, test_numpy_in_rates,
28+
test_numpy_in_counts, test_numpy_in_set_counts, test_multi_methods_plot, test_unit_x_conversion,
29+
test_Silicon_valley, test_replacing_species_name_in_expression, test_basic_assignment,
30+
test_all_asgn_ops, text_complex_assignments,
31+
text_assign_context_exit, text_even_more_complex_assignments, test_assign_context_complex,
32+
test_assign_context_constant, test_duration_with_run, test_rev, test_dimensionless_count,
33+
test_assignment_similar_species, test_blocked_names, test_blocked_names_2,
34+
test_update_parameter_for_multi_model, test_update_parameter_through_str,
35+
test_update_multiple_parameters_in_expression, test_update_parameter_with_unit,
36+
test_species_value_modification, test_all_value_modification]
37+
38+
# test_no_species_in_asg
39+
# test_illegal_unit_op_in_assignment
40+
# temporary_test_removal = [test_parameter_fit_with_units, test_multiple_runs_fit, test_simple_fit]
41+
test_remov = [test_antimony_compose_model_gen, test_antimony_model]
42+
sub_test = test_list
43+
#sub_test = [test_antimony_compose_model_gen]
44+
def perform_tests():
45+
any_failed = False
46+
for test in sub_test:
47+
try:
48+
test()
49+
print(f'Test {test} passed')
50+
except:
51+
print('\033[91m' + f'Test {test} failed' + '\033[0m', file=sys.stderr)
52+
any_failed = True
53+
if any_failed:
54+
assert False
55+
perform_tests()

for_local_use.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,26 @@
33

44
if __name__ == '__main__':
55

6+
# TODO: Ask Matthias about removed tests
7+
8+
# Replace parameters using units
9+
A = BaseSpecies()
10+
A.a1, A.a2
11+
B = New(A)
12+
B.b1, B.b2
613
k1 = ModelParameters(1)
7-
A, B, C, D = BaseSpecies()
814

9-
A >> 2 * B[modules.mobspy_parameters._Internal_Parameter_Constructor('k1', 3)]
10-
B >> C + D[modules.mobspy_parameters._Internal_Parameter_Constructor('k2', 1.4)]
15+
B >> Zero [k1]
16+
17+
B(100), B.b2(100)
18+
S = Simulation(B)
19+
S.level = -1
20+
S.compile()
21+
22+
S.update_model([All[B], 200/u.l])
1123

12-
A(100)
13-
S = Simulation(A | B | C | D)
14-
S.duration = 10
15-
print(S.compile())
16-
# print(S.generate_sbml()[0])
24+
print(S.generate_sbml()[0])
1725

18-
S.update_model()
26+
# print(A.get_characteristics())
1927

2028

mobspy/data_handler/time_series_object.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pandas as pd
55
from mobspy.modules.meta_class import *
66
from mobspy.modules.class_of_meta_specie_named_any import *
7+
import mobspy.simulation_logging as simlog
78
import inspect
89

910

mobspy/modules/compiler.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from mobspy.simulation_logging.log_scripts import error as simlog_error, warning as simlog_warning
2-
from mobspy.modules.mobspy_parameters import _Internal_Parameter_Constructor as mp_Mobspy_Parameter
2+
from mobspy.modules.mobspy_parameters import Internal_Parameter_Constructor as mp_Mobspy_Parameter
33
from mobspy.modules.species_string_generator import construct_all_combinations as ssg_construct_all_combinations, \
44
construct_species_char_list as ssg_construct_species_char_list
55
from pint import Quantity
@@ -29,7 +29,8 @@ def add_to_parameters_to_sbml(cls, parameters_used, parameters_for_sbml, paramet
2929
if parameter.name in parameters_used:
3030
parameters_used[parameter.name]['used_in'].add('$sbml')
3131
else:
32-
temp = {'name': parameter.name, 'values': parameter.value, 'used_in': {'$sbml'}}
32+
temp = {'name': parameter.name, 'values': parameter.value, 'used_in': {'$sbml'},
33+
'object': parameter}
3334
parameters_used[parameter.name] = temp
3435

3536
try:
@@ -138,7 +139,7 @@ def compile(cls, meta_species_to_simulate, reactions_set, species_counts, orthog
138139
species.order_references()
139140

140141
# Start by creating the Mappings for the SBML
141-
# Convert to user friendly format as well
142+
# Convert to user-friendly format as well
142143
mappings_for_sbml = {}
143144
for spe_object in meta_species_to_simulate:
144145
mappings_for_sbml[spe_object.get_name()] = []
@@ -202,7 +203,7 @@ def compile(cls, meta_species_to_simulate, reactions_set, species_counts, orthog
202203
= parameters_used[count['quantity'].name]['used_in'].union(set(species_strings))
203204
else:
204205
temp = {'name': count['quantity'].name, 'values': count['quantity'].value,
205-
'used_in': set(species_strings)}
206+
'used_in': set(species_strings), 'object': count['quantity']}
206207
parameters_used[count['quantity'].name] = temp
207208

208209
temp_count = uh_convert_counts(count['quantity'], volume, dimension)
@@ -232,7 +233,7 @@ def compile(cls, meta_species_to_simulate, reactions_set, species_counts, orthog
232233
parameters_used[count['quantity'].name]['used_in'].add(species_string)
233234
else:
234235
temp = {'name': count['quantity'].name, 'values': count['quantity'].value,
235-
'used_in': {species_string}}
236+
'used_in': {species_string}, 'object': count['quantity']}
236237
parameters_used[count['quantity'].name] = temp
237238

238239
temp_count = uh_convert_counts(count['quantity'], volume, dimension)

mobspy/modules/event_functions.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from mobspy.modules.species_string_generator import construct_all_combinations as ssg_construct_all_combinations, \
44
construct_species_char_list as ssg_construct_species_char_list
55
from pint import Quantity
6-
from mobspy.modules.mobspy_parameters import _Internal_Parameter_Constructor as mp_Mobspy_Parameter
6+
from mobspy.modules.mobspy_parameters import Internal_Parameter_Constructor as mp_Mobspy_Parameter
77
from mobspy.modules.function_rate_code import search_for_parameters_in_str as frc_search_for_parameters_in_str
88

99

mobspy/modules/function_rate_code.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from mobspy.modules.mobspy_expressions import MobsPyExpression as mbe_MobsPyExpression, \
1616
ExpressionDefiner as mbe_ExpressionDefiner, Specific_Species_Operator as mbe_Specific_Species_Operator
1717
from pint import Quantity
18-
from mobspy.modules.mobspy_parameters import _Internal_Parameter_Constructor as mp_Mobspy_Parameter
18+
from mobspy.modules.mobspy_parameters import Internal_Parameter_Constructor as mp_Mobspy_Parameter
1919
from re import split as re_split
2020
import timeit
2121

mobspy/modules/meta_class.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from mobspy.modules.mobspy_expressions import OverrideQuantity as me_OverrideQuantity, \
1414
MobsPyExpression as me_MobsPyExpression, Specific_Species_Operator as me_Specific_Species_Operator, \
1515
ExpressionDefiner as me_ExpressionDefiner
16-
from mobspy.modules.mobspy_parameters import _Internal_Parameter_Constructor as mp_Mobspy_Parameter
16+
from mobspy.modules.mobspy_parameters import Internal_Parameter_Constructor as mp_Mobspy_Parameter
1717
from numpy import integer as np_int_, floating as np_float_
1818
from inspect import stack as inspect_stack
1919
from mobspy.modules.meta_class_utils import unite_characteristics as mcu_unite_characteristics, \
@@ -356,6 +356,22 @@ def __init__(self, object_reference, characteristics, stoichiometry=1, label=Non
356356
self.list_of_reactants = [{'object': object_reference, 'characteristics': characteristics,
357357
'stoichiometry': stoichiometry, 'label': label}]
358358

359+
def get_spe_object(self):
360+
if len(self.list_of_reactants) != 1:
361+
simlog_error("The internal method get_queried_characteristics can only be used for "
362+
"Reacting_Species with a single ",
363+
full_exception_log=True)
364+
else:
365+
return self.list_of_reactants[0]['object']
366+
367+
def get_query_characteristics(self):
368+
if len(self.list_of_reactants) != 1:
369+
simlog_error("The internal method get_queried_characteristics can only be used for "
370+
"Reacting_Species with a single ",
371+
full_exception_log=True)
372+
else:
373+
return self.list_of_reactants[0]['characteristics']
374+
359375
def __rmul__(self, stoichiometry):
360376
"""
361377
Multiplication by the stoichiometry for reactions
@@ -442,7 +458,7 @@ def __call__(self, quantity):
442458
if len(self.list_of_reactants) != 1:
443459
simlog_error('Assignment used incorrectly. Only one species at a time', stack_index=2)
444460
quantity_dict = species_object.add_quantities(characteristics, quantity)
445-
# elif isinstance(quantity, ExpressionDefiner) and not isinstance(quantity, _Internal_Parameter_Constructor):
461+
# elif isinstance(quantity, ExpressionDefiner) and not isinstance(quantity, Internal_Parameter_Constructor):
446462
# simlog.error('Operations are not allowed for count assignment. Only individual parameters', stack_index=2)
447463
elif asgi_Assign.check_context():
448464
dummy_rsp = species_object
@@ -1096,6 +1112,12 @@ def __init__(self, name):
10961112
# This will store the quantities relating to the species counts
10971113
self._species_counts = []
10981114

1115+
def get_spe_object(self):
1116+
return self
1117+
1118+
def get_query_characteristics(self):
1119+
return 'std$'
1120+
10991121
def link_a_species(self, other_species):
11001122
"""
11011123
Links a species with another. So if one is added to the model, the other is also added to the model

mobspy/modules/mobspy_parameters.py

+39-19
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pint import Quantity, UnitRegistry
66

77

8-
class _Internal_Parameter_Constructor(me_ExpressionDefiner, me_QuantityConverter):
8+
class Internal_Parameter_Constructor(me_ExpressionDefiner, me_QuantityConverter):
99
"""
1010
This is the constructor that is called by ModelParameters to create a model parameter
1111
(not a simulation parameter). The user is not supposed to create parameters using this object.
@@ -28,34 +28,38 @@ def __init__(self, name, value):
2828
self._operation = str(name)
2929
self._parameter_set.add(self)
3030

31-
def unit_process(value):
32-
# We convert into MobsPy units already during the definition of a parameter
33-
self.value = self.convert_received_unit(value).magnitude
31+
self.process_value(value)
3432

35-
self.original_magnitude = value.magnitude
36-
self.conversion_factor = self.value / self.original_magnitude
37-
self.original_unit = value.units
33+
def unit_process(self, value):
34+
# We convert into MobsPy units already during the definition of a parameter
35+
self.value = self.convert_received_unit(value).magnitude
3836

39-
# For future developers, the T is there to avoid potential bugs with the . query
40-
self._unit_count_op = value
41-
self._unit_conc_op = value
42-
self._unit_operation = value
43-
self._has_units = 'T'
37+
self.original_magnitude = value.magnitude
38+
self.conversion_factor = self.value / self.original_magnitude
39+
self.original_unit = value.units
4440

45-
return self.value, self.original_unit
41+
# For future developers, the T is there to avoid potential bugs with the . query
42+
self._unit_count_op = value
43+
self._unit_conc_op = value
44+
self._unit_operation = value
45+
self._has_units = 'T'
46+
47+
return self.value, self.original_unit
48+
49+
def process_value(self, value):
4650

4751
if isinstance(value, Quantity):
48-
unit_process(value)
52+
self.unit_process(value)
4953
elif type(value) == list or type(value) == tuple:
5054
new_list = []
5155
first_unit = None
5256
for i, val in enumerate(value):
5357
if isinstance(val, Quantity) and i == 0:
54-
new_value, first_unit = unit_process(val)
58+
new_value, first_unit = self.unit_process(val)
5559
elif isinstance(val, Quantity) and i > 0 and first_unit is None:
5660
simlog.error("MobsPy parameters must all be the same unit", stack_index=1)
5761
elif isinstance(val, Quantity) and i > 0 and first_unit is not None:
58-
new_value, unit = unit_process(val)
62+
new_value, unit = self.unit_process(val)
5963
if unit != first_unit:
6064
simlog.error("MobsPy parameters must all be the same unit", stack_index=1)
6165
else:
@@ -72,6 +76,7 @@ def unit_process(value):
7276
self.conversion_factor = 1
7377
self._has_units = False
7478

79+
7580
def convert_to_original_unit(self):
7681
"""
7782
Converts the parameter from the MobsPy standard unit to the original unit of the parameter
@@ -108,6 +113,21 @@ def has_units(self):
108113
else:
109114
return False
110115

116+
def update_value(self, new_value):
117+
118+
temp_set = set()
119+
temp_set.add(self)
120+
self.original_value = new_value
121+
122+
self._ms_active = True
123+
124+
self._parameter_set.add(self)
125+
126+
self.process_value(new_value)
127+
128+
def get_name(self):
129+
return self.name
130+
111131
def __str__(self):
112132
return str(self._operation)
113133

@@ -124,9 +144,9 @@ def ModelParameters(*args):
124144
simlog.error('You must provide an initial value for every parameter variable declared', stack_index=2)
125145

126146
if len(parameter_variable_names) > 1:
127-
parameters_to_return = [_Internal_Parameter_Constructor(p, v) for p, v in zip(parameter_variable_names, args)]
147+
parameters_to_return = [Internal_Parameter_Constructor(p, v) for p, v in zip(parameter_variable_names, args)]
128148
else:
129-
parameters_to_return = _Internal_Parameter_Constructor(parameter_variable_names[0], args[0])
149+
parameters_to_return = Internal_Parameter_Constructor(parameter_variable_names[0], args[0])
130150

131151
return parameters_to_return
132152

@@ -137,5 +157,5 @@ def ModelParameters(*args):
137157
r1 = (a + b + c)/5
138158
print(r1._operation)
139159
# print(type(r1._parameter_set))
140-
# print(_Internal_Parameter_Constructor.parameter_stack)
160+
# print(Internal_Parameter_Constructor.parameter_stack)
141161

mobspy/modules/set_counts_module.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from mobspy.simulation_logging.log_scripts import error as simlog_error
22
from inspect import stack as inspect_stack
33
from mobspy.modules.meta_class import List_Species, Species, Reacting_Species
4-
from mobspy.modules.mobspy_parameters import _Internal_Parameter_Constructor as mp_Mobspy_Parameter
4+
from mobspy.modules.mobspy_parameters import Internal_Parameter_Constructor as mp_Mobspy_Parameter
55
from pint import Quantity
66
from numpy import integer as np_int_, floating as np_float_
77

mobspy/modules/species_string_generator.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ def characteristics_dictionary(characteristics, characteristics_to_object):
1616
return object_to_characteristic
1717

1818

19-
def construct_species_char_list(spe_object, characteristics, characteristics_to_object, symbol=None):
19+
def construct_species_char_list(spe_or_reactiong_object, characteristics,
20+
characteristics_to_object, symbol=None):
2021
"""
2122
This function constructs a list in the format ['species_name', 'char1', 'char2', ...]. It generetes this list
2223
for a given meta-species and the specified characteristics. Values of characteristics not specified in a
@@ -31,26 +32,31 @@ def construct_species_char_list(spe_object, characteristics, characteristics_to_
3132
"""
3233
if characteristics == 'std$':
3334
characteristics = set()
35+
spe_object = spe_or_reactiong_object.get_spe_object()
3436

3537
ordered_references_list = spe_object.get_ordered_references()
3638

3739
objects_to_characteristic = characteristics_dictionary(characteristics, characteristics_to_object)
3840

3941
species_char_list = [spe_object]
42+
4043
for obj in ordered_references_list:
4144
if obj in objects_to_characteristic:
4245
species_char_list.append(objects_to_characteristic[obj])
4346
else:
4447
species_char_list.append(obj.first_characteristic)
4548

49+
4650
if symbol is not None:
4751
species_char_list = symbol.join([spe_object.get_name()] + species_char_list [1:]) \
4852
if len(species_char_list) > 1 else spe_object.get_name()
4953

54+
5055
return species_char_list
5156

5257

53-
def construct_all_combinations(spe_object, characteristics, characteristics_to_object, symbol=None):
58+
def construct_all_combinations(spe_or_reactiong_object,
59+
characteristics, characteristics_to_object, symbol=None):
5460
"""
5561
This function constructs all possible list in the format ['species_name', 'char1', 'char2', ...] using
5662
all combinations of characteristics from the vector coordinates not used in the characteristics specified
@@ -65,6 +71,7 @@ def construct_all_combinations(spe_object, characteristics, characteristics_to_o
6571

6672
if characteristics == 'std$':
6773
characteristics = set()
74+
spe_object = spe_or_reactiong_object.get_spe_object()
6875

6976
spe_object.order_references()
7077
ordered_references_list = spe_object.get_ordered_references()

0 commit comments

Comments
 (0)