Skip to content

Commit ec58f42

Browse files
committed
Merge branch 'notebook_interface' into develop
2 parents 654b725 + 24b0836 commit ec58f42

36 files changed

+3677
-1081
lines changed

bin/ipynb_to_report

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ output_filename="$(echo ${report_nb} | sed 's/ /_/g' | sed 's/.ipynb$//').tex"
99
export TEXINPUTS="${template_dir}//:"
1010

1111
jupyter nbconvert "${report_nb}" \
12+
--execute \
1213
--to latex \
1314
--template=${template_dir}/pop_report.tplx \
1415
--output=${output_filename}

ipython_templates/pop_report.tplx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
## Input necessary details from ipynb metadata
2727
((* block maketitle *))
2828

29-
((* for item in ['reprefnum', 'title', 'servicelevel', 'author', 'contributors'] *))
29+
((* for item in ['reprefnum', 'title', 'author', 'contributors'] *))
3030
\((( item ))){((( nb.metadata.get("pop_metadata", {}).get(item, '\color{{red}} pop\_metadata.{} NOT SET'.format(item))
3131
)))}
3232
((* endfor *))

pypop/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212

1313
from .version import get_version
1414

15-
__all__ = ['__version__']
15+
__all__ = ["__version__"]
1616

1717
__version__ = get_version()
18-
19-

pypop/cli.py

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,19 @@
55
"""CLI Analysis scripts"""
66

77
from os import getcwd
8-
from os.path import expanduser, join as path_join, normpath
8+
from os.path import (
9+
exists as path_exists,
10+
expanduser,
11+
isabs,
12+
join as path_join,
13+
normpath,
14+
realpath,
15+
relpath,
16+
)
17+
from pkg_resources import resource_filename
918
from shutil import copytree, Error as shutil_error
19+
from webbrowser import open_new_tab
20+
import sys
1021

1122
from matplotlib import use
1223

@@ -17,10 +28,31 @@
1728
from pypop.dimemas import dimemas_idealise
1829
from pypop.config import set_dimemas_path, set_paramedir_path, set_tmpdir_path
1930
from pypop.examples import examples_directory
31+
from pypop.server import get_notebook_server_instance, construct_nb_url
2032

2133
from argparse import ArgumentParser
2234
from tqdm import tqdm
2335

36+
import nbformat
37+
38+
latest_nbformat = getattr(nbformat, "v{}".format(nbformat.current_nbformat))
39+
new_nb = latest_nbformat.new_notebook
40+
code_cell = latest_nbformat.new_code_cell
41+
md_cell = latest_nbformat.new_markdown_cell
42+
43+
GUI_MSG = """
44+
PyPOP GUI Ready:
45+
If the gui does not open automatically, please go to the following url
46+
in your web browser:
47+
48+
{}
49+
"""
50+
51+
OWN_SERVER_MSG = """
52+
A new notebook server was started for this PyPOP session. When you are finished,
53+
press CTRL-C in this window to shut down the server.
54+
"""
55+
2456

2557
def _dimemas_idealise_parse_args():
2658

@@ -133,6 +165,10 @@ def _preprocess_traces_parse_args():
133165
parser.add_argument(
134166
"--dimemas-path", type=str, metavar="PATH", help="Path to Dimemas executable"
135167
)
168+
169+
parser.add_argument(
170+
"--tag", type=str, metavar="TAG", help="Tag to apply to trace(s)"
171+
)
136172
parser.add_argument(
137173
"--outfile-path",
138174
type=str,
@@ -274,6 +310,7 @@ def preprocess_traces():
274310
force_recalculation=config.force_recalculation,
275311
chop_to_roi=config.chop_to_roi,
276312
outpath=config.outfile_path,
313+
tag=config.tag,
277314
)
278315

279316

@@ -322,3 +359,127 @@ def copy_examples():
322359
except shutil_error as err:
323360
print("Copy failed: {}".format(str(err)))
324361
return -1
362+
363+
364+
def _gui_launcher_parse_args():
365+
366+
# make an argument parser
367+
parser = ArgumentParser(description="Launch the PyPOP GUI and Notebook server")
368+
369+
# First define collection of traces
370+
parser.add_argument(
371+
"nb_path",
372+
type=str,
373+
nargs="?",
374+
metavar="NB_PATH",
375+
help="GUI Notebook name/path default is $PWD/pypop_gui.ipynb",
376+
)
377+
parser.add_argument(
378+
"-n",
379+
"--notebookdir",
380+
type=str,
381+
metavar="NB_DIR",
382+
help="Notebook server root directory (default is $PWD or inferred from "
383+
"NB_PATH), ignored if an existing server is used",
384+
)
385+
parser.add_argument(
386+
"-f",
387+
"--force-overwrite",
388+
action="store_true",
389+
help="Overwrite existing file when creating GUI notebook.",
390+
)
391+
392+
return parser.parse_args()
393+
394+
395+
def _gui_exit(msg, own_server):
396+
print(msg, file=sys.stderr)
397+
if own_server:
398+
own_server.kill()
399+
sys.exit(-1)
400+
401+
402+
def pypop_gui():
403+
"""Entrypoint for launching Jupyter Notebook GUI
404+
"""
405+
406+
config = _gui_launcher_parse_args()
407+
408+
notebookdir = getcwd()
409+
nb_name = "pypop_gui.ipynb"
410+
if config.notebookdir:
411+
notebookdir = realpath(notebookdir)
412+
413+
nb_path = realpath(path_join(notebookdir, nb_name))
414+
if config.nb_path:
415+
if isabs(config.nb_path):
416+
if relpath(realpath(config.nb_path), notebookdir):
417+
gui_exit(
418+
"Requested gui notebook file path is not in the notebook server "
419+
"directory ({}).".format(config.nb_path, notebookdir),
420+
None,
421+
)
422+
nb_path = os.realpath(config.nb_path)
423+
else:
424+
nb_name = os.realpath(join(notebookdir, config.nb_path))
425+
426+
server_info, own_server = get_notebook_server_instance()
427+
428+
real_nbdir = realpath(server_info["notebook_dir"])
429+
if relpath(nb_path, real_nbdir).startswith(".."):
430+
_gui_exit(
431+
"Requested gui notebook file path {} is not in the root of the "
432+
"notebook server ({}). You may need to specify a different working "
433+
"directory, change the server config, or allow PyPOP to start its own "
434+
"server.".format(nb_path, real_nbdir),
435+
own_server,
436+
)
437+
438+
if not path_exists(nb_path) or config.force_overwrite:
439+
try:
440+
write_gui_nb(nb_path)
441+
except:
442+
_gui_exit("Failed to create gui notebook", own_server)
443+
444+
nb_url = construct_nb_url(server_info, nb_path)
445+
446+
open_new_tab(nb_url)
447+
448+
print(GUI_MSG.format(nb_url))
449+
450+
if own_server:
451+
print(OWN_SERVER_MSG)
452+
try:
453+
own_server.wait()
454+
except KeyboardInterrupt:
455+
own_server.terminate()
456+
457+
458+
def hidden_code_cell(*args, **kwargs):
459+
460+
hidden_cell = {"hide_input": True}
461+
462+
if "metadata" in kwargs:
463+
kwargs["metadata"].update(hidden_cell)
464+
else:
465+
kwargs["metadata"] = hidden_cell
466+
467+
return code_cell(*args, **kwargs)
468+
469+
470+
def write_gui_nb(gui_nb_path):
471+
472+
gui_nb = new_nb(metadata={})
473+
474+
gui_code = """\
475+
from pypop.notebook_interface import MetricsWizard
476+
from pypop.metrics import MPI_OpenMP_Metrics
477+
gui = MetricsWizard(MPI_OpenMP_Metrics)
478+
display(gui)\
479+
"""
480+
gui_cells = [(gui_code, hidden_code_cell)]
481+
482+
for cell_text, cell_ctr in gui_cells:
483+
gui_nb.cells.append(cell_ctr(cell_text))
484+
485+
nbformat.write(gui_nb, gui_nb_path)

pypop/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from os.path import normpath, expanduser
99

10-
__all__ = ['set_paramedir_path', 'set_dimemas_path', 'set_tmpdir_path']
10+
__all__ = ["set_paramedir_path", "set_dimemas_path", "set_tmpdir_path"]
1111

1212
_dimemas_path = None
1313
_paramedir_path = None

pypop/dimemas.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,7 @@ def dimemas_idealise(tracefile, outpath=None):
5959

6060
# Pass trace, run config and path to idealisation skeleton config and let
6161
# dimemas_analyze work its subtle magic(k)s
62-
return dimemas_analyse(
63-
tracefile, IDEAL_CONF_PATH, outpath, subs
64-
)
62+
return dimemas_analyse(tracefile, IDEAL_CONF_PATH, outpath, subs)
6563

6664

6765
def dimemas_analyse(tracefile, configfile, outpath=None, substrings=None):
@@ -93,7 +91,7 @@ def dimemas_analyse(tracefile, configfile, outpath=None, substrings=None):
9391

9492
# Perform all work in a tempdir with predictable names,
9593
# this works around a series of weird dimemas bugs
96-
94+
9795
# Make sure config._tmpdir_path exists before using it
9896
if config._tmpdir_path:
9997
try:
@@ -142,7 +140,7 @@ def dimemas_analyse(tracefile, configfile, outpath=None, substrings=None):
142140
# Now create the dim file for dimemas
143141
tmp_dim = os.path.join(workdir, splitext(basename(tmp_prv))[0] + ".dim")
144142

145-
prv2dim_binpath = 'prv2dim'
143+
prv2dim_binpath = "prv2dim"
146144
if config._dimemas_path:
147145
prv2dim_binpath = os.path.join(config._dimemas_path, prv2dim_binpath)
148146

@@ -165,7 +163,7 @@ def dimemas_analyse(tracefile, configfile, outpath=None, substrings=None):
165163
except Exception as err:
166164
raise RuntimeError("prv2dim execution_failed: {}".format(err))
167165

168-
dimemas_binpath = 'Dimemas'
166+
dimemas_binpath = "Dimemas"
169167
if config._dimemas_path:
170168
dimemas_binpath = os.path.join(config._dimemas_path, dimemas_binpath)
171169

@@ -228,4 +226,4 @@ def dimemas_analyse(tracefile, configfile, outpath=None, substrings=None):
228226
shutil.rmtree(workdir, ignore_errors=True)
229227

230228
# finally return outpath as promised
231-
return os.path.join(outpath,filestem + ".sim.prv")
229+
return os.path.join(outpath, filestem + ".sim.prv")

0 commit comments

Comments
 (0)