Skip to content

Commit

Permalink
feat: updated to Biosimulators-utils 0.1.114: organized options, adde…
Browse files Browse the repository at this point in the history
…d option to control logging; added Python package to specs; added fonts to Docker image
  • Loading branch information
jonrkarr committed Sep 1, 2021
1 parent 69f5bf5 commit 6b76949
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 57 deletions.
5 changes: 5 additions & 0 deletions Dockerfile-pyneuroml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ RUN mkdir -p /usr/share/man/man1/ \
&& apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/*

# 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_pyNeuroML
RUN pip install /root/Biosimulators_pyNeuroML \
Expand Down
11 changes: 10 additions & 1 deletion biosimulators-netpyne.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
},
"operatingSystemType": "Linux"
},
"pythonApi": {
"package": "biosimulators-pyneuroml",
"module": "biosimulators_pyneuroml.api.netpyne"
},
"authors": [
{
"firstName": "Salvador",
Expand Down Expand Up @@ -105,7 +109,12 @@
"namespace": "pypi",
"id": "netpyne",
"url": "https://pypi.org/project/netpyne"
}
},
{
"namespace": "pypi",
"id": "biosimulators-pyneuroml",
"url": "https://pypi.org/project/biosimulators-pyneuroml/"
}
],
"citations": [
{
Expand Down
11 changes: 10 additions & 1 deletion biosimulators-neuron.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
},
"operatingSystemType": "Linux"
},
"pythonApi": {
"package": "biosimulators-pyneuroml",
"module": "biosimulators_pyneuroml.api.neuron"
},
"authors": [
{
"firstName": "Michael",
Expand Down Expand Up @@ -89,7 +93,12 @@
"namespace": "pypi",
"id": "NEURON",
"url": "https://pypi.org/project/NEURON"
}
},
{
"namespace": "pypi",
"id": "biosimulators-pyneuroml",
"url": "https://pypi.org/project/biosimulators-pyneuroml/"
}
],
"citations": [
{
Expand Down
11 changes: 10 additions & 1 deletion biosimulators-pyneuroml.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
},
"operatingSystemType": "Linux"
},
"pythonApi": {
"package": "biosimulators-pyneuroml",
"module": "biosimulators_pyneuroml.api.pyneuroml"
},
"authors": [
{
"firstName": "Padraig",
Expand Down Expand Up @@ -62,7 +66,12 @@
"namespace": "pypi",
"id": "pyNeuroML",
"url": "https://pypi.org/project/pyNeuroML"
}
},
{
"namespace": "pypi",
"id": "biosimulators-pyneuroml",
"url": "https://pypi.org/project/biosimulators-pyneuroml/"
}
],
"citations": [
{
Expand Down
51 changes: 22 additions & 29 deletions biosimulators_pyneuroml/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .data_model import Simulator, KISAO_ALGORITHM_MAP, SEDML_TIME_OUTPUT_COLUMN_ID, SEDML_OUTPUT_FILE_ID
from .utils import validate_task, read_xml_file, set_sim_in_lems_xml, run_lems_xml, get_simulator_run_lems_method
from biosimulators_utils.combine.exec import exec_sedml_docs_in_archive
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
Expand All @@ -25,10 +26,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,
config=None,
simulator=Simulator.pyneuroml):
""" Execute the SED tasks defined in a COMBINE/OMEX archive and save the outputs
Expand All @@ -41,13 +39,8 @@ 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
simulator (:obj:`Simulator`, optional): simulator
raise_exceptions (:obj:`bool`, optional): whether to raise exceptions
config (:obj:`Config`, optional): BioSimulators common configuration
Returns:
:obj:`tuple`:
Expand All @@ -58,21 +51,17 @@ def exec_sedml_docs_in_combine_archive(archive_filename, out_dir,
sed_doc_executer = functools.partial(exec_sed_doc, functools.partial(exec_sed_task, simulator=simulator))
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, simulator=Simulator.pyneuroml):
def exec_sed_task(task, variables, log=None, config=None, simulator=Simulator.pyneuroml):
''' 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
simulator (:obj:`Simulator`, optional): simulator
Returns:
Expand All @@ -86,17 +75,20 @@ def exec_sed_task(task, variables, log=None, simulator=Simulator.pyneuroml):
could not be recorded
:obj:`NotImplementedError`: if the task is not of a supported type or involves an unsuported feature
'''
log = log or TaskLog()
config = config or get_config()
if config.LOG and not log:
log = TaskLog()

sim = task.simulation
sim.algorithm = copy.deepcopy(sim.algorithm)
sim.algorithm.kisao_id = validate_task(task, variables, simulator)
sim.algorithm.kisao_id = validate_task(task, variables, simulator, config=config)

lems_root = read_xml_file(task.model.source)

set_sim_in_lems_xml(lems_root, task, variables)
lems_results = run_lems_xml(lems_root, working_dirname=os.path.dirname(
task.model.source), lems_filename=task.model.source)[SEDML_OUTPUT_FILE_ID]
task.model.source), lems_filename=task.model.source,
verbose=config.VERBOSE, config=config)[SEDML_OUTPUT_FILE_ID]

# transform the results to an instance of :obj:`VariableResults`
variable_results = VariableResults()
Expand All @@ -110,15 +102,16 @@ def exec_sed_task(task, variables, log=None, simulator=Simulator.pyneuroml):
variable_results[variable.id] = lems_result.to_numpy()[-(sim.number_of_points + 1):]

# log action
log.algorithm = sim.algorithm.kisao_id
log.simulator_details = {
'method': 'pyneuroml.pynml.' + get_simulator_run_lems_method(simulator).__name__,
'lemsSimulation': {
'length': '{}s'.format(sim.output_end_time),
'step': '{}s'.format((sim.output_end_time - sim.output_start_time) / sim.number_of_steps),
'method': KISAO_ALGORITHM_MAP[sim.algorithm.kisao_id]['id'],
},
}
if config.LOG:
log.algorithm = sim.algorithm.kisao_id
log.simulator_details = {
'method': 'pyneuroml.pynml.' + get_simulator_run_lems_method(simulator).__name__,
'lemsSimulation': {
'length': '{}s'.format(sim.output_end_time),
'step': '{}s'.format((sim.output_end_time - sim.output_start_time) / sim.number_of_steps),
'method': KISAO_ALGORITHM_MAP[sim.algorithm.kisao_id]['id'],
},
}

# return results and log
return variable_results, log
26 changes: 14 additions & 12 deletions biosimulators_pyneuroml/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,19 @@
]


def validate_task(task, variables, simulator):
def validate_task(task, variables, simulator, config=None):
""" Validate a task
Args:
task (:obj:`Task`): task
variables (:obj:`list` of :obj:`Variable`): variables
simulator (:obj:`Simulator`): simulator
config (:obj:`Config`, optional): BioSimulators common configuration
Returns:
:obj:`str`: KiSAO id for a possibly alternative simulation algorithm
"""
config = get_config()
config = config or get_config()

model = task.model
sim = task.simulation
Expand Down Expand Up @@ -90,7 +91,7 @@ def validate_task(task, variables, simulator):
simulator_kisao_alg_map = {kisao_id: alg_props for kisao_id,
alg_props in KISAO_ALGORITHM_MAP.items() if simulator in alg_props['simulators']}

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(
sim.algorithm.kisao_id, simulator_kisao_alg_map.keys(),
substitution_policy=algorithm_substitution_policy)
Expand Down Expand Up @@ -159,7 +160,8 @@ def set_sim_in_lems_xml(lems_xml_root, task, variables):


def run_lems_xml(lems_xml_root, working_dirname='.', lems_filename=None,
simulator=Simulator.pyneuroml, num_processors=None, max_memory=None, verbose=None):
simulator=Simulator.pyneuroml, num_processors=None, max_memory=None, verbose=False,
config=None):
"""Run a LEMS document with a simulator
Args:
Expand All @@ -170,11 +172,13 @@ def run_lems_xml(lems_xml_root, working_dirname='.', lems_filename=None,
num_processors (:obj:`int`, optional): number of processors to use (only used with NetPyNe)
max_memory (:obj:`int`, optional): maximum memory to use in bytes
verbose (:obj:`bool`, optional): whether to display extra information about simulation runs
config (:obj:`Config`, optional): BioSimulators common configuration
Returns:
:obj:`dict` of :obj:`str` => :obj:`pandas.DataFrame`: dictionary that maps the id of each output file
to a Pandas data frame with its value
"""
config = config or get_config()
run_lems_method = get_simulator_run_lems_method(simulator)
options = get_run_lems_options(num_processors=num_processors, max_memory=max_memory, verbose=verbose)

Expand All @@ -194,16 +198,17 @@ def run_lems_xml(lems_xml_root, working_dirname='.', lems_filename=None,

results_dirname = tempfile.mkdtemp()
options.exec_in_dir = results_dirname
with StandardOutputErrorCapturer(relay=options.verbose) as captured:
with StandardOutputErrorCapturer(relay=options.verbose, disabled=not config.LOG) as captured:
result = run_lems_method(temp_filename, **options.to_kw_args(simulator))
if not result:
os.remove(temp_filename)
shutil.rmtree(results_dirname)

msg = '`{}` was not able to execute {}:\n\n {}'.format(
msg = '`{}` was not able to execute {}'.format(
simulator.value,
'`{}`'.format(lems_filename) if lems_filename else 'the LEMS document',
captured.get_text().replace('\n', '\n '))
'`{}`'.format(lems_filename) if lems_filename else 'the LEMS document')
if config.LOG:
msg += '\n\n ' + captured.get_text().replace('\n', '\n ')
raise RuntimeError(msg)

# read results
Expand Down Expand Up @@ -242,7 +247,7 @@ def get_simulator_run_lems_method(simulator):
raise NotImplementedError('`{}` is not a supported simulator.'.format(simulator))


def get_run_lems_options(num_processors=None, max_memory=None, verbose=None):
def get_run_lems_options(num_processors=None, max_memory=None, verbose=False):
""" Get options for running a LEMS document
Args:
Expand All @@ -259,9 +264,6 @@ def get_run_lems_options(num_processors=None, max_memory=None, verbose=None):
if max_memory is None:
max_memory = get_available_memory() - 100 * 1000000

if verbose is None:
verbose = get_config().VERBOSE

options = RunLemsOptions(num_processors=num_processors, max_memory=max_memory, verbose=verbose)

return options
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
biosimulators_utils[neuroml,lems,logging] >= 0.1.104
biosimulators_utils[neuroml,lems,logging] >= 0.1.114
kisao
lxml
numpy
Expand Down
31 changes: 19 additions & 12 deletions tests/test_core_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from biosimulators_pyneuroml.data_model import Simulator, SIMULATOR_ENABLED, KISAO_ALGORITHM_MAP
from biosimulators_utils.combine import data_model as combine_data_model
from biosimulators_utils.combine.io import CombineArchiveWriter
from biosimulators_utils.config import get_config
from biosimulators_utils.log.data_model import TaskLog
from biosimulators_utils.report import data_model as report_data_model
from biosimulators_utils.report.io import ReportReader
Expand Down Expand Up @@ -74,12 +75,15 @@ def test_exec_sedml_docs_in_combine_archive(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)

Expand All @@ -91,12 +95,15 @@ def test_exec_sedml_docs_in_combine_archive_with_all_algorithms(self):
doc, archive_filename = self._build_combine_archive(algorithm=alg)

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)

Expand Down

0 comments on commit 6b76949

Please sign in to comment.