Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wip custom stdout capture in exec functions #64

Merged
merged 3 commits into from
May 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions biosimulators_copasi/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
from biosimulators_utils.utils.core import raise_errors_warnings
from biosimulators_utils.warnings import warn, BioSimulatorsWarning
from kisao.data_model import AlgorithmSubstitutionPolicy, ALGORITHM_SUBSTITUTION_POLICY_LEVELS
from .data_model import KISAO_ALGORITHMS_MAP, Units
from .utils import (get_algorithm_id, set_algorithm_parameter_value,
from biosimulators_copasi.data_model import KISAO_ALGORITHMS_MAP, Units
from biosimulators_copasi.utils import (get_algorithm_id, set_algorithm_parameter_value,
get_copasi_model_object_by_sbml_id, get_copasi_model_obj_sbml_ids,
fix_copasi_generated_combine_archive as fix_copasi_generated_combine_archive_func)
import COPASI
Expand Down Expand Up @@ -76,9 +76,10 @@ def exec_sedml_docs_in_combine_archive(archive_filename: str, out_dir: str, conf
return result


def exec_sed_doc(doc: Union[SedDocument, str], working_dir: str, base_out_path: str, rel_out_path: Optional[str] = None,
apply_xml_model_changes: bool = True, log: Optional[SedDocumentLog] = None, indent: int = 0,
pretty_print_modified_xml_models: bool = False, log_level=StandardOutputErrorCapturerLevel.c,
def exec_sed_doc(doc: Union[SedDocument, str], working_dir: str, base_out_path: str, rel_out_path: Optional[str] = None,
apply_xml_model_changes: bool = True, log: Optional[SedDocumentLog] = None,
indent: int = 0, pretty_print_modified_xml_models: bool = False,
log_level: Optional[Union[StandardOutputErrorCapturerLevel, str]] = StandardOutputErrorCapturerLevel.c,
config: Optional[Config] = None) -> Tuple[ReportResults, SedDocumentLog]:
""" Execute the tasks specified in a SED document and generate the specified outputs

Expand Down Expand Up @@ -146,7 +147,8 @@ def exec_sed_task(task: Task, variables: List[Variable], preprocessed_task: Opti

config = config or get_config() # noqa python:S3776

log = TaskLog() if not log and config.LOG else log # noqa python:S3776
if not log and config.LOG: # noqa python:S3776
log = TaskLog() # noqa python:S3776

if not preprocessed_task: # noqa python:S3776
preprocessed_task = preprocess_sed_task(task, variables, config=config) # noqa python:S3776
Expand Down
2 changes: 1 addition & 1 deletion biosimulators_copasi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from types import FunctionType #PR: 55
from typing import Dict, List, Tuple, Union, Optional #PR: 55
from .data_model import KISAO_ALGORITHMS_MAP, KISAO_PARAMETERS_MAP, Units
from biosimulators_copasi.data_model import KISAO_ALGORITHMS_MAP, KISAO_PARAMETERS_MAP, Units
from biosimulators_utils.combine.data_model import CombineArchiveContentFormat
from biosimulators_utils.combine.io import CombineArchiveReader, CombineArchiveWriter
from biosimulators_utils.config import get_config, Config # noqa: F401
Expand Down
320 changes: 320 additions & 0 deletions stdout_with_biocopasi.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,320 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "_YxY48I4_5n_"
},
"outputs": [],
"source": [
"!pip install biosimulators-copasi"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"id": "aFMAsiJ2MG0I"
},
"outputs": [],
"source": [
"#define a class which captures output \n",
"\n",
"from io import StringIO\n",
"import sys\n",
"\n",
"class OutputCapturer(list):\n",
" def __init__(self):\n",
" \"\"\"Implementation: with OutputCapturer() as output: \"\"\"\n",
" super().__init__()\n",
" self._stdout = None\n",
" self._stringio = None\n",
" \n",
" def __enter__(self):\n",
" self._stdout = sys.stdout\n",
" self._stringio = StringIO()\n",
" sys.stdout = self._stringio\n",
" return self\n",
" \n",
" def __exit__(self, exc_type, exc_val, exc_tb):\n",
" self.extend(self._stringio.getvalue().splitlines())\n",
" del self._stringio\n",
" sys.stdout = self._stdout\n",
" \n",
" def get_lines(self):\n",
" return self.copy()\n",
" \n",
" def get_output(self):\n",
" return '\\n'.join(self)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "p_grB5eYV0QE"
},
"source": [
"example implementation of ```OutputCapturer()```:\n",
"\n",
"\n",
"\n",
"```\n",
"def perform_operation(x0, x1):\n",
" return x0*x1 + x1*x0 \n",
"\n",
"\n",
"with OutputCapturer() as output:\n",
" x0 = 4\n",
" x1 = 6 \n",
" y = perform_operation(x0, x1)\n",
" print(y)\n",
"\n",
"output, y, output.get_output()\n",
"```\n",
"\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5W8QxB0aWI8W"
},
"source": [
"We attempt to utilize `OutputCapturer()` in place of `StandardOutputErrorCapturer()` in `biosimulators_copasi.core.exec_sed_doc()`. This method will be used as the 'task executer' in the `exec_sedml_docs_in_archive()` method."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "41w8aQndAhAi",
"outputId": "aa08abf6-80b7-414d-985a-70fb29181c94"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/usr/local/lib/python3.10/dist-packages/requests/__init__.py:102: RequestsDependencyWarning: urllib3 (1.26.15) or chardet (5.1.0)/charset_normalizer (2.0.12) doesn't match a supported version!\n",
" warnings.warn(\"urllib3 ({}) or chardet ({})/charset_normalizer ({}) doesn't match a supported \"\n"
]
}
],
"source": [
"from typing import Dict, List, Tuple, Union, Optional \n",
"from biosimulators_utils.combine.exec import exec_sedml_docs_in_archive\n",
"from biosimulators_utils.config import get_config, Config # noqa: F401\n",
"from biosimulators_utils.log.data_model import CombineArchiveLog, TaskLog, StandardOutputErrorCapturerLevel, SedDocumentLog # noqa: F401 \n",
"from biosimulators_utils.viz.data_model import VizFormat # noqa: F401\n",
"from biosimulators_utils.report.data_model import ReportFormat, VariableResults, SedDocumentResults, ReportResults # noqa: F401 \n",
"from biosimulators_utils.sedml.data_model import (Task, ModelLanguage, ModelAttributeChange, UniformTimeCourseSimulation, # noqa: F401\n",
" Variable, Symbol, SedDocument)\n",
"from biosimulators_utils.sedml import validation\n",
"from biosimulators_utils.sedml.exec import exec_sed_doc as base_exec_sed_doc\n",
"from biosimulators_utils.simulator.utils import get_algorithm_substitution_policy\n",
"from biosimulators_utils.utils.core import raise_errors_warnings\n",
"from biosimulators_utils.warnings import warn, BioSimulatorsWarning\n",
"from kisao.data_model import AlgorithmSubstitutionPolicy, ALGORITHM_SUBSTITUTION_POLICY_LEVELS\n",
"from biosimulators_copasi.core import exec_sed_task\n",
"from biosimulators_copasi.data_model import KISAO_ALGORITHMS_MAP, Units\n",
"from biosimulators_copasi.utils import (get_algorithm_id, set_algorithm_parameter_value,\n",
" get_copasi_model_object_by_sbml_id, get_copasi_model_obj_sbml_ids,\n",
" fix_copasi_generated_combine_archive as fix_copasi_generated_combine_archive_func)\n",
"import COPASI\n",
"import lxml\n",
"import math\n",
"import numpy\n",
"import os\n",
"import tempfile"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "x9mIoXBTX7f-"
},
"outputs": [],
"source": [
"#with capturer.CaptureOutput(merged=True, relay=False) as captured:"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"id": "hEeB4V8eAqRq"
},
"outputs": [],
"source": [
"#HERE USE OUTPUT CAPTURER!\n",
"\n",
"\n",
"def exec_sed_doc(doc: Union[SedDocument, str], working_dir: str, base_out_path: str, \n",
" rel_out_path: Optional[str] = None, apply_xml_model_changes: bool = True, \n",
" log: Optional[SedDocumentLog] = None, indent: int = 0, \n",
" pretty_print_modified_xml_models: bool = False, log_level=None,\n",
" config: Optional[Config] = None) -> Tuple[ReportResults, SedDocumentLog]:\n",
" \"\"\" Execute the tasks specified in a SED document and generate the specified outputs\"\"\"\n",
" \n",
" log_level = log_level or OutputCapturer()\n",
" with log_level:\n",
" results, log = base_exec_sed_doc(exec_sed_task, doc, working_dir, base_out_path,\n",
" rel_out_path=rel_out_path,\n",
" apply_xml_model_changes=apply_xml_model_changes,\n",
" log=log,\n",
" indent=indent,\n",
" pretty_print_modified_xml_models=pretty_print_modified_xml_models,\n",
" log_level=log_level,\n",
" config=config)\n",
" return {\n",
" 'log_level': log_level, \n",
" 'simulation_results': results,\n",
" 'log': log\n",
" }"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "eeAGQuGTYrmQ"
},
"outputs": [],
"source": [
"input_fp = \"/content/BIOMD0000000912_sim.sedml\"\n",
"output_fp = \"/content\"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "SZywMk37YrkD",
"outputId": "1dc7103b-bce5-4fc4-bd9e-2c9c0869f109"
},
"outputs": [
{
"data": {
"text/plain": [
"7"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "IK3Yh2W8Yrhk"
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "TU0RKbPAYrfI"
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Qoqb3Tw7YrcX"
},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"id": "tBY4Xrz5C_EK"
},
"outputs": [],
"source": [
"def exec_sedml_docs_in_combine_archive(archive_filename: str, out_dir: str, config: Optional[Config] = None,\n",
" fix_copasi_generated_combine_archive: Optional[bool] = None) -> Tuple[SedDocumentResults, CombineArchiveLog]:\n",
" \"\"\" Execute the SED tasks defined in a COMBINE/OMEX archive and save the outputs\"\"\"\n",
" \n",
" if fix_copasi_generated_combine_archive is None: # noqa python:S3776\n",
" fix_copasi_generated_combine_archive = os.getenv('FIX_COPASI_GENERATED_COMBINE_ARCHIVE', '0').lower() in ['1', 'true'] # noqa python:S3776\n",
"\n",
" if fix_copasi_generated_combine_archive: # noqa python:S3776\n",
" temp_archive_file, temp_archive_filename = tempfile.mkstemp()\n",
" os.close(temp_archive_file)\n",
" fix_copasi_generated_combine_archive_func(archive_filename, temp_archive_filename)\n",
" archive_filename = temp_archive_filename\n",
"\n",
" result = exec_sedml_docs_in_archive(exec_sed_doc, archive_filename, out_dir,\n",
" apply_xml_model_changes=True,\n",
" config=config)\n",
" if fix_copasi_generated_combine_archive: # noqa python:S3776\n",
" os.remove(temp_archive_filename)\n",
"\n",
" return result"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "unWUAzgTDHay"
},
"outputs": [],
"source": [
"try:\n",
" with capturer.CaptureOutput(merged=True, relay=False) as captured:\n",
" exec_sedml_docs_in_archive(\n",
" archive_filename, \n",
" output_dir, \n",
" simulator=Simulator(), \n",
" model_language=model_language, \n",
" outputs=outputs, \n",
" sbml_files=sbml_files, \n",
" validate=validate, \n",
" **kwargs)\n",
"\n",
" except Exception as exception:\n",
" # ...\n",
" # Keep the lines that log the captured output\n",
" # ...\n",
"\n",
" return results, captured.get_captured_text()"
]
}
],
"metadata": {
"colab": {
"provenance": []
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
}
},
"nbformat": 4,
"nbformat_minor": 0
}