19
19
from biosimulators_utils .sedml .data_model import (Task , ModelLanguage , ModelAttributeChange , SteadyStateSimulation , # noqa: F401
20
20
Variable )
21
21
from biosimulators_utils .sedml .exec import exec_sed_doc as base_exec_sed_doc
22
- from biosimulators_utils .sedml .utils import apply_changes_to_xml_model
23
22
from biosimulators_utils .simulator .utils import get_algorithm_substitution_policy
24
23
from biosimulators_utils .utils .core import raise_errors_warnings
25
24
from biosimulators_utils .warnings import warn , BioSimulatorsWarning
30
29
import cobra .io
31
30
import copy
32
31
import os
33
- import tempfile
34
32
35
33
__all__ = [
36
34
'exec_sedml_docs_in_combine_archive' ,
@@ -139,40 +137,23 @@ def exec_sed_task(task, variables, preprocessed_task=None, log=None, config=None
139
137
if preprocessed_task is None :
140
138
preprocessed_task = preprocess_sed_task (task , variables , config = config )
141
139
140
+ # get model
141
+ cobra_model = preprocessed_task ['model' ]['model' ]
142
+
142
143
# modify model
143
- raise_errors_warnings (validation .validate_model_change_types (task .model .changes , (ModelAttributeChange , )),
144
- error_summary = 'Changes for model `{}` are not supported.' .format (task .model .id ))
145
144
if task .model .changes :
146
- model_etree = preprocessed_task ['model' ]['etree' ]
147
-
148
- model = copy .deepcopy (task .model )
149
- for change in model .changes :
150
- change .new_value = str (change .new_value )
151
-
152
- apply_changes_to_xml_model (model , model_etree , sed_doc = None , working_dir = None )
153
-
154
- model_file , model_filename = tempfile .mkstemp (suffix = '.xml' )
155
- os .close (model_file )
145
+ raise_errors_warnings (validation .validate_model_change_types (task .model .changes , (ModelAttributeChange , )),
146
+ error_summary = 'Changes for model `{}` are not supported.' .format (task .model .id ))
156
147
157
- model_etree .write (model_filename ,
158
- xml_declaration = True ,
159
- encoding = "utf-8" ,
160
- standalone = False ,
161
- pretty_print = False )
162
- else :
163
- model_filename = task .model .source
164
-
165
- # get the model
166
- cobra_model = cobra .io .read_sbml_model (model_filename )
167
- if task .model .changes :
168
- os .remove (model_filename )
148
+ model_change_obj_attr_map = preprocessed_task ['model' ]['model_change_obj_attr_map' ]
149
+ for change in task .model .changes :
150
+ model_obj , attr_name = model_change_obj_attr_map [change .target ]
151
+ new_value = float (change .new_value )
152
+ setattr (model_obj , attr_name , new_value )
169
153
170
154
variable_xpath_sbml_id_map = preprocessed_task ['model' ]['variable_xpath_sbml_id_map' ]
171
155
variable_xpath_sbml_fbc_id_map = preprocessed_task ['model' ]['variable_xpath_sbml_fbc_id_map' ]
172
156
173
- # set solver
174
- cobra_model .solver = preprocessed_task ['simulation' ]['solver' ]
175
-
176
157
# Load the simulation method specified by ``sim.algorithm``
177
158
method_props = preprocessed_task ['simulation' ]['method_props' ]
178
159
method_kw_args = copy .copy (preprocessed_task ['simulation' ]['method_kw_args' ])
@@ -241,6 +222,50 @@ def preprocess_sed_task(task, variables, config=None):
241
222
model_etree = etree .parse (model .source )
242
223
namespaces = get_namespaces_for_xml_doc (model_etree )
243
224
225
+ # Read the model
226
+ cobra_model = cobra .io .read_sbml_model (model .source )
227
+
228
+ # preprocess model changes
229
+ model_change_sbml_id_map = validation .validate_target_xpaths (
230
+ model .changes , model_etree , attr = 'id' )
231
+ model_change_obj_attr_map = {}
232
+ sbml_id_model_obj_map = {'R_' + reaction .id : reaction for reaction in cobra_model .reactions }
233
+ namespaces_list = namespaces .values ()
234
+ invalid_changes = []
235
+ for change in model .changes :
236
+ sbml_id = model_change_sbml_id_map [change .target ]
237
+ model_obj = sbml_id_model_obj_map .get (sbml_id , None )
238
+
239
+ attr_name = None
240
+
241
+ if model_obj is not None :
242
+ _ , sep , attr = change .target .partition ('/@' )
243
+ ns , _ , attr = attr .partition (':' )
244
+ if change .target_namespaces .get (ns , None ) in namespaces_list :
245
+ if attr == 'lowerFluxBound' :
246
+ attr_name = 'lower_bound'
247
+ elif attr == 'upperFluxBound' :
248
+ attr_name = 'upper_bound'
249
+
250
+ if attr_name :
251
+ model_change_obj_attr_map [change .target ] = (model_obj , attr_name )
252
+ else :
253
+ invalid_changes .append (change .target )
254
+
255
+ if invalid_changes :
256
+ valid_changes = []
257
+ for reaction in cobra_model .reactions :
258
+ valid_changes .append (
259
+ "/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='R_{}']/@fbc:lowerFluxBound" .format (reaction .id ))
260
+ valid_changes .append (
261
+ "/sbml:sbml/sbml:model/sbml:listOfReactions/sbml:reaction[@id='R_{}']/@fbc:upperFluxBound" .format (reaction .id ))
262
+
263
+ msg = 'The following changes are invalid:\n {}\n \n The following targets are valid:\n {}' .format (
264
+ '\n ' .join (sorted (invalid_changes )),
265
+ '\n ' .join (sorted (valid_changes )),
266
+ )
267
+ raise ValueError (msg )
268
+
244
269
# preprocess variables
245
270
variable_xpath_sbml_id_map = validation .validate_target_xpaths (
246
271
variables , model_etree , attr = 'id' )
@@ -256,9 +281,6 @@ def preprocess_sed_task(task, variables, config=None):
256
281
}
257
282
)
258
283
259
- # Read the model
260
- cobra_model = cobra .io .read_sbml_model (model .source )
261
-
262
284
# get the SBML-FBC id of the active objective
263
285
active_objective_sbml_fbc_id = get_active_objective_sbml_fbc_id (model .source )
264
286
@@ -306,15 +328,15 @@ def preprocess_sed_task(task, variables, config=None):
306
328
# Return processed information about the task
307
329
return {
308
330
'model' : {
309
- 'etree ' : model_etree ,
331
+ 'model ' : cobra_model ,
310
332
'active_objective_sbml_fbc_id' : active_objective_sbml_fbc_id ,
333
+ 'model_change_obj_attr_map' : model_change_obj_attr_map ,
311
334
'variable_xpath_sbml_id_map' : variable_xpath_sbml_id_map ,
312
335
'variable_xpath_sbml_fbc_id_map' : variable_xpath_sbml_fbc_id_map ,
313
336
},
314
337
'simulation' : {
315
338
'algorithm_kisao_id' : exec_kisao_id ,
316
339
'method_props' : method_props ,
317
340
'method_kw_args' : method_kw_args ,
318
- 'solver' : cobra_model .solver ,
319
341
}
320
342
}
0 commit comments