예제 #1
0
    def get_parameter_names(self, target_scale: str = 'prior'):
        """Get meaningful parameter names, corrected for target scale."""
        parameter_df = petab.normalize_parameter_df(
            self.petab_problem.parameter_df
        )

        # scale
        if target_scale == C.LIN:
            target_scales = {key: C.LIN for key in self.prior_scales}
        elif target_scale == 'prior':
            target_scales = self.prior_scales
        elif target_scale == 'scaled':
            target_scales = self.scaled_scales
        else:
            raise ValueError(f"Did not recognize target scale {target_scale}")

        names = {}
        for _, row in parameter_df.reset_index().iterrows():
            if row[C.ESTIMATE] == 0:
                continue
            key = row[C.PARAMETER_ID]
            name = str(key)
            if C.PARAMETER_NAME in parameter_df:
                if not petab.is_empty(row[C.PARAMETER_NAME]):
                    name = str(row[C.PARAMETER_NAME])

            target_scale = target_scales[key]
            if target_scale != C.LIN:
                # mini check whether the name might indicate the scale already
                if not name.startswith("log"):
                    name = target_scale + "(" + name + ")"
            names[key] = name
        return names
예제 #2
0
def calculate_residuals_for_table(measurement_df: pd.DataFrame,
                                  simulation_df: pd.DataFrame,
                                  observable_df: pd.DataFrame,
                                  parameter_df: pd.DataFrame,
                                  normalize: bool = True,
                                  scale: bool = True) -> pd.DataFrame:
    """
    Calculate residuals for a single measurement table.
    For the argumenets, see `calculate_residuals`.
    """
    # create residual df as copy of measurement df, change column
    residual_df = measurement_df.copy(deep=True).rename(
        columns={MEASUREMENT: RESIDUAL})

    # matching columns
    compared_cols = set(MEASUREMENT_DF_COLS)
    compared_cols -= {MEASUREMENT}
    compared_cols &= set(measurement_df.columns)
    compared_cols &= set(simulation_df.columns)

    # compute noise formulas for observables
    noise_formulas = get_symbolic_noise_formulas(observable_df)

    # iterate over measurements, find corresponding simulations
    for irow, row in measurement_df.iterrows():
        measurement = row[MEASUREMENT]
        # look up in simulation df
        masks = [(simulation_df[col] == row[col]) | petab.is_empty(row[col])
                 for col in compared_cols]
        mask = reduce(lambda x, y: x & y, masks)
        simulation = simulation_df.loc[mask][SIMULATION].iloc[0]
        if scale:
            # apply scaling
            observable = observable_df.loc[row[OBSERVABLE_ID]]
            trafo = observable.get(OBSERVABLE_TRANSFORMATION, LIN)
            simulation = petab.scale(simulation, trafo)
            measurement = petab.scale(measurement, trafo)

        # non-normalized residual is just the difference
        residual = simulation - measurement

        noise_value = 1
        if normalize:
            # look up noise standard deviation
            noise_value = evaluate_noise_formula(row, noise_formulas,
                                                 parameter_df, simulation)
        residual /= noise_value

        # fill in value
        residual_df.loc[irow, RESIDUAL] = residual
    return residual_df
예제 #3
0
def calculate_llh_for_table(measurement_df: pd.DataFrame,
                            simulation_df: pd.DataFrame,
                            observable_df: pd.DataFrame,
                            parameter_df: pd.DataFrame) -> float:
    """Calculate log-likelihood for one set of tables. For the arguments, see
    `calculate_llh`."""
    llhs = []

    # matching columns
    compared_cols = set(MEASUREMENT_DF_COLS)
    compared_cols -= {MEASUREMENT}
    compared_cols &= set(measurement_df.columns)
    compared_cols &= set(simulation_df.columns)

    # compute noise formulas for observables
    noise_formulas = get_symbolic_noise_formulas(observable_df)

    # iterate over measurements, find corresponding simulations
    for irow, row in measurement_df.iterrows():
        measurement = row[MEASUREMENT]

        # look up in simulation df
        masks = [(simulation_df[col] == row[col]) | petab.is_empty(row[col])
                 for col in compared_cols]
        mask = reduce(lambda x, y: x & y, masks)

        simulation = simulation_df.loc[mask][SIMULATION].iloc[0]

        observable = observable_df.loc[row[OBSERVABLE_ID]]

        # get scale
        scale = observable.get(OBSERVABLE_TRANSFORMATION, LIN)

        # get noise standard deviation
        noise_value = evaluate_noise_formula(row, noise_formulas, parameter_df,
                                             petab.scale(simulation, scale))

        # get noise distribution
        noise_distribution = observable.get(NOISE_DISTRIBUTION, NORMAL)

        llh = calculate_single_llh(measurement, simulation, scale,
                                   noise_distribution, noise_value)
        llhs.append(llh)
    llh = sum(llhs)
    return llh