diff --git a/Dockerfile b/Dockerfile index 3dfdce2..e9fb3e1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ # Base OS FROM python:3.9-slim-buster -ARG VERSION="0.1.14" +ARG VERSION="0.1.15" ARG SIMULATOR_VERSION="0.22.1" # metadata @@ -41,6 +41,11 @@ LABEL \ about.tags="constraint-based modeling,flux balance analysis,systems biology,biochemical networks,SBML,SED-ML,COMBINE,OMEX,BioSimulators" \ maintainer="BioSimulators Team " +# fonts for matplotlib +RUN apt-get update -y \ + && apt-get install -y --no-install-recommends libfreetype6 \ + && rm -rf /var/lib/apt/lists/* + # Copy code for command-line interface into image and install it COPY . /root/Biosimulators_COBRApy RUN pip install /root/Biosimulators_COBRApy \ diff --git a/biosimulators.json b/biosimulators.json index 29edc3d..082e2e4 100644 --- a/biosimulators.json +++ b/biosimulators.json @@ -19,6 +19,10 @@ }, "operatingSystemType": "Linux" }, + "pythonApi": { + "package": "biosimulators-cobrapy", + "module": "biosimulators_cobrapy" + }, "authors": [ { "firstName": "Ali", diff --git a/biosimulators_cobrapy/_version.py b/biosimulators_cobrapy/_version.py index 112abf1..ac1125f 100644 --- a/biosimulators_cobrapy/_version.py +++ b/biosimulators_cobrapy/_version.py @@ -1 +1 @@ -__version__ = '0.1.14' +__version__ = '0.1.15' diff --git a/biosimulators_cobrapy/core.py b/biosimulators_cobrapy/core.py index 5050674..85f5e59 100644 --- a/biosimulators_cobrapy/core.py +++ b/biosimulators_cobrapy/core.py @@ -10,7 +10,7 @@ from .utils import (get_active_objective_sbml_fbc_id, set_simulation_method_arg, apply_variables_to_simulation_method_args, validate_variables, get_results_of_variables) from biosimulators_utils.combine.exec import exec_sedml_docs_in_archive -from biosimulators_utils.config import get_config +from biosimulators_utils.config import get_config, Config # noqa: F401 from biosimulators_utils.log.data_model import CombineArchiveLog, TaskLog # noqa: F401 from biosimulators_utils.viz.data_model import VizFormat # noqa: F401 from biosimulators_utils.report.data_model import ReportFormat, VariableResults, SedDocumentResults # noqa: F401 @@ -34,11 +34,7 @@ ] -def exec_sedml_docs_in_combine_archive(archive_filename, out_dir, - return_results=False, - report_formats=None, plot_formats=None, - bundle_outputs=None, keep_individual_outputs=None, - raise_exceptions=True): +def exec_sedml_docs_in_combine_archive(archive_filename, out_dir, config=None): """ Execute the SED tasks defined in a COMBINE/OMEX archive and save the outputs Args: @@ -50,12 +46,7 @@ def exec_sedml_docs_in_combine_archive(archive_filename, out_dir, * HDF5: directory in which to save a single HDF5 file (``{ out_dir }/reports.h5``), with reports at keys ``{ relative-path-to-SED-ML-file-within-archive }/{ report.id }`` within the HDF5 file - return_results (:obj:`bool`, optional): whether to return the result of each output of each SED-ML file - report_formats (:obj:`list` of :obj:`ReportFormat`, optional): report format (e.g., csv or h5) - plot_formats (:obj:`list` of :obj:`VizFormat`, optional): report format (e.g., pdf) - bundle_outputs (:obj:`bool`, optional): if :obj:`True`, bundle outputs into archives for reports and plots - keep_individual_outputs (:obj:`bool`, optional): if :obj:`True`, keep individual output files - raise_exceptions (:obj:`bool`, optional): whether to raise exceptions + config (:obj:`Config`, optional): BioSimulators common configuration Returns: :obj:`tuple`: @@ -66,21 +57,17 @@ def exec_sedml_docs_in_combine_archive(archive_filename, out_dir, sed_doc_executer = functools.partial(exec_sed_doc, exec_sed_task) return exec_sedml_docs_in_archive(sed_doc_executer, archive_filename, out_dir, apply_xml_model_changes=True, - return_results=return_results, - report_formats=report_formats, - plot_formats=plot_formats, - bundle_outputs=bundle_outputs, - keep_individual_outputs=keep_individual_outputs, - raise_exceptions=raise_exceptions) + config=config) -def exec_sed_task(task, variables, log=None): +def exec_sed_task(task, variables, log=None, config=None): ''' Execute a task and save its results Args: task (:obj:`Task`): task variables (:obj:`list` of :obj:`Variable`): variables that should be recorded log (:obj:`TaskLog`, optional): log for the task + config (:obj:`Config`, optional): BioSimulators common configuration Returns: :obj:`tuple`: @@ -93,9 +80,10 @@ def exec_sed_task(task, variables, log=None): could not be recorded :obj:`NotImplementedError`: if the task is not of a supported type or involves an unsuported feature ''' - config = get_config() + config = config or get_config() - log = log or TaskLog() + if config.LOG and not log: + log = TaskLog() model = task.model sim = task.simulation @@ -132,7 +120,7 @@ def exec_sed_task(task, variables, log=None): # Load the simulation method specified by ``simulation.algorithm`` simulation = task.simulation algorithm_kisao_id = simulation.algorithm.kisao_id - algorithm_substitution_policy = get_algorithm_substitution_policy() + algorithm_substitution_policy = get_algorithm_substitution_policy(config=config) exec_kisao_id = get_preferred_substitute_algorithm_by_ids( simulation.algorithm.kisao_id, KISAO_ALGORITHMS_PARAMETERS_MAP.keys(), substitution_policy=algorithm_substitution_policy) @@ -187,11 +175,12 @@ def exec_sed_task(task, variables, log=None): active_objective_fbc_id, method_props, variables, solution) # log action - log.algorithm = exec_kisao_id - log.simulator_details = { - 'method': method_props['method'].__module__ + '.' + method_props['method'].__name__, - 'arguments': method_kw_args, - } + if config.LOG: + log.algorithm = exec_kisao_id + log.simulator_details = { + 'method': method_props['method'].__module__ + '.' + method_props['method'].__name__, + 'arguments': method_kw_args, + } # Return the results of each variable and log return variable_results, log diff --git a/requirements.txt b/requirements.txt index f01be17..6efb2f5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -biosimulators_utils[logging] >= 0.1.104 +biosimulators_utils[logging] >= 0.1.114 cobra kisao lxml diff --git a/tests/test_core_main.py b/tests/test_core_main.py index 8b9de09..500808e 100644 --- a/tests/test_core_main.py +++ b/tests/test_core_main.py @@ -11,6 +11,7 @@ from biosimulators_utils.combine import data_model as combine_data_model from biosimulators_utils.combine.exceptions import CombineArchiveExecutionError from biosimulators_utils.combine.io import CombineArchiveWriter +from biosimulators_utils.config import get_config from biosimulators_utils.report import data_model as report_data_model from biosimulators_utils.report.io import ReportReader from biosimulators_utils.simulator.exec import exec_sedml_docs_in_archive_with_containerized_simulator @@ -211,7 +212,9 @@ def test_exec_sed_task_error_handling(self): _, archive_filename = self._build_combine_archive(algorithm=sedml_data_model.Algorithm(kisao_id='KISAO_0000448')) with self.assertRaisesRegex(CombineArchiveExecutionError, 'No algorithm can be substituted'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception _, archive_filename = self._build_combine_archive( algorithm=sedml_data_model.Algorithm( @@ -220,11 +223,15 @@ def test_exec_sed_task_error_handling(self): )) with mock.patch.dict('os.environ', {'ALGORITHM_SUBSTITUTION_POLICY': 'NONE'}): with self.assertRaisesRegex(CombineArchiveExecutionError, 'is not a valid'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception with mock.patch.dict('os.environ', {'ALGORITHM_SUBSTITUTION_POLICY': 'SIMILAR_VARIABLES'}): with self.assertWarnsRegex(BioSimulatorsWarning, 'Unsuported value'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception _, archive_filename = self._build_combine_archive( algorithm=sedml_data_model.Algorithm( @@ -233,11 +240,15 @@ def test_exec_sed_task_error_handling(self): )) with mock.patch.dict('os.environ', {'ALGORITHM_SUBSTITUTION_POLICY': 'NONE'}): with self.assertRaisesRegex(CombineArchiveExecutionError, 'not a valid value'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception with mock.patch.dict('os.environ', {'ALGORITHM_SUBSTITUTION_POLICY': 'SIMILAR_VARIABLES'}): with self.assertWarnsRegex(BioSimulatorsWarning, 'Unsuported value'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception _, archive_filename = self._build_combine_archive( algorithm=sedml_data_model.Algorithm( @@ -246,11 +257,15 @@ def test_exec_sed_task_error_handling(self): )) with mock.patch.dict('os.environ', {'ALGORITHM_SUBSTITUTION_POLICY': 'NONE'}): with self.assertRaisesRegex(CombineArchiveExecutionError, 'does not support parameter'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception with mock.patch.dict('os.environ', {'ALGORITHM_SUBSTITUTION_POLICY': 'SIMILAR_VARIABLES'}): with self.assertWarnsRegex(BioSimulatorsWarning, 'does not support parameter'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception # no solution model_changes = [ @@ -262,18 +277,23 @@ def test_exec_sed_task_error_handling(self): ] _, archive_filename = self._build_combine_archive(model_changes=model_changes) with self.assertRaisesRegex(CombineArchiveExecutionError, 'could not be found'): - core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, self.dirname) + if log.exception: + raise log.exception def test_exec_sedml_docs_in_combine_archive_successfully(self): doc, archive_filename = self._build_combine_archive() out_dir = os.path.join(self.dirname, 'out') - core.exec_sedml_docs_in_combine_archive(archive_filename, out_dir, - report_formats=[ - report_data_model.ReportFormat.h5, - ], - bundle_outputs=True, - keep_individual_outputs=True) + + config = get_config() + config.REPORT_FORMATS = [report_data_model.ReportFormat.h5] + config.BUNDLE_OUTPUTS = True + config.KEEP_INDIVIDUAL_OUTPUTS = True + + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, out_dir, config=config) + if log.exception: + raise log.exception self._assert_combine_archive_outputs(doc, out_dir) @@ -567,12 +587,15 @@ def test_exec_sedml_docs_in_combine_archive_with_all_algorithms(self): for alg in gen_algorithms_from_specs(os.path.join(os.path.dirname(__file__), '..', 'biosimulators.json')).values(): doc, archive_filename = self._build_combine_archive(algorithm=alg) out_dir = os.path.join(self.dirname, alg.kisao_id) - core.exec_sedml_docs_in_combine_archive(archive_filename, out_dir, - report_formats=[ - report_data_model.ReportFormat.h5, - ], - bundle_outputs=True, - keep_individual_outputs=True) + + config = get_config() + config.REPORT_FORMATS = [report_data_model.ReportFormat.h5] + config.BUNDLE_OUTPUTS = True + config.KEEP_INDIVIDUAL_OUTPUTS = True + + _, log = core.exec_sedml_docs_in_combine_archive(archive_filename, out_dir, config=config) + if log.exception: + raise log.exception self._assert_combine_archive_outputs(doc, out_dir)