Ejemplo n.º 1
0
def database(tmp_path):
    params = pd.DataFrame()
    params["name"] = list("abc")
    database = prepare_database(
        path=tmp_path / "test.db",
        params=params,
        dash_options={
            "a": 3,
            "no_browser": True
        },
        constraints=[{
            "loc": "a",
            "type": "increasing"
        }],
        optimization_status="success",
    )

    tables = ["params_history", "criterion_history", "timestamps"]
    for i in range(10):
        params = pd.Series(index=list("abc"), data=i)
        critval = i**2
        time = datetime(year=2020,
                        month=4,
                        day=9,
                        hour=12,
                        minute=41,
                        second=i)
        rows = [params, {"value": critval}, {"value": time}]
        upd_db.append_rows(database, tables, rows)
        sleep(0.1)

    return database
Ejemplo n.º 2
0
        def wrapper_log_gradient(*args, **kwargs):
            gradient = func(*args, **kwargs)

            if database:
                data = [dict(zip(names, gradient))]
                append_rows(database, ["gradient_history"], data)

            return gradient
Ejemplo n.º 3
0
        def wrapper_log_evaluation(params, *args, **kwargs):
            criterion_value, comparison_plot_data = func(
                params, *args, **kwargs)

            if database:
                adj_params = params.copy().set_index("name")["value"]
                cp_data = {"value": comparison_plot_data["value"].to_numpy()}
                crit_val = {"value": criterion_value}

                append_rows(database, tables, [adj_params, crit_val, cp_data])

            return criterion_value
Ejemplo n.º 4
0
def database(tmp_path):
    params = pd.DataFrame()
    params["name"] = list("abc")
    database = prepare_database(
        path=tmp_path / "test.db",
        params=params,
        db_options={"a": 3},
        optimization_status="success",
    )

    tables = ["params_history", "criterion_history"]
    for i in range(10):
        params = pd.Series(index=list("abc"), data=i)
        critval = i ** 2
        append_rows(database, tables, [params, {"value": critval}])

    return database
Ejemplo n.º 5
0
        def wrapper_handle_exceptions(x, *args, **kwargs):
            try:
                out = func(x, *args, **kwargs)
            except (KeyboardInterrupt, SystemExit):
                raise
            except Exception as e:
                # Adjust the criterion value at the start.
                start_criterion_value = general_options[
                    "start_criterion_value"]
                constant, slope = general_options.get(
                    "criterion_exception_penalty", (None, None))
                constant = 2 * start_criterion_value if constant is None else constant
                slope = 0.1 * start_criterion_value if slope is None else slope
                raise_exc = general_options.get("criterion_exception_raise",
                                                False)

                if raise_exc:
                    raise e
                else:
                    if database:
                        exception_info = traceback.format_exc()
                        p = reparametrize_from_internal(
                            internal=x,
                            fixed_values=params["_internal_fixed_value"].
                            to_numpy(),
                            pre_replacements=params["_pre_replacements"].
                            to_numpy().astype(int),
                            processed_constraints=constraints,
                            post_replacements=(params["_post_replacements"].
                                               to_numpy().astype(int)),
                            processed_params=params,
                        )
                        msg = (exception_info + "\n\n" +
                               "The parameters are\n\n" +
                               p["value"].to_csv(sep="\t", header=True))
                        append_rows(database, "exceptions", {"value": msg})

                    out = min(
                        MAX_CRITERION_PENALTY,
                        constant + slope * np.linalg.norm(x - start_params),
                    )

            return out
Ejemplo n.º 6
0
def prepare_database(
    path,
    params,
    comparison_plot_data=None,
    dash_options=None,
    constraints=None,
    optimization_status="scheduled",
    gradient_status=0,
):
    """Return database metadata object with all relevant tables for the optimization.

    This should always be used to create entirely new databases or to create the
    tables needed during optimization in an existing database.

    A new database is created if path does not exist yet. Otherwise the
    existing database is loaded and all tables needed to log the optimization are
    overwritten. Other tables remain unchanged.

    The resulting database has the following tables:

    - params_history: the complete history of parameters from the optimization. The
      index column is "iteration", the remaining columns are parameter names taken
      from params["name"].
    - gradient_history: the complete history of gradient evaluations from the
      optimization. Same columns as params_history.
    - criterion_history: the complete history of criterion values from the optimization.
      The index column is "iteration", the second column is "value".
    - time_stamps: timestamps from the end of each criterion evaluation. Same columns as
      criterion_history.
    - convergence_history: the complete history of convergence criteria from the
      optimization. The index column is "iteration", the other columns are "ftol",
      "gtol" and "xtol".
    - start_params: copy of user provided ``params``. This is not just the first entry
      of params_history because it contains all columns and has a different index.
    - optimization_status: table with one row and one column called "value" which takes
      the values "scheduled", "running", "success" or "failure". Initialized to
      ``optimization_status``.
    - gradient_status: table with one row and one column called "value" which
      can be any float between 0 and 1 and indicates the progress of the gradient
      calculation. Initialized to ``gradient_status``
    - dash_options: table with one row and one column called "value". It contains
      a dictionary with the dashboard options.
      Internally this is a PickleType, so the dictionary must be pickle serializable.
      Initialized to dash_options.
    - exceptions: table with one column called "value" with exceptions.
    - constraints: table with one row and one column called "value". It contains the
      list of constraints. Internally this is a PickleType, so the list must be pickle
      serializable.


    Args:
        path (str or pathlib.Path): location of the database file. If the file does
            not exist, it will be created.
        params (pd.DataFrame): see :ref:`params`.
        comparison_plot_data : (numpy.ndarray or pandas.Series or pandas.DataFrame):
            Contains the data for the comparison plot. Later updates will only deliver
            the value column where as this input has an index and other invariant
            information.
        dash_options (dict): Dictionary with the dashboard options.
        optimization_status (str): One of "scheduled", "running", "success", "failure".
        gradient_status (float): Progress of gradient calculation between 0 and 1.
        constraints (list): List of constraints.

    Returns:
        database (sqlalchemy.MetaData). The engine that connects
        to the database can be accessed via ``database.bind``.

    """
    gradient_status = float(gradient_status)
    database = load_database(path)

    opt_tables = [
        "params_history",
        "gradient_history",
        "criterion_history",
        "timestamps",
        "convergence_history",
        "start_params",
        "comparison_plot",
        "optimization_status",
        "gradient_status",
        "dash_options",
        "exceptions",
        "constraints",
    ]

    for table in opt_tables:
        if table in database.tables:
            database.tables[table].drop(database.bind)

    _define_table_formatted_with_params(database, params, "params_history")
    _define_table_formatted_with_params(database, params, "gradient_history")
    _define_fitness_history_table(database, "criterion_history")
    _define_time_stamps_table(database)
    _define_convergence_history_table(database)
    _define_start_params_table(database)
    _define_one_column_pickle_table(database, "comparison_plot")
    _define_optimization_status_table(database)
    _define_gradient_status_table(database)
    _define_scalar_pickle_table(database, "dash_options")
    _define_string_table(database, "exceptions")
    _define_scalar_pickle_table(database, "constraints")
    engine = database.bind
    database.create_all(engine)

    append_rows(database, "start_params", {"value": params})
    append_rows(database, "optimization_status",
                {"value": optimization_status})
    append_rows(database, "gradient_status", {"value": gradient_status})
    append_rows(database, "dash_options", {"value": dash_options})
    append_rows(database, "constraints", {"value": constraints})

    if comparison_plot_data is None:
        comparison_plot_data = pd.DataFrame({"value": [np.nan]})
    append_rows(database, "comparison_plot", {"value": comparison_plot_data})

    return database