Source code for trixi.experiment_browser.browser

import argparse
import json
import os
import sys
from collections import OrderedDict

import colorlover as cl
from flask import Blueprint, Flask, abort, render_template, request

from trixi.experiment_browser.dataprocessing import group_images, make_graphs, merge_results, process_base_dir
from trixi.experiment_browser.experimentreader import ExperimentReader, CombiExperimentReader, group_experiments_by
from trixi.util import Config

# These keys will be ignored when in a config file
IGNORE_KEYS = ("name",
               "experiment_dir",
               "work_dir",
               "config_dir",
               "log_dir",
               "checkpoint_dir",
               "img_dir",
               "plot_dir",
               "save_dir",
               "result_dir",
               "time",
               "state")

# Set the color palette for plots
COLORMAP = cl.scales["8"]["qual"]["Dark2"]


[docs]def parse_args(): # Read in base directory if len(sys.argv) > 1: parser = argparse.ArgumentParser() parser.add_argument("base_directory", help="Give the path to the base directory of your project files", type=str, default=".") parser.add_argument("-d", "--debug", action="store_true", help="Turn debug mode on, eg. for live reloading.") parser.add_argument("-x", "--expose", action="store_true", help="Make server externally visible") parser.add_argument("-p", "--port", default=5000, type=int, help="Port to start the server on (5000 by default)") args = parser.parse_args() base_dir = args.base_directory if base_dir[-1] == os.sep: base_dir = base_dir[:-1] else: args = type('', (), {})() args.port = 5000 args.expose = False args.debug = False args.base_directory = "." base_dir = "." return args, base_dir
[docs]def create_flask_app(base_dir): # The actual flask app lives in the package directory. The blueprint allows us # to specify an additional static folder and we use that to give access to the # experiment files app = Flask(__name__, static_folder=os.path.join(os.path.dirname(__file__), "static")) blueprint = Blueprint("data", __name__, static_url_path=base_dir, static_folder=base_dir) app.register_blueprint(blueprint) return app
[docs]def register_url_routes(app, base_dir): app.add_url_rule("/", "overview", lambda: overview(base_dir), methods=["GET"]) app.add_url_rule("/overview", "overview_", lambda: overview_(base_dir), methods=["GET"]) app.add_url_rule('/experiment', "experiment", lambda: experiment(base_dir), methods=['GET']) app.add_url_rule('/combine', "combine", lambda: combine(base_dir), methods=['GET']) app.add_url_rule('/experiment_log', "experiment_log", lambda: experiment_log(base_dir), methods=['GET']) app.add_url_rule('/experiment_plots', "experiment_plots", lambda: experiment_plots(base_dir), methods=['GET']) app.add_url_rule('/experiment_remove', "experiment_remove", lambda: experiment_remove(base_dir), methods=['GET']) app.add_url_rule('/experiment_star', "experiment_star", lambda: experiment_star(base_dir), methods=['GET']) app.add_url_rule('/experiment_rename', "experiment_rename", lambda: experiment_rename(base_dir), methods=['GET'])
[docs]def start_browser(): args, base_dir = parse_args() base_dir = os.path.abspath(base_dir) app = create_flask_app(base_dir) register_url_routes(app, base_dir) host = "0.0.0.0" if args.expose else "localhost" app.run(debug=args.debug, host=host, port=args.port)
[docs]def overview(base_dir): try: base_info = process_base_dir(base_dir, ignore_keys=IGNORE_KEYS) base_info["title"] = base_dir return render_template("overview.html", **base_info) except Exception as e: print(e.__repr__()) raise e abort(500)
[docs]def overview_(base_dir): dir_ = request.args.get("dir") try: base_info = process_base_dir(base_dir, dir_, ignore_keys=IGNORE_KEYS) base_info["title"] = dir_ return render_template("overview.html", **base_info) except Exception as e: print(e.__repr__()) raise e abort(500)
[docs]def experiment(base_dir): experiment_paths = request.args.getlist('exp') name = request.args.get('name', "") do_save = request.args.get('save', "") combi = request.args.get('combi', 'false') experiments = [] if combi == "true": combi_exp = CombiExperimentReader(base_dir, experiment_paths, name=name) if do_save == "true": combi_exp.save() experiments = [combi_exp] else: # Get all Experiments for experiment_path in sorted(experiment_paths): exp = ExperimentReader(base_dir, experiment_path) experiments.append(exp) # Assign unique names exp_names = [exp.exp_name for exp in experiments] if len(exp_names) > len(set(exp_names)): for i, exp in enumerate(experiments): exp.exp_name += str(i) exp_names = [exp.exp_name for exp in experiments] # Site Content content = {} # Get config default_val = "-" combi_config = {} exp_configs = [exp.config.flat(False) for exp in experiments] diff_config_keys = list(Config.difference_config_static(*exp_configs).flat().keys()) config_keys = set([k for c in exp_configs for k in c.keys()]) for k in sorted(config_keys): combi_config[k] = [] for conf in exp_configs: combi_config[k].append(conf.get(k, default_val)) config_keys = list(sorted(list(config_keys))) # Get results default_val = "-" combi_results = {} exp_results = [exp.get_results() for exp in experiments] result_keys = set([k for r in exp_results for k in r.keys()]) for k in sorted(result_keys): combi_results[k] = [] for res in exp_results: combi_results[k].append(res.get(k, default_val)) result_keys = list(sorted(list(result_keys))) # Get images images = OrderedDict({}) image_keys = set() image_path = {} for exp in experiments: exp_images = exp.get_images() img_groups = group_images(exp_images) images[exp.exp_name] = img_groups image_path[exp.exp_name] = exp.img_dir image_keys.update(list(img_groups.keys())) image_keys = list(image_keys) image_keys.sort() # Get Plots plots = OrderedDict({}) for exp in experiments: exp_plots = exp.get_plots() plots[exp.exp_name] = exp_plots # Get logs logs_dict = OrderedDict({}) for exp in experiments: exp_logs = [(os.path.basename(l), exp.exp_dir) for l in exp.get_logs()] logs_dict[exp.exp_name] = exp_logs content["title"] = experiments content["images"] = {"img_path": image_path, "imgs": images, "img_keys": image_keys} content["plots"] = {"plots": plots} content["config"] = {"exps": experiments, "configs": combi_config, "keys": config_keys, "diff_keys": diff_config_keys} content["results"] = {"exps": exp_names, "results": combi_results, "keys": result_keys} content["logs"] = {"logs_dict": logs_dict} return render_template('experiment.html', **content)
[docs]def experiment_log(base_dir): experiment_path = request.args.get('exp') log_name = request.args.get('log') exp = ExperimentReader(base_dir, experiment_path) content = exp.get_log_file_content(log_name) print(experiment_path, log_name) return content
[docs]def experiment_remove(base_dir): experiment_paths = request.args.getlist('exp') # Get all Experiments for experiment_path in sorted(experiment_paths): exp = ExperimentReader(base_dir, experiment_path) exp.ignore_experiment() return ""
[docs]def experiment_plots(base_dir): experiment_paths = request.args.getlist('exp') combi = request.args.get('combi', 'false') experiments = [] if combi == "true": combi_exp = CombiExperimentReader(base_dir, experiment_paths) # combi_exp.save() experiments = [combi_exp] else: # Get all Experiments for experiment_path in sorted(experiment_paths): exp = ExperimentReader(base_dir, experiment_path) experiments.append(exp) # Assign unique names exp_names = [exp.exp_name for exp in experiments] if len(exp_names) > len(set(exp_names)): for i, exp in enumerate(experiments): exp.exp_name += str(i) exp_names = [exp.exp_name for exp in experiments] results = [] for exp in experiments: results.append(exp.get_results_log()) results = merge_results(exp_names, results) graphs, traces = make_graphs(results, color_map=COLORMAP) graphs = [str(g) for g in graphs] return json.dumps({"graphs": graphs, "traces": traces})
[docs]def experiment_star(base_dir): experiment_path = request.args.get('exp') star_val = request.args.get('star') star_val = bool(int(star_val)) print(experiment_path, star_val) exp = ExperimentReader(base_dir, experiment_path) exp.update_meta_info(star=star_val) return ""
[docs]def experiment_rename(base_dir): experiment_path = request.args.get('exp') new_name = request.args.get('name') print(experiment_path, new_name) exp = ExperimentReader(base_dir, experiment_path) exp.update_meta_info(name=new_name) return ""
[docs]def combine(base_dir): experiment_paths = request.args.getlist('exp') group_by_list = request.args.getlist('group') name = request.args.get('name', "") try: exps = [] for ep in experiment_paths: expr = ExperimentReader(os.path.join(base_dir, ep)) if expr.exp_info.get("state", "Combined") != "Combined": exps.append(expr) exp_groups = group_experiments_by(exps, group_by_list) combis = [] for group in exp_groups: expc = CombiExperimentReader(base_dir="", exp_dirs=[e.work_dir for e in group], name=name) combis.append(expc) for expc in combis: expc.save() return "1" except Exception as e: return "0" return "0"
if __name__ == "__main__": start_browser()