def _write_bounds(self): """ Parameter bounds for optimizer Offset parameters are allowed to be negative """ lower_bound = np.array([ petab.scale( self.petab_problem.parameter_df.loc[par_id, ptc.LOWER_BOUND], self.petab_problem.parameter_df.loc[par_id, ptc.PARAMETER_SCALE]) for par_id in self.problem_parameter_ids ]) upper_bound = np.array([ petab.scale( self.petab_problem.parameter_df.loc[par_id, ptc.UPPER_BOUND], self.petab_problem.parameter_df.loc[par_id, ptc.PARAMETER_SCALE]) for par_id in self.problem_parameter_ids ]) self.f.require_dataset('/parameters/lowerBound', shape=lower_bound.shape, data=lower_bound, dtype='f8') self.f.require_dataset('/parameters/upperBound', shape=upper_bound.shape, data=upper_bound, dtype='f8')
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
def test_scale_unscale(): """Test the parameter scaling functions.""" par = 2.5 # scale assert petab.scale(par, LIN) == par assert petab.scale(par, LOG) == np.log(par) assert petab.scale(par, LOG10) == np.log10(par) # unscale assert petab.unscale(par, LIN) == par assert petab.unscale(par, LOG) == np.exp(par) assert petab.unscale(par, LOG10) == 10**par # map scale assert list(petab.map_scale([par]*3, [LIN, LOG, LOG10])) == \ [par, np.log(par), np.log10(par)] # map unscale assert list(petab.map_unscale([par]*3, [LIN, LOG, LOG10])) == \ [par, np.exp(par), 10**par] # map broadcast assert list(petab.map_scale([par, 2*par], LOG)) == \ list(np.log([par, 2*par])) assert list(petab.map_unscale([par, 2*par], LOG)) == \ list(np.exp([par, 2*par]))
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
def rescale(val: Number, origin_scale: str, target_scale: str) -> Number: """Convert parameter value from origin scale to target scale. Parameters ---------- val: Parameter value to rescale. origin_scale: Origin scale. target_scale: Target scale. Returns ------- val: The rescaled parameter value. """ if origin_scale == target_scale: # nothing to be done return val # origin to linear to target return petab.scale(petab.unscale(val, origin_scale), target_scale)