26
26
import tempfile
27
27
28
28
__all__ = [
29
+ 'preprocess_model_attribute_change' ,
29
30
'add_model_attribute_change_to_task' ,
30
31
'add_variables_to_model' ,
31
32
'add_simulation_to_task' ,
34
35
]
35
36
36
37
37
- def add_model_attribute_change_to_task (task , change ):
38
- """ Encode SED model attribute changes into a BioNetGen task
38
+ def preprocess_model_attribute_change (task , change ):
39
+ """ Process a model change
39
40
40
41
* Compartment sizes: targets should follow the pattern ``compartments.<compartment_id>.size``
41
42
* Function expressions: targets should follow the pattern ``functions.<function_id>.expression``
@@ -46,11 +47,13 @@ def add_model_attribute_change_to_task(task, change):
46
47
task (:obj:`Task`): BioNetGen task
47
48
change (:obj:`ModelAttributeChange`): model attribute change
48
49
50
+ Returns:
51
+ :obj:`dict`: processed information about the model change
52
+
49
53
Raises:
50
54
:obj:`ValueError`: if a target of a change is not valid
51
55
"""
52
56
target = change .target
53
- new_value = change .new_value
54
57
55
58
compartment_size_match = re .match (r'^compartments\.([^\.]+)(\.size)?$' , target )
56
59
if compartment_size_match :
@@ -62,25 +65,32 @@ def add_model_attribute_change_to_task(task, change):
62
65
for i_line , line in enumerate (block ):
63
66
match = re .match (pattern , line )
64
67
if match :
65
- block [i_line ] = '{} {} {} {}' .format (obj_id , match .group (1 ), new_value , (match .group (3 ) or '' ).strip ()).strip ()
66
68
comp_changed = True
69
+ return {
70
+ 'type' : 'replace_line_in_block' ,
71
+ 'block' : block ,
72
+ 'i_line' : i_line ,
73
+ 'new_line' : lambda new_value : '{} {} {} {}' .format (obj_id , match .group (1 ), new_value , (match .group (3 ) or '' ).strip ()).strip (),
74
+ }
67
75
68
76
if not comp_changed :
69
77
raise ValueError (('The size of compartment `{}` cannot be changed '
70
78
'because the model does not have a compartment with this id.' ).format (obj_id ))
71
79
72
- return
73
-
74
80
parameter_values_match = re .match (r'^parameters\.([^\.]+)(\.value)?$' , target )
75
81
if parameter_values_match :
76
- task .actions .append ('setParameter("{}", {})' .format (parameter_values_match .group (1 ), new_value ))
77
- return
82
+ return {
83
+ 'type' : 'append_action' ,
84
+ 'action' : lambda new_value : 'setParameter("{}", {})' .format (parameter_values_match .group (1 ), new_value ),
85
+ }
78
86
79
87
species_counts_match = re .match (r'^species\.([^\.]+)\((.*?)\)(\.initialCount)?$' , target )
80
88
if species_counts_match :
81
- task .actions .append ('setConcentration("{}({})", {})' .format (
82
- species_counts_match .group (1 ), species_counts_match .group (2 ), new_value ))
83
- return
89
+ return {
90
+ 'type' : 'append_action' ,
91
+ 'action' : lambda new_value : 'setConcentration("{}({})", {})' .format (
92
+ species_counts_match .group (1 ), species_counts_match .group (2 ), new_value ),
93
+ }
84
94
85
95
functions_expression_match = re .match (r'^functions\.([^\.\(\)]+)(\.expression)?$' , target )
86
96
if functions_expression_match :
@@ -94,14 +104,17 @@ def add_model_attribute_change_to_task(task, change):
94
104
match = re .match (pattern , line )
95
105
if match :
96
106
func_changed = True
97
- block [i_line ] = '{}({}) = {}' .format (obj_id , match .group (1 ), new_value )
107
+ return {
108
+ 'type' : 'replace_line_in_block' ,
109
+ 'block' : block ,
110
+ 'i_line' : i_line ,
111
+ 'new_line' : lambda new_value : '{}({}) = {}' .format (obj_id , match .group (1 ), new_value ),
112
+ }
98
113
99
114
if not func_changed :
100
115
raise ValueError (('The expression of function `{}` cannot be changed '
101
116
'because the model does not have a function with this id.' ).format (obj_id ))
102
117
103
- return
104
-
105
118
function_args_expression_match = re .match (r'^functions\.([^\.]+)\((.*?)\)(\.expression)?$' , target )
106
119
if function_args_expression_match :
107
120
obj_id = function_args_expression_match .group (1 )
@@ -115,14 +128,17 @@ def add_model_attribute_change_to_task(task, change):
115
128
match = re .match (pattern , line )
116
129
if match :
117
130
func_changed = True
118
- block [i_line ] = '{}({}) = {}' .format (obj_id , obj_args , new_value )
131
+ return {
132
+ 'type' : 'replace_line_in_block' ,
133
+ 'block' : block ,
134
+ 'i_line' : i_line ,
135
+ 'new_line' : lambda new_value : '{}({}) = {}' .format (obj_id , obj_args , new_value ),
136
+ }
119
137
120
138
if not func_changed :
121
139
raise ValueError (('The expression of function `{}` cannot be changed '
122
140
'because the model does not have a function with this id.' ).format (obj_id ))
123
141
124
- return
125
-
126
142
target_patterns = {
127
143
'compartment size' : compartment_size_match ,
128
144
'parameter value' : parameter_values_match ,
@@ -135,6 +151,33 @@ def add_model_attribute_change_to_task(task, change):
135
151
raise NotImplementedError (msg )
136
152
137
153
154
+ def add_model_attribute_change_to_task (task , change , preprocessed_change = None ):
155
+ """ Encode SED model attribute changes into a BioNetGen task
156
+
157
+ * Compartment sizes: targets should follow the pattern ``compartments.<compartment_id>.size``
158
+ * Function expressions: targets should follow the pattern ``functions.<function_id>.expression``
159
+ * Initial species counts: targets should follow the pattern ``species.<species_id>.count``
160
+ * Parameter values: targets should follow the pattern ``parameters.<parameter_id>.value``
161
+
162
+ Args:
163
+ task (:obj:`Task`): BioNetGen task
164
+ change (:obj:`ModelAttributeChange`): model attribute change
165
+ preprocessed_change (:obj:`dict`): preprocessed information about the change
166
+
167
+ Raises:
168
+ :obj:`ValueError`: if a target of a change is not valid
169
+ """
170
+ if preprocessed_change is None :
171
+ preprocessed_change = preprocess_model_attribute_change (task , change )
172
+
173
+ new_value = change .new_value
174
+
175
+ if preprocessed_change ['type' ] == 'replace_line_in_block' :
176
+ preprocessed_change ['block' ][preprocessed_change ['i_line' ]] = preprocessed_change ['new_line' ](new_value )
177
+ else :
178
+ task .actions .append (preprocessed_change ['action' ](new_value ))
179
+
180
+
138
181
def add_variables_to_model (model , variables ):
139
182
""" Encode SED variables into observables in a BioNetGen task
140
183
0 commit comments