def test_get_parameters_variables_outputs_for_simulation(self): fixtures_dirname = os.path.join(os.path.dirname(__file__), 'fixtures') for model_filename in [ os.path.join(fixtures_dirname, 'test.bngl'), os.path.join(fixtures_dirname, 'LR_comp_resolved.bngl'), ]: changes, sim, variables, plots = get_parameters_variables_outputs_for_simulation( model_filename, None, UniformTimeCourseSimulation, None) task = read_task(model_filename) task.actions = [] for change in changes: add_model_attribute_change_to_task(task, change) add_variables_to_model(task.model, variables) model_filename_2 = os.path.join(self.dirname, 'task.bngl') write_task(task, model_filename_2) changes_2, sim, variables_2, plots_2 = get_parameters_variables_outputs_for_simulation( model_filename_2, None, UniformTimeCourseSimulation, None) for change, change_2 in zip(changes, changes_2): self.assertTrue(change_2.is_equal(change)) for variable, variable_2 in zip(variables, variables_2): self.assertTrue(variable_2.is_equal(variable)) task_2 = read_task(model_filename_2) self.assertEqual(task_2.model, task.model)
def test_get_parameters_variables_for_simulation_with_step_args(self): with self.assertWarnsRegex(BioSimulatorsWarning, r'Output step interval \(`output_step_interval`\) was ignored'): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( os.path.join(self.FIXTURE_DIRNAME, 'step-action-args.bngl'), None, UniformTimeCourseSimulation, None) self.assertEqual(sims[0].algorithm.changes[-1].kisao_id, 'KISAO_0000415') self.assertEqual(sims[0].algorithm.changes[-1].new_value, '10000')
def test_get_parameters_variables_for_simulation_compartmentalized(self): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( self.COMP_FIXTURE_FILENAME, None, UniformTimeCourseSimulation, None) self.assertTrue(params[0].is_equal(ModelAttributeChange( id='value_parameter_NaV', name='Value of parameter "NaV"', target='parameters.NaV.value', new_value='6.02e8', ))) self.assertTrue(params[2].is_equal(ModelAttributeChange( id='value_parameter_Vec', name='Value of parameter "Vec"', target='parameters.Vec.value', new_value='1000*Vcell', ))) self.assertTrue(params[11].is_equal(ModelAttributeChange( id='initial_size_compartment_EC', name='Initial size of 3-D compartment "EC"', target='compartments.EC.size', new_value='1000000', ))) self.assertTrue(params[12].is_equal(ModelAttributeChange( id='initial_size_compartment_PM', name='Initial size of 2-D compartment "PM"', target='compartments.PM.size', new_value='10', ))) self.assertTrue(params[14].is_equal(ModelAttributeChange( id='initial_amount_species__EC_L_r_', name='Initial amount of species "@EC:L(r)"', target='species.@EC:L(r).initialCount', new_value='L0', ))) self.assertEqual(len(params), 16) self.assertTrue(vars[0].is_equal(Variable( id='time', name='Time', symbol=Symbol.time.value, ))) self.assertTrue(vars[1].is_equal(Variable( id='amount_molecule_L_r_', name='Dynamics of molecule "L(r)"', target='molecules.L(r).count', ))) self.assertTrue(vars[3].is_equal(Variable( id='amount_species__EC_L_r_', name='Dynamics of species "@EC:L(r)"', target='species.@EC:L(r).count', ))) self.assertTrue(vars[5].is_equal(Variable( id='amount_molecule_L_r_1__R_l_1_', name='Dynamics of molecule "L(r!1).R(l!1)"', target='molecules.L(r!1).R(l!1).count', ))) self.assertEqual(len(vars), 7)
def test_get_parameters_variables_for_simulation_with_sample_times(self): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( os.path.join(self.FIXTURE_DIRNAME, 'sample-times.bngl'), None, UniformTimeCourseSimulation, None) self.assertEqual(sims[0].initial_time, 0) self.assertEqual(sims[0].output_start_time, 1) self.assertEqual(sims[0].output_end_time, 5) self.assertEqual(sims[0].number_of_steps, 4)
def test_get_parameters_variables_for_simulation_with_non_uniform_sample_times(self): with self.assertWarnsRegex(BioSimulatorsWarning, 'Non-uniformly-distributed sample times'): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( os.path.join(self.FIXTURE_DIRNAME, 'non-uniform-sample-times.bngl'), None, UniformTimeCourseSimulation, None) self.assertEqual(sims[0].initial_time, 0) self.assertEqual(sims[0].output_start_time, 1) self.assertEqual(sims[0].output_end_time, 6) self.assertEqual(sims[0].number_of_steps, 1)
def test_get_parameters_variables_for_simulation(self): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation(self.FIXTURE_FILENAME, None, OneStepSimulation, None) params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( self.FIXTURE_FILENAME, None, UniformTimeCourseSimulation, None) self.assertTrue(params[0].is_equal(ModelAttributeChange( id='value_parameter_k_1', name='Value of parameter "k_1"', target='parameters.k_1.value', new_value='0.0', ))) self.assertTrue(params[7].is_equal(ModelAttributeChange( id='value_parameter_fa', name='Value of parameter "fa"', target='parameters.fa.value', new_value='1E-5', ))) self.assertTrue(params[9].is_equal(ModelAttributeChange( id='initial_amount_species_GeneA_00__', name='Initial amount of species "GeneA_00()"', target='species.GeneA_00().initialCount', new_value='1', ))) self.assertTrue(params[17].is_equal(ModelAttributeChange( id='expression_function_gfunc', name='Expression of function "gfunc()"', target='functions.gfunc.expression', new_value='(0.5*(Atot^2))/(10+(Atot^2))', ))) self.assertEqual(len(sims), 5) self.assertIsInstance(sims[0], UniformTimeCourseSimulation) expected_sim = UniformTimeCourseSimulation( id='simulation_0', initial_time=0., output_start_time=0., output_end_time=1000000., number_of_steps=1000, algorithm=Algorithm( kisao_id='KISAO_0000029', changes=[ AlgorithmParameterChange( kisao_id='KISAO_0000488', new_value='2', ) ] ) ) self.assertTrue(sims[0].is_equal(expected_sim)) self.assertTrue(vars[0].is_equal(Variable( id='time', name='Time', symbol=Symbol.time.value, ))) self.assertTrue(vars[1].is_equal(Variable( id='amount_molecule_A__', name='Dynamics of molecule "A()"', target='molecules.A().count', ))) self.assertTrue(vars[9].is_equal(Variable( id='amount_species_GeneA_00__', name='Dynamics of species "GeneA_00()"', target='species.GeneA_00().count', ))) self.assertEqual(len(vars), 17)
def test_get_parameters_variables_for_simulation_action_syntax_error_handling(self): with self.assertRaisesRegex(ValueError, 'not a valid BNGL or BNGL XML file'): get_parameters_variables_outputs_for_simulation(self.INVALID_SYNTAX_FIXTURE_FILENAME, None, UniformTimeCourseSimulation, None)
def test_get_parameters_variables_for_simulation_no_actions(self): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( self.NO_ACTIONS_FIXTURE_FILENAME, None, OneStepSimulation, None) params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( self.NO_ACTIONS_FIXTURE_FILENAME, None, UniformTimeCourseSimulation, None)
def test_get_parameters_variables_for_simulation_multiple_actions(self): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( self.MULTIPLE_ACTIONS_FIXTURE_FILENAME, None, UniformTimeCourseSimulation, None) self.assertEqual(len(sims), 7)
def test_get_parameters_variables_for_simulation_error_handling(self): with self.assertRaisesRegex(ValueError, 'is not a path to a model file'): get_parameters_variables_outputs_for_simulation(None, None, UniformTimeCourseSimulation, None) with self.assertRaisesRegex(FileNotFoundError, 'does not exist'): get_parameters_variables_outputs_for_simulation('not a file', None, UniformTimeCourseSimulation, None) with self.assertRaisesRegex(ValueError, 'not a valid BNGL or BNGL XML file'): get_parameters_variables_outputs_for_simulation(self.INVALID_FIXTURE_FILENAME, None, UniformTimeCourseSimulation, None) with self.assertRaisesRegex(NotImplementedError, 'must be'): get_parameters_variables_outputs_for_simulation(self.FIXTURE_FILENAME, None, SteadyStateSimulation, None) with self.assertRaisesRegex(ValueError, 'must define a `method` argument'): get_parameters_variables_outputs_for_simulation(os.path.join(self.FIXTURE_DIRNAME, 'insufficient-action-args.bngl'), None, UniformTimeCourseSimulation, None) with self.assertRaisesRegex(ValueError, 'must define a `method` argument'): get_parameters_variables_outputs_for_simulation(os.path.join(self.FIXTURE_DIRNAME, 'insufficient-action-args.bngl'), None, UniformTimeCourseSimulation, None) with self.assertRaisesRegex(ValueError, r'`Simulation end time \(`t_end`\) must be set'): get_parameters_variables_outputs_for_simulation(os.path.join(self.FIXTURE_DIRNAME, 'insufficient-action-args-2.bngl'), None, UniformTimeCourseSimulation, None)
def test_get_parameters_variables_for_simulation_native_data_types(self): params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( self.FIXTURE_FILENAME, None, UniformTimeCourseSimulation, None, native_ids=True, native_data_types=True) self.assertTrue(params[0].is_equal(ModelAttributeChange( id='k_1', name=None, target='parameters.k_1.value', new_value=0.0, ))) self.assertTrue(params[7].is_equal(ModelAttributeChange( id='fa', name=None, target='parameters.fa.value', new_value=1E-5, ))) self.assertTrue(params[9].is_equal(ModelAttributeChange( id='GeneA_00()', name=None, target='species.GeneA_00().initialCount', new_value=1, ))) self.assertTrue(params[17].is_equal(ModelAttributeChange( id='gfunc', name=None, target='functions.gfunc.expression', new_value='(0.5*(Atot^2))/(10+(Atot^2))', ))) self.assertEqual(len(sims), 5) self.assertIsInstance(sims[0], UniformTimeCourseSimulation) expected_sim = UniformTimeCourseSimulation( id='simulation_0', initial_time=0., output_start_time=0., output_end_time=1000000., number_of_steps=1000, algorithm=Algorithm( kisao_id='KISAO_0000029', changes=[ AlgorithmParameterChange( kisao_id='KISAO_0000488', new_value=2, ) ] ) ) self.assertTrue(sims[0].is_equal(expected_sim)) self.assertTrue(vars[0].is_equal(Variable( id=None, name=None, symbol=Symbol.time.value, ))) self.assertTrue(vars[1].is_equal(Variable( id='A()', name=None, target='molecules.A().count', ))) self.assertTrue(vars[9].is_equal(Variable( id='GeneA_00()', name=None, target='species.GeneA_00().count', ))) self.assertEqual(len(vars), 17)
def test_get_parameters_variables_for_simulation_with_empty_sample_times(self): with self.assertRaisesRegex(ValueError, 'must be a non-empty array'): get_parameters_variables_outputs_for_simulation(os.path.join(self.FIXTURE_DIRNAME, 'empty-sample-times.bngl'), None, UniformTimeCourseSimulation, None)
def get_parameters_variables_outputs_for_simulation( model_filename, model_language, simulation_type, algorithm_kisao_id=None, change_level=SedDocument, native_ids=False, native_data_types=False, model_language_options=None): """ Get the possible observables for a simulation of a model This method supports the following formats * SBML * SBML-fbc * SBML-qual Args: model_filename (:obj:`str`): path to model file model_language (:obj:`str`): model language (e.g., ``urn:sedml:language:sbml``) simulation_type (:obj:`types.Type`): subclass of :obj:`Simulation` algorithm_kisao_id (:obj:`str`, optional): KiSAO id of the algorithm for simulating the model (e.g., ``KISAO_0000019`` for CVODE) change_level (:obj:`types.Type`, optional): level at which model changes will be made (:obj:`SedDocument` or :obj:`Task`) native_ids (:obj:`bool`, optional): whether to return the raw id and name of each model component rather than the suggested name for the variable of an associated SED-ML data generator native_data_types (:obj:`bool`, optional): whether to return new_values in their native data types model_language_options (:obj:`dict`, optional): additional options to pass to the methods for individual model formats. Dictionary that maps model languages (:obj:`ModelLanguage`) to dictionaries of optional keyword arguments for each language Returns: :obj:`list` of :obj:`ModelAttributeChange`: possible attributes of a model that can be changed and their default values :obj:`list` of :obj:`Simulation`: simulation of the model :obj:`list` of :obj:`Variable`: possible observables for a simulation of the model :obj:`list` of :obj:`Plot`: possible plots of the results of a simulation of the model Raises: :obj:`UnsupportedModelLanguageError`: if :obj:`model_language` is not a supported language """ if model_language_options is None: model_language_options = {} # functions are imported here to only import libraries for required model languages if model_language and re.match(ModelLanguagePattern.BNGL.value, model_language): from biosimulators_utils.model_lang.bngl.utils import get_parameters_variables_outputs_for_simulation elif model_language and re.match(ModelLanguagePattern.CellML.value, model_language): from biosimulators_utils.model_lang.cellml.utils import get_parameters_variables_outputs_for_simulation elif model_language and re.match(ModelLanguagePattern.LEMS.value, model_language): # from biosimulators_utils.model_lang.lems.utils import get_parameters_variables_outputs_for_simulation raise UnsupportedModelLanguageError( 'Models of language `{}` are not supported'.format(model_language)) elif model_language and re.match(ModelLanguagePattern.RBA.value, model_language): from biosimulators_utils.model_lang.rba.utils import get_parameters_variables_outputs_for_simulation elif model_language and re.match(ModelLanguagePattern.SBML.value, model_language): from biosimulators_utils.model_lang.sbml.utils import get_parameters_variables_outputs_for_simulation elif model_language and re.match(ModelLanguagePattern.Smoldyn.value, model_language): from biosimulators_utils.model_lang.smoldyn.utils import get_parameters_variables_outputs_for_simulation elif model_language and re.match(ModelLanguagePattern.XPP.value, model_language): from biosimulators_utils.model_lang.xpp.utils import get_parameters_variables_outputs_for_simulation else: raise UnsupportedModelLanguageError( 'Models of language `{}` are not supported'.format(model_language)) return get_parameters_variables_outputs_for_simulation( model_filename, model_language, simulation_type, algorithm_kisao_id=algorithm_kisao_id, change_level=change_level, native_ids=native_ids, native_data_types=native_data_types, **model_language_options.get(model_language, {}), )
def build_combine_archive_for_model(model_filename, model_language, simulation_type, archive_filename, extra_contents=None, config=None, **model_language_options): """ Build A COMBINE/OMEX archive with a SED-ML file for a model Args: model_filename (:obj:`str`): path to model file model_language (:obj:`ModelLanguage`): model language simulation_type (:obj:`type`): subclass of :obj:`Simulation` archive_filename (:obj:`str`): path to save COMBINE/OMEX archive extra_contents (:obj:`dict` of :obj:`str` -> :obj:`CombineArchiveContent`, optional): dictionary that maps the local paths of additional files to include in the COMBINE/OMEX archive to their intended locations within the COMBINE/OMEX archive config (:obj:`Config`, optional): whether to fail on missing includes **model_language_options: additional options to pass to the methods for individual model formats """ # make a SED-ML document for the model params, sims, vars, plots = get_parameters_variables_outputs_for_simulation( model_filename, model_language, simulation_type, **model_language_options) sedml_doc = SedDocument() model = Model( id='model', source=os.path.basename(model_filename), language=model_language.value, changes=params, ) sedml_doc.models.append(model) for i_sim, sim in enumerate(sims): sedml_doc.simulations.append(sim) if len(sims) > 1: sim_suffix = '_' + str(i_sim) else: sim_suffix = '' task = Task( id='task' + sim_suffix, model=model, simulation=sim, ) sedml_doc.tasks.append(task) report = Report(id='report' + sim_suffix, ) sedml_doc.outputs.append(report) var_data_gen_map = {} for var in vars: var_copy = copy.copy(var) var_copy.id = '{}{}'.format(var_copy.id, sim_suffix) var_copy.task = task data_gen = DataGenerator( id='data_generator{}_{}'.format(sim_suffix, var_copy.id), name=var_copy.name, variables=[var_copy], math=var_copy.id, ) sedml_doc.data_generators.append(data_gen) var_data_gen_map[var] = data_gen report.data_sets.append( DataSet( id='data_set{}_{}'.format(sim_suffix, var_copy.id), label=var_copy.id, name=var_copy.name, data_generator=data_gen, )) for plot in plots: plot_copy = copy.copy(plot) plot_copy.id = '{}{}'.format(plot_copy.id, sim_suffix) if isinstance(plot, Plot2D): plot_copy.curves = [] for curve in plot.curves: assert len(curve.x_data_generator.variables) == 1 assert len(curve.y_data_generator.variables) == 1 assert curve.x_data_generator.math == curve.x_data_generator.variables[ 0].id assert curve.y_data_generator.math == curve.y_data_generator.variables[ 0].id plot_copy.curves.append( Curve( id='{}{}'.format(curve.id, sim_suffix), name=curve.name, x_data_generator=var_data_gen_map[ curve.x_data_generator.variables[0]], y_data_generator=var_data_gen_map[ curve.y_data_generator.variables[0]], x_scale=curve.x_scale, y_scale=curve.y_scale, )) else: plot_copy.surfaces = [] for surface in plot.surfaces: assert len(curve.x_data_generator.variables) == 1 assert len(curve.y_data_generator.variables) == 1 assert len(curve.z_data_generator.variables) == 1 assert curve.x_data_generator.math == curve.x_data_generator.variables[ 0].id assert curve.y_data_generator.math == curve.y_data_generator.variables[ 0].id assert curve.z_data_generator.math == curve.z_data_generator.variables[ 0].id plot_copy.curves.append( Surface( id='{}{}'.format(curve.id, sim_suffix), name=curve.name, x_data_generator=var_data_gen_map[ curve.x_data_generator.variables[0]], y_data_generator=var_data_gen_map[ curve.y_data_generator.variables[0]], z_data_generator=var_data_gen_map[ curve.z_data_generator.variables[0]], x_scale=curve.x_scale, y_scale=curve.y_scale, z_scale=curve.z_scale, )) sedml_doc.outputs.append(plot_copy) # make temporary directory for archive archive_dirname = tempfile.mkdtemp() shutil.copyfile( model_filename, os.path.join(archive_dirname, os.path.basename(model_filename))) SedmlSimulationWriter().run(sedml_doc, os.path.join(archive_dirname, 'simulation.sedml'), config=config) # form a description of the archive archive = CombineArchive() archive.contents.append( CombineArchiveContent( location=os.path.basename(model_filename), format=CombineArchiveContentFormat[model_language.name].value, )) archive.contents.append( CombineArchiveContent( location='simulation.sedml', format=CombineArchiveContentFormat.SED_ML.value, )) for local_path, extra_content in (extra_contents or {}).items(): shutil.copyfile(local_path, os.path.join(archive_dirname, extra_content.location)) archive.contents.append(extra_content) # save archive to file CombineArchiveWriter().run(archive, archive_dirname, archive_filename) # clean up temporary directory for archive shutil.rmtree(archive_dirname)