|
5 | 5 | """CLI Analysis scripts""" |
6 | 6 |
|
7 | 7 | 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 |
9 | 18 | from shutil import copytree, Error as shutil_error |
| 19 | +from webbrowser import open_new_tab |
| 20 | +import sys |
10 | 21 |
|
11 | 22 | from matplotlib import use |
12 | 23 |
|
|
17 | 28 | from pypop.dimemas import dimemas_idealise |
18 | 29 | from pypop.config import set_dimemas_path, set_paramedir_path, set_tmpdir_path |
19 | 30 | from pypop.examples import examples_directory |
| 31 | +from pypop.server import get_notebook_server_instance, construct_nb_url |
20 | 32 |
|
21 | 33 | from argparse import ArgumentParser |
22 | 34 | from tqdm import tqdm |
23 | 35 |
|
| 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 | + |
24 | 56 |
|
25 | 57 | def _dimemas_idealise_parse_args(): |
26 | 58 |
|
@@ -133,6 +165,10 @@ def _preprocess_traces_parse_args(): |
133 | 165 | parser.add_argument( |
134 | 166 | "--dimemas-path", type=str, metavar="PATH", help="Path to Dimemas executable" |
135 | 167 | ) |
| 168 | + |
| 169 | + parser.add_argument( |
| 170 | + "--tag", type=str, metavar="TAG", help="Tag to apply to trace(s)" |
| 171 | + ) |
136 | 172 | parser.add_argument( |
137 | 173 | "--outfile-path", |
138 | 174 | type=str, |
@@ -274,6 +310,7 @@ def preprocess_traces(): |
274 | 310 | force_recalculation=config.force_recalculation, |
275 | 311 | chop_to_roi=config.chop_to_roi, |
276 | 312 | outpath=config.outfile_path, |
| 313 | + tag=config.tag, |
277 | 314 | ) |
278 | 315 |
|
279 | 316 |
|
@@ -322,3 +359,127 @@ def copy_examples(): |
322 | 359 | except shutil_error as err: |
323 | 360 | print("Copy failed: {}".format(str(err))) |
324 | 361 | 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) |
0 commit comments