Added ability to pre-process and statically render notebooks, untested
@@ -40,8 +40,9 @@ Free Energy Required Arguments:
YANK Health Report Arguments:
-o=REPORT, --output=REPORT Name of the health report Jupyter notebook or static file, can use a path + name as well
If the filename ends in .pdf or .html, the notebook is auto run and converted to a
- static PDF or HTML file respectively.
- Static generation may be slow!
+ static PDF or HTML file respectively
+ PDF requires xelatex binary in OS path, often provided by LaTeX packages
+ Static generation may be slow
Extract Trajectory Required Arguments:
--netcdf=FILEPATH Path to the NetCDF file.
@@ -120,7 +121,9 @@ def dispatch_report(args):
# Check modules for render
store = args['--store']
output = args['--output']
- file_base_name, file_extension = os.path.splitext(output)
+ file_full_path, file_extension = os.path.splitext(output)
+ _, file_base_name = os.path.split(file_full_path)
+ # PDF requires xelatex binary in the OS (provided by LaTeX such as TeXLive and MiKTeX)
static_extensions = [".pdf", ".html"]
try:
import matplotlib
@@ -141,6 +144,41 @@ def dispatch_report(args):
if file_extension.lower() in static_extensions:
# Cast to static ouptput
print("Rendering notebook as static file...")
+ import nbformat
+ from nbconvert.preprocessors import ExecutePreprocessor
+ import nbconvert.exporters
+ # Categorize exporters based on extension, requires exporter object and data type output
+ # 'b' = byte types output, e.g. PDF
+ # 't' = text based output, e.g. HTML or even raw notebook, human-readable-like
+ exporters = {".pdf": {'exporter': nbconvert.exporters.PDFExporter, 'write_type': 'b'},
+ ".html": {'exporter': nbconvert.exporters.HTMLExporter, 'write_type': 't'}
+ }
+ temporary_directory = analyze.mmtools.utils.temporary_directory
+ with temporary_directory() as tmp_dir_path:
+ temp_notebook_name = "tmp_notebook.ipynb"
+ tmp_nb_path = os.path.join(tmp_dir_path, temp_notebook_name)
+ # Write out temporary notebook to raw text
+ with open(tmp_nb_path, 'w') as tmp_notebook:
+ tmp_notebook.write(notebook_text)
+ # Read the temp notebook into a notebook_node object nbconvert can work with
+ with open(tmp_nb_path, 'r') as tmp_notebook:
+ loaded_notebook = nbformat.read(tmp_notebook, as_version=4)
+ ep = ExecutePreprocessor()
+ # Set the title name, does not appear in all exporters
+ resource_data = {'metadata': {'name': 'YANK Simulation Report: {}'.format(file_base_name)}}
+ # Process notebook
+ print("Processing notebook now, this may take a while...")
+ processed_notebook, resources = ep.preprocess(loaded_notebook, resource_data)
+ # Retrieve exporter
+ exporter_data = exporters[file_extension.lower()]
+ # Determine exporter and data output type
+ exporter = exporter_data['exporter']
+ write_type = exporter_data['write_type']
+ with open(output, 'w{}'.format(write_type)) as notebook:
+ exported_notebook, _ = nbconvert.exporters.export(exporter, processed_notebook, resources=resources)
+ notebook.write(exported_notebook)
+ else:
+ # No pre-rendering, no need to process anything
with open(output, 'w') as notebook:
notebook.write(notebook_text)
