コード例 #1
0
def test_get_simulation_conditions():
    """Test get_simulation_conditions"""

    # only simulation condition
    measurement_df = pd.DataFrame(data={
        SIMULATION_CONDITION_ID: ['c0', 'c1', 'c0', 'c1'],
    })
    expected = pd.DataFrame(data={
        SIMULATION_CONDITION_ID: ['c0', 'c1'],
    })
    actual = petab.get_simulation_conditions(measurement_df)
    assert actual.equals(expected)

    # simulation and preequilibration condition
    measurement_df = pd.DataFrame(
        data={
            SIMULATION_CONDITION_ID: ['c0', 'c1', 'c0', 'c1'],
            PREEQUILIBRATION_CONDITION_ID: ['c1', 'c0', 'c1', 'c0'],
        })
    expected = pd.DataFrame(
        data={
            SIMULATION_CONDITION_ID: ['c0', 'c1'],
            PREEQUILIBRATION_CONDITION_ID: ['c1', 'c0'],
        })
    actual = petab.get_simulation_conditions(measurement_df)
    assert actual.equals(expected)

    # simulation with and without preequilibration
    measurement_df = pd.DataFrame(
        data={
            SIMULATION_CONDITION_ID: ['c0', 'c1', 'c0', 'c1'],
            PREEQUILIBRATION_CONDITION_ID: ['', '', 'c1', 'c0'],
        })
    expected = pd.DataFrame(
        data={
            SIMULATION_CONDITION_ID: ['c0', 'c1', 'c0', 'c1'],
            PREEQUILIBRATION_CONDITION_ID: ['', '', 'c1', 'c0'],
        }).sort_values(
            [SIMULATION_CONDITION_ID, PREEQUILIBRATION_CONDITION_ID],
            ignore_index=True)
    actual = petab.get_simulation_conditions(measurement_df)
    assert actual.equals(expected)

    # simulation with and without preequilibration; NaNs
    measurement_df = pd.DataFrame(
        data={
            SIMULATION_CONDITION_ID: ['c0', 'c1', 'c0', 'c1'],
            PREEQUILIBRATION_CONDITION_ID: [np.nan, np.nan, 'c1', 'c0'],
        })
    expected = pd.DataFrame(
        data={
            SIMULATION_CONDITION_ID: ['c0', 'c1', 'c0', 'c1'],
            PREEQUILIBRATION_CONDITION_ID: ['', '', 'c1', 'c0'],
        }).sort_values(
            [SIMULATION_CONDITION_ID, PREEQUILIBRATION_CONDITION_ID],
            ignore_index=True)
    actual = petab.get_simulation_conditions(measurement_df)
    assert actual.equals(expected)
コード例 #2
0
ファイル: petab_objective.py プロジェクト: paulstapor/parPE
def rdatas_to_measurement_df(rdatas: Sequence[amici.ReturnData],
                             model: AmiciModel,
                             measurement_df: pd.DataFrame) -> pd.DataFrame:
    """
    Create a measurement dataframe in the PEtab format from the passed
    `rdatas` and own information.

    :param rdatas:
        A sequence of rdatas with the ordering of
        `petab.get_simulation_conditions`.

    :param model:
        AMICI model used to generate `rdatas`.

    :param measurement_df:
        PEtab measurement table used to generate `rdatas`.

    :return:
        A dataframe built from the rdatas in the format of `measurement_df`.
    """

    df = pd.DataFrame(columns=list(measurement_df.columns))

    simulation_conditions = petab.get_simulation_conditions(measurement_df)

    observable_ids = model.getObservableIds()

    # iterate over conditions
    for (_, condition), rdata in zip(simulation_conditions.iterrows(), rdatas):
        # current simulation matrix
        y = rdata['y']
        # time array used in rdata
        t = list(rdata['t'])

        # extract rows for condition
        cur_measurement_df = petab.get_rows_for_condition(
            measurement_df, condition)

        # iterate over entries for the given condition
        # note: this way we only generate a dataframe entry for every
        # row that existed in the original dataframe. if we want to
        # e.g. have also timepoints non-existent in the original file,
        # we need to instead iterate over the rdata['y'] entries
        for _, row in cur_measurement_df.iterrows():
            # copy row
            row_sim = copy.deepcopy(row)

            # extract simulated measurement value
            timepoint_idx = t.index(row[TIME])
            observable_idx = observable_ids.index(row[OBSERVABLE_ID])
            measurement_sim = y[timepoint_idx, observable_idx]

            # change measurement entry
            row_sim[MEASUREMENT] = measurement_sim

            # append to dataframe
            df = df.append(row_sim, ignore_index=True)

    return df
コード例 #3
0
ファイル: petab_import.py プロジェクト: martamatos/pyPESTO
    def create_objective(
            self,
            model: 'amici.Model' = None,
            solver: 'amici.Solver' = None,
            edatas: Sequence['amici.ExpData'] = None,
            force_compile: bool = False
    ) -> 'PetabAmiciObjective':
        """
        Create a pypesto.PetabAmiciObjective.
        """
        # get simulation conditions
        simulation_conditions = petab.get_simulation_conditions(
            self.petab_problem.measurement_df)

        # create model
        if model is None:
            model = self.create_model(force_compile=force_compile)
        # create solver
        if solver is None:
            solver = self.create_solver(model)
        # create conditions and edatas from measurement data
        if edatas is None:
            edatas = self.create_edatas(
                model=model,
                simulation_conditions=simulation_conditions)

        parameter_mapping = amici.petab_objective.create_parameter_mapping(
            petab_problem=self.petab_problem,
            simulation_conditions=simulation_conditions,
            scaled_parameters=True,
            amici_model=model)

        par_ids = self.petab_problem.x_ids

        # fill in dummy parameters (this is needed since some objective
        #  initialization e.g. checks for preeq parameters)
        problem_parameters = {key: val for key, val in zip(
            self.petab_problem.x_ids,
            self.petab_problem.x_nominal_scaled)}
        amici.parameter_mapping.fill_in_parameters(
            edatas=edatas,
            problem_parameters=problem_parameters,
            scaled_parameters=True,
            parameter_mapping=parameter_mapping,
            amici_model=model)

        # create objective
        obj = PetabAmiciObjective(
            petab_importer=self,
            amici_model=model, amici_solver=solver, edatas=edatas,
            x_ids=par_ids, x_names=par_ids,
            parameter_mapping=parameter_mapping)

        return obj
コード例 #4
0
    def rdatas_to_measurement_df(self, rdatas, model=None):
        """
        Create a measurement dataframe in the petab format from
        the passed `rdatas` and own information.

        Parameters
        ----------

        rdatas: list of amici.RData
            A list of rdatas as produced by
            pypesto.AmiciObjective.__call__(x, return_dict=True)['rdatas'].

        Returns
        -------

        df: pandas.DataFrame
            A dataframe built from the rdatas in the format as in
            self.petab_problem.measurement_df.
        """
        # create model
        if model is None:
            model = self.create_model()

        measurement_df = self.petab_problem.measurement_df

        # initialize dataframe
        df = pd.DataFrame(
            columns=list(self.petab_problem.measurement_df.columns))

        # get simulation conditions
        simulation_conditions = petab.get_simulation_conditions(measurement_df)

        # get observable ids
        observable_ids = model.getObservableIds()

        # iterate over conditions
        for data_idx, condition in simulation_conditions.iterrows():
            # current rdata
            rdata = rdatas[data_idx]
            # current simulation matrix
            y = rdata['y']
            # time array used in rdata
            t = list(rdata['t'])

            # extract rows for condition
            cur_measurement_df = petab.get_rows_for_condition(
                measurement_df, condition)

            # iterate over entries for the given condition
            # note: this way we only generate a dataframe entry for every
            # row that existed in the original dataframe. if we want to
            # e.g. have also timepoints non-existent in the original file,
            # we need to instead iterate over the rdata['y'] entries
            for _, row in cur_measurement_df.iterrows():
                # copy row
                row_sim = copy.deepcopy(row)

                # extract simulated measurement value
                timepoint_idx = t.index(row.time)
                observable_idx = observable_ids.index("observable_" +
                                                      row.observableId)
                measurement_sim = y[timepoint_idx, observable_idx]

                # change measurement entry
                row_sim.measurement = measurement_sim

                # append to dataframe
                df = df.append(row_sim, ignore_index=True)

        return df
コード例 #5
0
    def create_objective(self,
                         model=None,
                         solver=None,
                         edatas=None,
                         force_compile: bool = False):
        """
        Create a pypesto.PetabAmiciObjective.
        """
        # get simulation conditions
        simulation_conditions = petab.get_simulation_conditions(
            self.petab_problem.measurement_df)

        # create model
        if model is None:
            model = self.create_model(force_compile=force_compile)
        # create solver
        if solver is None:
            solver = self.create_solver(model)
        # create conditions and edatas from measurement data
        if edatas is None:
            edatas = self.create_edatas(
                model=model, simulation_conditions=simulation_conditions)

        # simulation <-> optimization parameter mapping
        par_opt_ids = self.petab_problem.get_optimization_parameters()

        parameter_mappings = \
            petab.get_optimization_to_simulation_parameter_mapping(
                condition_df=self.petab_problem.condition_df,
                measurement_df=self.petab_problem.measurement_df,
                parameter_df=self.petab_problem.parameter_df,
                sbml_model=self.petab_problem.sbml_model,
                simulation_conditions=simulation_conditions,
            )

        scale_mappings = \
            petab.get_optimization_to_simulation_scale_mapping(
                parameter_df=self.petab_problem.parameter_df,
                mapping_par_opt_to_par_sim=parameter_mappings,
                measurement_df=self.petab_problem.measurement_df
            )

        # unify and check preeq and sim mappings
        parameter_mapping, scale_mapping = _merge_preeq_and_sim_pars(
            parameter_mappings, scale_mappings)

        # simulation ids (for correct order)
        par_sim_ids = list(model.getParameterIds())

        # create lists from dicts in correct order
        parameter_mapping = _mapping_to_list(parameter_mapping, par_sim_ids)
        scale_mapping = _mapping_to_list(scale_mapping, par_sim_ids)

        # check whether there is something suspicious in the mapping
        _check_parameter_mapping_ok(parameter_mapping, par_sim_ids, model,
                                    edatas)

        # create objective
        obj = PetabAmiciObjective(petab_importer=self,
                                  amici_model=model,
                                  amici_solver=solver,
                                  edatas=edatas,
                                  x_ids=par_opt_ids,
                                  x_names=par_opt_ids,
                                  mapping_par_opt_to_par_sim=parameter_mapping,
                                  mapping_scale_opt_to_scale_sim=scale_mapping)

        return obj
コード例 #6
0
    def create_edatas(self, model=None, simulation_conditions=None):
        """
        Create list of amici.ExpData objects.
        """
        # create model
        if model is None:
            model = self.create_model()

        condition_df = self.petab_problem.condition_df.reset_index()
        measurement_df = self.petab_problem.measurement_df

        # number of amici simulations will be number of unique
        # (preequilibrationConditionId, simulationConditionId) pairs.
        # Can be improved by checking for identical condition vectors.
        if simulation_conditions is None:
            simulation_conditions = petab.get_simulation_conditions(
                measurement_df)

        observable_ids = model.getObservableIds()

        fixed_parameter_ids = model.getFixedParameterIds()

        edatas = []
        for _, condition in simulation_conditions.iterrows():
            # amici.ExpData for each simulation

            # extract rows for condition
            df_for_condition = petab.get_rows_for_condition(
                measurement_df, condition)

            # make list of all timepoints for which measurements exist
            timepoints = sorted(df_for_condition.time.unique().astype(float))

            # init edata object
            edata = amici.ExpData(model.get())

            # find rep numbers of time points
            timepoints_w_reps = []
            for time in timepoints:
                # subselect for time
                df_for_time = df_for_condition[df_for_condition.time == time]
                # rep number is maximum over rep numbers for observables
                n_reps = max(
                    df_for_time.groupby(['observableId', 'time']).size())
                # append time point n_rep times
                timepoints_w_reps.extend([time] * n_reps)

            # set time points in edata
            edata.setTimepoints(timepoints_w_reps)

            # handle fixed parameters
            _handle_fixed_parameters(edata, condition_df, fixed_parameter_ids,
                                     condition)

            # prepare measurement matrix
            y = np.full(shape=(edata.nt(), edata.nytrue()), fill_value=np.nan)
            # prepare sigma matrix
            sigma_y = np.full(shape=(edata.nt(), edata.nytrue()),
                              fill_value=np.nan)

            # add measurements and sigmas
            # iterate over time points
            for time in timepoints:
                # subselect for time
                df_for_time = df_for_condition[df_for_condition.time == time]
                time_ix_0 = timepoints_w_reps.index(time)

                # remember used time indices for each observable
                time_ix_for_obs_ix = {}

                # iterate over measurements
                for _, measurement in df_for_time.iterrows():
                    # extract observable index
                    observable_ix = observable_ids.index(
                        f'observable_{measurement.observableId}')

                    # update time index for observable
                    if observable_ix in time_ix_for_obs_ix:
                        time_ix_for_obs_ix[observable_ix] += 1
                    else:
                        time_ix_for_obs_ix[observable_ix] = time_ix_0

                    # fill observable and possibly noise parameter
                    y[time_ix_for_obs_ix[observable_ix],
                      observable_ix] = measurement.measurement
                    if isinstance(measurement.noiseParameters, numbers.Number):
                        sigma_y[time_ix_for_obs_ix[observable_ix],
                                observable_ix] = measurement.noiseParameters

            # fill measurements and sigmas into edata
            edata.setObservedData(y.flatten())
            edata.setObservedDataStdDev(sigma_y.flatten())

            # append edata to edatas list
            edatas.append(edata)

        return edatas
コード例 #7
0
    def create_objective(self,
                         model: 'amici.Model' = None,
                         solver: 'amici.Solver' = None,
                         edatas: Sequence['amici.ExpData'] = None,
                         force_compile: bool = False,
                         **kwargs) -> AmiciObjective:
        """Create a :class:`pypesto.AmiciObjective`.

        Parameters
        ----------
        model:
            The AMICI model.
        solver:
            The AMICI solver.
        edatas:
            The experimental data in AMICI format.
        force_compile:
            Whether to force-compile the model if not passed.
        **kwargs:
            Additional arguments passed on to the objective.

        Returns
        -------
        objective:
            A :class:`pypesto.AmiciObjective` for the model and the data.
        """
        # get simulation conditions
        simulation_conditions = petab.get_simulation_conditions(
            self.petab_problem.measurement_df)

        # create model
        if model is None:
            model = self.create_model(force_compile=force_compile)
        # create solver
        if solver is None:
            solver = self.create_solver(model)
        # create conditions and edatas from measurement data
        if edatas is None:
            edatas = self.create_edatas(
                model=model, simulation_conditions=simulation_conditions)

        parameter_mapping = amici.petab_objective.create_parameter_mapping(
            petab_problem=self.petab_problem,
            simulation_conditions=simulation_conditions,
            scaled_parameters=True,
            amici_model=model)

        par_ids = self.petab_problem.x_ids

        # fill in dummy parameters (this is needed since some objective
        #  initialization e.g. checks for preeq parameters)
        problem_parameters = {
            key: val
            for key, val in zip(self.petab_problem.x_ids,
                                self.petab_problem.x_nominal_scaled)
        }
        amici.parameter_mapping.fill_in_parameters(
            edatas=edatas,
            problem_parameters=problem_parameters,
            scaled_parameters=True,
            parameter_mapping=parameter_mapping,
            amici_model=model)

        # create objective
        obj = AmiciObjective(amici_model=model,
                             amici_solver=solver,
                             edatas=edatas,
                             x_ids=par_ids,
                             x_names=par_ids,
                             parameter_mapping=parameter_mapping,
                             amici_object_builder=self,
                             **kwargs)

        return obj