Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
c1275a0
add functions for testing remotely to init and update ipynb testing file
stellaprins Jul 3, 2024
55585f5
Merge pull request #34 from OpenSourceBrain/feature/test_feature_actions
stellaprins Jul 3, 2024
fac0989
Update non-omv.yml
pgleeson Jul 3, 2024
662b722
add unzip_file function and update ipynb for testing
stellaprins Jul 3, 2024
81ef1b0
Merge branch 'development' into feature/32-test-compatibility-biosimu…
stellaprins Jul 3, 2024
a68d11d
Merge branch 'feature/31-create-lems_nml2_ex9_fn-docker-results-table…
stellaprins Jul 3, 2024
bff7036
import functions from pyneuroml biosimulators fork
stellaprins Jul 4, 2024
bdc0132
change name function (parse_error_message to ansi_to_html)
stellaprins Jul 4, 2024
f85ffeb
use biosimulations.get_simulator_versions to determine engine_version
stellaprins Jul 4, 2024
218053c
remove print for d1 plot filepaths in move_d1_files
stellaprins Jul 4, 2024
7ae14fd
add back log.yml functionality in run_biosimulators_docker
stellaprins Jul 4, 2024
8efc401
add tests and table for compatibility biosimulators remote
stellaprins Jul 5, 2024
09ac975
add command line script for testing compatability biosimulators remotely
stellaprins Jul 5, 2024
7f95aff
adjust for changes in pyneuroml development biosimulators module
stellaprins Jul 31, 2024
de0969e
Merge branch 'master' into feature/32-test-compatibility-biosimulator…
stellaprins Jul 31, 2024
9cc2cae
Refactor test compatibility biosimulators script and workflow
stellaprins Aug 5, 2024
6c7b12d
read log.yml file for error messages
stellaprins Aug 5, 2024
b2fbbe0
combine local and remote biosimulators compatibility tables and refac…
stellaprins Aug 6, 2024
7aba39c
fix local d1 plots links in results table
stellaprins Aug 6, 2024
283fcfb
remove seperate remote script and results table after integration
stellaprins Aug 6, 2024
9a2583b
remove display_markdown since it is not being used in test_compatibil…
stellaprins Aug 7, 2024
9af99fc
add #!/usr/bin/env python on top of test_compatibility_biosimulators
stellaprins Aug 7, 2024
890ef16
changing None to 'unknown' for engine string if not found in move_d1_…
stellaprins Aug 7, 2024
5a61e74
added back parser for --output-dir d1_plots
stellaprins Aug 7, 2024
c479d67
add closing bracket
stellaprins Aug 7, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/non-omv.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ jobs:

- name: Test validity of files
run: |
pip install pyNeuroML
pip install pyNeuroML pyNeuroML[annotations]
cd SBML
./validateAll.sh

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added SBML/d1_plots_remote/amici_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/bionetgen_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/boolnet_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/cbmpy_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/cobrapy_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/copasi_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/gillespy2_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/ginsim_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/libsbmlsim_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/masspy_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/pysces_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/rbapy_d1.pdf
Binary file not shown.
Binary file added SBML/d1_plots_remote/tellurium_d1.pdf
Binary file not shown.
46 changes: 23 additions & 23 deletions SBML/results_compatibility_biosimulators.md

Large diffs are not rendered by default.

912 changes: 866 additions & 46 deletions SBML/test_compatibility_biosimulators.ipynb

Large diffs are not rendered by default.

125 changes: 93 additions & 32 deletions SBML/test_compatibility_biosimulators.py
Copy link
Collaborator

@robertvi robertvi Aug 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "#!/usr/bin/env python" line has to be the first line in order to work. So it should either be removed or moved to the first line. I think the two python comments above and below it can be combined into one?

Original file line number Diff line number Diff line change
Expand Up @@ -3,61 +3,122 @@
It runs each engine and records the result (pass/fail) and any error messages encountered during the simulation.
The results are then displayed in a table and saved to a markdown file.
'''
#!/usr/bin/env python

'''
use pymetadata module to create a minimal valid combine archive
using LEMS_NML2_Ex9_FN.sbml and LEMS_NML2_Ex9_FN.sedml
'''

import sys
sys.path.append("..")
import utils
import os
import pandas as pd
from IPython.display import display_markdown
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display_markdown seems not to be needed in this script? Therefore we could probably remove the requirement for IPython?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Done! :)

import shutil
import argparse

parser = argparse.ArgumentParser(description='Test compatibility of different biosimulation engines')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The --output-dir option is still being passed to the script in the non-oml.yml GH action, but is ignored due to this code block being removed. It might be useful to retain this option to allow easy testing without being forced to overwrite an existing output folder that you want to keep?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Done.

parser.add_argument('--output-dir',action='store',default='d1_plots',help='Where to move the output pdf plots to')
args = parser.parse_args()
import yaml

sbml_filepath = 'LEMS_NML2_Ex9_FN.sbml'
sedml_filepath = 'LEMS_NML2_Ex9_FN_missing_xmlns.sedml' #xmlns:sbml missing (original file)
sedml_filepath = 'LEMS_NML2_Ex9_FN_missing_xmlns.sedml' #xmlns:sbml missing

engines = utils.engines
types_dict = utils.types_dict

engine_dict = {}

output_folder = 'output' #initial temporary output folder
#########################################################################################
# Run remotely
#########################################################################################

remote_output_dir = 'remote_results'

download_links_dict = dict()
for e in engines.keys():
download_link = utils.run_biosimulators_remote(e, sedml_filepath, sbml_filepath)
download_links_dict[e] = download_link

extract_dir_dict = dict()
for e, link in download_links_dict.items():
extract_dir = utils.get_remote_results(e, link, remote_output_dir)
extract_dir_dict[e] = extract_dir

results = dict()
for e, extract_dir in extract_dir_dict.items():
status = ""
error_message = ""
exception_type = ""

log_yml_path = utils.find_file_in_dir('log.yml', extract_dir)[0]
if not log_yml_path:
status = None
error_message = 'log.yml not found'
continue
with open(log_yml_path) as f:
log_yml_dict = yaml.safe_load(f)
if log_yml_dict['status'] == 'SUCCEEDED':
status = 'pass'
elif log_yml_dict['status'] == 'FAILED':
status = 'FAIL'
exception = log_yml_dict['exception']
error_message = exception['message']
exception_type = exception['type']
else:
status = None
results[e] = [status, error_message, exception_type]

file_paths = utils.find_files(remote_output_dir, '.pdf')
utils.move_d1_files(file_paths, 'd1_plots_remote')

# remove the remote results directory
if os.path.exists(remote_output_dir):
shutil.rmtree(remote_output_dir)
print('Removed ' + remote_output_dir + ' folder')

#########################################################################################
# Run locally
#########################################################################################

results_local = {}

output_folder = 'output'

for e in engines.keys():
print('Running ' + e)
output_dir = os.path.abspath(os.path.join(output_folder, e))
engine_dict[e] = utils.run_biosimulators_docker(e, sedml_filepath, sbml_filepath, output_dir=output_dir)
utils.move_d1_files(utils.find_files(output_dir, '.pdf'), e, args.output_dir)
record = utils.run_biosimulators_docker(e, sedml_filepath, sbml_filepath, output_dir=output_dir)
results_local[e] = record

file_paths = utils.find_files(output_folder, '.pdf')
utils.move_d1_files(file_paths, 'd1_plots_local')

shutil.rmtree(output_folder)
# if it exists remove the output folder
if os.path.exists(output_folder):
shutil.rmtree(output_folder)
print('Removed ' + output_folder + ' folder')

# TODO: move part that creates table to utils
# Create a table of the results
results_table = pd.DataFrame.from_dict(engine_dict).T
results_table.columns = ['pass/FAIL', 'Error']
results_table.index.name = 'Engine'
results_table.reset_index(inplace=True)
#########################################################################################
# process results and save markdown table
#########################################################################################

results_table['Error'] = results_table.apply(lambda x: None if x['pass/FAIL'] == x['Error'] else x['Error'], axis=1)
results_table['pass/FAIL'] = results_table['pass/FAIL'].replace('other', 'FAIL')
results_table = utils.create_results_table(results, types_dict, sbml_filepath, sedml_filepath, engines, 'd1_plots_remote')
results_table_local = utils.create_results_table(results_local, types_dict, sbml_filepath, sedml_filepath, engines, 'd1_plots_local')

results_table['Error'] = results_table['Error'].apply(lambda x: utils.parse_error_message(x))
results_table['Error'] = results_table['Error'].apply(lambda x: utils.collapsible_content(x))
# rename cols to distinguish between local and remote results except for Engine column
results_table.columns = [str(col) + ' (remote)' if col != 'Engine' else str(col) for col in results_table.columns]
results_table_local.columns = [str(col) + ' (local)' if col != 'Engine' else str(col) for col in results_table_local.columns]

results_table['Compatibility'] = results_table['Engine'].apply(lambda x: utils.check_file_compatibility_test(x, types_dict, sbml_filepath, sedml_filepath))
results_table['Compatibility'] = results_table['Compatibility'].apply(lambda x: utils.collapsible_content(x[1], title=x[0]))
results_table['pass/FAIL'] = results_table['pass/FAIL'].apply(lambda x: f'<span style="color:darkred;">{x}</span>' if x == 'FAIL' else x)
results_table['Compatibility'] = results_table['Compatibility'].apply(lambda x: f'<span style="color:darkred;">{x}</span>' if 'FAIL' in x else x)
# combine remote and local results
combined_results = pd.merge(results_table, results_table_local, on='Engine', how='outer')
combined_results = combined_results.reindex(columns=['Engine'] + sorted(combined_results.columns[1:]))

# d1 plot clickable link
results_table['d1'] = results_table['Engine'].apply(lambda x: utils.d1_plots_dict(engines, args.output_dir).get(x, None))
results_table['d1'] = results_table['d1'].apply(lambda x: utils.create_hyperlink(x))
cols_order = ['Engine', 'pass/FAIL (remote)', 'pass/FAIL (local)',\
'Compatibility (remote)', 'Compatibility (local)', \
'Type (remote)', \
'Error (remote)', 'Error (local)', \
'd1 (remote)', 'd1 (local)']

results_table = results_table.to_markdown(index=False)
combined_results = combined_results[cols_order]

# save results_md_table
with open('results_compatibility_biosimulators.md', 'w', encoding='utf-8') as f:
f.write(results_table)
# save the results to a markdown file
with open('results_compatibility_biosimulators.md', 'w') as f:
f.write(combined_results.to_markdown())
Loading