Пример #1
0
def get_experiment(experiment, **kwargs):
    """Returns the specified experiment.

    :param experiment: experiment name or index
    :type experiment: int or str or COPASI.CExperiment

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: the experiment or an error if none existent
    """
    if not isinstance(experiment, COPASI.CExperiment):
        model = model_io.get_model_from_dict_or_default(kwargs)
        assert (isinstance(model, COPASI.CDataModel))

        task = model.getTask(TASK_PARAMETER_ESTIMATION)
        assert (isinstance(task, COPASI.CFitTask))

        problem = task.getProblem()
        assert (isinstance(problem, COPASI.CFitProblem))
        exp_set = problem.getExperimentSet()

        if type(experiment) is int and experiment >= exp_set.size():
            raise ValueError('Experiment index out of bounds')
        exp = exp_set.getExperiment(experiment)
        if exp is not None:
            experiment = exp
        else:
            raise ValueError('No experiment for: {0}'.format(experiment))
    return experiment
Пример #2
0
def get_opt_statistic(**kwargs):
    """Return information about the last optimization run.

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: dictionary with the statistic
    :rtype: {}
    """
    dm = model_io.get_model_from_dict_or_default(kwargs)

    task = dm.getTask(basico.T.OPTIMIZATION)
    assert (isinstance(task, COPASI.COptTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.COptProblem))

    result = {
        'obj': problem.getSolutionValue(),
        'f_evals': problem.getFunctionEvaluations(),
        'failed_evals_exception': problem.getFailedEvaluationsExc(),
        'failed_evals_nan': problem.getFailedEvaluationsNaN(),
        'cpu_time': problem.getExecutionTime(),
    }
    result['evals_per_sec'] = result['cpu_time'] / result['f_evals']
    return result
Пример #3
0
def get_experiment_names(**kwargs):
    """Returns the list of experiment names

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: list of experiment names defined
    :rtype: [str]
    """
    model = model_io.get_model_from_dict_or_default(kwargs)
    assert (isinstance(model, COPASI.CDataModel))

    task = model.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    result = []
    for i in range(problem.getExperimentSet().size()):
        experiment = problem.getExperimentSet().getExperiment(i)
        result.append(experiment.getObjectName())
    return result
Пример #4
0
def get_fit_statistic(**kwargs):
    """Return information about the last fit.

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: dictionary with the fit statistic
    :rtype: {}
    """
    dm = model_io.get_model_from_dict_or_default(kwargs)

    task = dm.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    experiments = problem.getExperimentSet()
    assert (isinstance(experiments, COPASI.CExperimentSet))

    result = {
        'obj': problem.getSolutionValue(),
        'rms': problem.getRMS(),
        'sd': problem.getStdDeviation(),
        'f_evals': problem.getFunctionEvaluations(),
        'failed_evals_exception': problem.getFailedEvaluationsExc(),
        'failed_evals_nan': problem.getFailedEvaluationsNaN(),
        'cpu_time': problem.getExecutionTime(),
        'data_points': experiments.getDataPointCount(),
        'valid_data_points': experiments.getValidValueCount(),
    }
    result['evals_per_sec'] = result['cpu_time'] / result['f_evals']
    return result
Пример #5
0
def run_optimization(expression=None, output=None, settings=None, **kwargs):
    """Runs the optimization

    :param expression: optional objective function to be used
    :param settings: optional settings dictionary
    :param output: optional list of output to collect
    :param kwargs: optional arguments
    :return: pandas data frame of the specified output, or the resulting solution for the parameters
    """
    model = model_io.get_model_from_dict_or_default(kwargs)

    task = model.getTask(basico.T.OPTIMIZATION)
    assert (isinstance(task, COPASI.COptTask))
    problem = task.getProblem()
    assert (isinstance(problem, COPASI.COptProblem))

    if 'method' in kwargs:
        method = kwargs['method']
        if isinstance(method, dict):
            set_opt_settings({method}, model=model)
        elif isinstance(method, int):
            task.setMethodType(method)
        else:
            set_opt_settings({'method': {'name': method}}, model=model)
    if settings:
        set_opt_settings(settings, model)

    if expression:
        set_objective_function(expression, model)

    dh = None
    cols = []
    if output:
        dh, cols = basico.task_timecourse.create_data_handler(output,
                                                              after=output,
                                                              model=model)
        model.addInterface(dh)

    if not task.initializeRaw(COPASI.CCopasiTask.OUTPUT_UI):
        logging.warning("Couldn't initialize optimization task")

    use_initial_values = kwargs.get('use_initial_values', True)
    if not task.processRaw(use_initial_values):
        logging.warning("Couldn't process optimization task")

    if dh:
        model.removeInterface(dh)
        data = basico.task_timecourse.get_data_from_data_handler(dh, cols)
        del dh
        dh = None
        return data

    return get_opt_solution(model=model)
Пример #6
0
def _get_experiment_keys(**kwargs):
    model = model_io.get_model_from_dict_or_default(kwargs)
    assert (isinstance(model, COPASI.CDataModel))

    task = model.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    result = []
    for i in range(problem.getExperimentSet().size()):
        experiment = problem.getExperimentSet().getExperiment(i)
        result.append(experiment.getKey())
    return result
Пример #7
0
def remove_fit_parameters(**kwargs):
    """Removes all fit items

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: None
    """
    dm = model_io.get_model_from_dict_or_default(kwargs)

    pe_task = dm.getTask(TASK_PARAMETER_ESTIMATION)
    problem = pe_task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))
    while problem.getOptItemSize() > 0:
        problem.removeOptItem(0)
Пример #8
0
def num_validations_files(**kwargs):
    """Returns the number of cross validation experiment files

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: number of cross validation experiment files
    :rtype: int
    """
    model = model_io.get_model_from_dict_or_default(kwargs)
    assert (isinstance(model, COPASI.CDataModel))

    task = model.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    return problem.getCrossValidationSet().size()
Пример #9
0
def remove_experiments(**kwargs):
    """Removes all experiments from the model

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: None
    """
    dm = model_io.get_model_from_dict_or_default(kwargs)

    task = dm.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    experiments = problem.getExperimentSet()
    assert (isinstance(experiments, COPASI.CExperimentSet))

    for _ in range(experiments.size()):
        experiments.removeExperiment(0)
Пример #10
0
def get_simulation_results(values_only=False, **kwargs):
    """Runs the current solution statistics and returns result of simulation and experimental data

    :param values_only: if true, only time points at the measurements will be returned
    :type values_only: bool

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    - | `solution`: a solution data frame to use, if not specified a current solution
                    statistic will be computed

    :return: tuple of lists of experiment data, and a list of simulation data
    :rtype: ([pandas.DataFrame],[pandas.DataFrame])
    """
    import basico
    dm = model_io.get_model_from_dict_or_default(kwargs)

    task = dm.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    experiments = problem.getExperimentSet()
    assert (isinstance(experiments, COPASI.CExperimentSet))

    result = []
    num_experiments = experiments.getExperimentCount()
    if num_experiments == 0:
        return result

    if 'solution' in kwargs:
        solution = kwargs['solution']
    else:
        solution = run_parameter_estimation(
            method='Current Solution Statistics')

    model = dm.getModel()

    exp_data = []
    sim_data = []

    for i in range(num_experiments):
        change_set = COPASI.DataObjectSet()
        experiment = experiments.getExperiment(i)
        exp_name = experiment.getObjectName()
        df = get_data_from_experiment(experiment, rename_headers=True)
        columns = df.columns.to_list()
        mapping = get_experiment_mapping(experiment)

        # set independent values for that experiment
        independent = mapping[mapping.type == 'independent']
        num_independent = independent.shape[0]
        for j in range(num_independent):
            name = independent.iloc[j].mapping
            cn = independent.iloc[j].cn

            if name not in columns:
                # independent value is not found in df
                continue

            value = df.iloc[0][name]
            obj = dm.getObject(COPASI.CCommonName(cn))

            if obj is None:  # not found skip
                logging.debug(
                    'independent object not found for cn: {0}'.format(cn))
                continue

            if obj.getObjectName() == 'InitialConcentration':
                obj.getObjectParent().setInitialConcentration(value)
            else:
                obj.getObjectParent().setInitialValue(value)

            change_set.append(obj)
            logging.debug('set independent "{0}" to "{1}"'.format(cn, value))

        if change_set.size() > 0:
            model.updateInitialValues(change_set)

        _update_fit_parameters_from(dm, solution, exp_name)

        if experiment.getExperimentType() == COPASI.CTaskEnum.Task_steadyState:
            # run steady state
            basico.run_steadystate(model=dm)
            data = basico.model_info._collect_data(cns=mapping[
                mapping.type == 'dependent']['cn'].to_list()).transpose()
        else:
            # run time course
            duration = df.iloc[-1].Time
            if values_only:
                data = basico.run_time_course(values=df.Time.to_list(),
                                              start_time=df.iloc[0].Time)
            else:
                data = basico.run_time_course(duration=duration)

        exp_data.append(df)
        sim_data.append(data)

    return exp_data, sim_data
Пример #11
0
def run_parameter_estimation(**kwargs):
    """Runs the parameter estimation task as specified:

    The following are valid methods to be used for the parameter estimation task.

        Current Solution:

            * `Current Solution Statistics`,

        Global Methods:

            * `Random Search`,
            * `Simulated Annealing`,
            * `Differential Evolution`,
            * `Scatter Search`,
            * `Genetic Algorithm`,
            * `Evolutionary Programming`,
            * `Genetic Algorithm SR`,
            * `Evolution Strategy (SRES)`,
            * `Particle Swarm`,

        Local Methods:

            * `Levenberg - Marquardt`,
            * `Hooke & Jeeves`,
            * `Nelder - Mead`,
            * `Steepest Descent`,
            * `NL2SOL`,
            * `Praxis`,
            * `Truncated Newton`,

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    - | `method` (str): one of the strings from above

    - | `randomize_start_values` (bool): if true, parameters will be randomized before starting otherwise the
      | parameters starting value will be taken.

    - | `calculate_statistics` (bool): if true, the statistics will be calculated at the end of the task

    - | `create_parametersets` (bool): if true, parameter sets will be created for all experiments

    - `use_initial_values` (bool): whether to use initial values

    - `scheduled` (bool): sets whether the task is scheduled or not

    - `update_model` (bool): sets whether the model should be updated, or reset to initial conditions.

    - `settings` (dict): a dictionary with settings to use, in the same format as the ones obtained from
                         :func:`.get_task_settings`

    :return: the solution for the fit parameters see :func:`get_parameters_solution`.
    :rtype: pandas.DataFrame
    """
    model = model_io.get_model_from_dict_or_default(kwargs)
    assert (isinstance(model, COPASI.CDataModel))

    task = model.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    if problem.getOptItemSize() == 0:
        logging.warning(
            'No fit parameters defined, skipping parameter estimation run')
        return get_parameters_solution(model)

    if 'scheduled' in kwargs:
        task.setScheduled(kwargs['scheduled'])

    if 'update_model' in kwargs:
        task.setUpdateModel(kwargs['update_model'])

    old_create_parameter_sets = problem.getCreateParameterSets()
    # old_calculate_statistics = problem.getCalculateStatistics()
    # old_randomize_start_values = problem.getRandomizeStartValues()

    problem.setCreateParameterSets(True)

    if 'method' in kwargs:
        method = kwargs['method']
        if isinstance(method, int):
            task.setMethodType(method)
        else:
            task.setMethodType(COPASI.CCopasiMethod_TypeNameToEnum(method))

    if 'randomize_start_values' in kwargs:
        problem.setRandomizeStartValues(bool(kwargs['randomize_start_values']))

    if 'calculate_statistics' in kwargs:
        problem.setCalculateStatistics(bool(kwargs['calculate_statistics']))

    if 'create_parametersets' in kwargs:
        problem.setCreateParameterSets(bool(kwargs['create_parametersets']))

    use_initial_values = kwargs.get('use_initial_values', True)

    if 'settings' in kwargs:
        basico.set_task_settings(task, kwargs['settings'])

    result = task.initializeRaw(COPASI.CCopasiTask.OUTPUT_UI)
    if not result:
        logging.error("Error while initializing parameter estimation: " +
                      COPASI.CCopasiMessage.getLastMessage().getText())
    else:
        result = task.processRaw(use_initial_values)
        if not result:
            logging.error("Error while running parameter estimation: " +
                          COPASI.CCopasiMessage.getLastMessage().getText())

    problem.setCreateParameterSets(old_create_parameter_sets)

    return get_parameters_solution(model)
Пример #12
0
def add_experiment(name, data, **kwargs):
    """Adds a new experiment to the model.

    This method adds a new experiment file to the parameter estimation task. The provided
    data frame will be written into the current directory as `experiment_name.txt` unless a filename
    has been provided.

    The mapping between the columns and the model elements should be done by having the columns of the data
    frame be model element names in question. So for example `[A]` to note that the transient concentrations
    of a species `A` is to be mapped as dependent variable. or `[A]_0` to note that the initial concentration of
    a species `A` is to be mapped as independent variable.

    :param name: the name of the experiment
    :type name: str
    :param data: the data frame with the experimental data
    :type data: pandas.DataFrame
    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    - | `file_name` (str): the file name to save the experimental data to (otherwise it will be name.txt)

    :return: the filename of the generated data file
    :rtype: str
    """
    model = model_io.get_model_from_dict_or_default(kwargs)
    assert (isinstance(model, COPASI.CDataModel))
    task = model.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))
    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))
    exp_set = problem.getExperimentSet()
    assert (isinstance(exp_set, COPASI.CExperimentSet))
    exp = exp_set.getExperiment(name)
    if exp is not None:
        logging.error(
            'An experiment with the name {0} already exists'.format(name))
        return None

    # save data as tsv

    file_name = os.path.abspath(os.path.join(os.path.curdir, name + '.txt'))
    if 'file_name' in kwargs:
        file_name = os.path.abspath(kwargs['file_name'])

    assert (isinstance(data, pd.DataFrame))
    data.to_csv(file_name, sep='\t', header=True, index=False)
    # create experiment

    exp = COPASI.CExperiment(model)
    exp = exp_set.addExperiment(exp)
    info = COPASI.CExperimentFileInfo(exp_set)
    info.setFileName(file_name)
    info.sync()
    exp.setObjectName(name)
    exp.setFileName(file_name)
    exp.setHeaderRow(1)
    exp.setFirstRow(1)
    exp.setLastRow(len(data) + 1)

    columns = data.columns.to_list()
    if 'time' in [col.lower() for col in columns]:
        exp.setExperimentType(COPASI.CTaskEnum.Task_timeCourse)
    else:
        exp.setExperimentType(COPASI.CTaskEnum.Task_steadyState)

    obj_map = exp.getObjectMap()
    num_cols = len(columns)
    obj_map.setNumCols(num_cols)
    for i in range(num_cols):
        role = COPASI.CExperiment.ignore
        current = columns[i]
        if current.lower() == 'time':
            role = COPASI.CExperiment.time
        else:
            obj = model.findObjectByDisplayName(current)
            if obj is None:
                logging.warning(
                    "Can't find model element for {0}".format(current))
            else:
                assert (isinstance(obj, COPASI.CDataObject))
                if obj.getObjectType() != 'Reference':
                    try:
                        obj = obj.getValueReference()
                    except AttributeError:
                        logging.warning(
                            "Cannot map the element {0}".format(current))
                role = _get_role_for_reference(obj.getObjectName())
                obj_map.setObjectCN(i, obj.getCN())
        obj_map.setRole(i, role)

    exp.calculateWeights()
    exp_set.compile(model.getModel().getMathContainer())

    return file_name
Пример #13
0
def plot_per_dependent_variable(**kwargs):
    """
    This function creates a figure for each dependent variable, with traces for all experiments.

    :param kwargs:

    - | `model`: to specify the data model to be used (if not specified
      | the one from :func:`.get_current_model` will be taken)

    :return: array of tuples (fig, ax) for each figure created
    """
    dm = model_io.get_model_from_dict_or_default(kwargs)

    task = dm.getTask(TASK_PARAMETER_ESTIMATION)
    assert (isinstance(task, COPASI.CFitTask))

    problem = task.getProblem()
    assert (isinstance(problem, COPASI.CFitProblem))

    experiments = problem.getExperimentSet()
    assert (isinstance(experiments, COPASI.CExperimentSet))

    result = []
    num_experiments = experiments.getExperimentCount()
    if num_experiments == 0:
        return result

    exp_data, sim_data = get_simulation_results(**kwargs)

    dependent_variables = {}

    for i in range(num_experiments):
        experiment = experiments.getExperiment(i)
        mapping = get_experiment_mapping(experiment)

        # set independent values for that experiment
        dependent = mapping[mapping.type == 'dependent']
        num_dependent = dependent.shape[0]
        for j in range(num_dependent):
            name = dependent.iloc[j].mapping
            if name not in dependent_variables:
                dependent_variables[name] = []
            dependent_variables[name].append(i)

    for dependent in dependent_variables:
        fig, ax = plt.subplots()
        cycler = plt.cycler("color", plt.cm.tab20c.colors)()
        ax.set_title(dependent)
        experiment_indices = dependent_variables[dependent]

        for i in experiment_indices:
            experiment = experiments.getExperiment(i)
            exp_name = experiment.getObjectName()
            nextval = next(cycler)['color']
            name = dependent
            if name not in sim_data[i].columns:
                name = name[1:-1]

            sim_data[i].reset_index().plot(x='Time',
                                           y=name,
                                           label="{0} Fit".format(exp_name),
                                           ax=ax,
                                           color=nextval)
            exp_data[i].plot.scatter(x='Time',
                                     y=dependent,
                                     ax=ax,
                                     color=nextval,
                                     label='{0} Measured'.format(exp_name))
        result.append((fig, ax))

    return result