Source code for pharmpy.modeling.parameters

from __future__ import annotations

from collections.abc import Mapping
from typing import Iterable, Optional, Union

from pharmpy.basic import Expr
from pharmpy.model import Assignment, Model, Parameter, Parameters, RandomVariables


[docs] def get_thetas(model: Model): """Get all thetas (structural parameters) of a model Parameters ---------- model : Model Pharmpy model object Returns ------- Parameters A copy of all theta parameters Example ------- >>> from pharmpy.modeling import * >>> model = load_example_model("pheno") >>> get_thetas(model) value lower upper fix POP_CL 0.004693 0.00 ∞ False POP_VC 1.009160 0.00 ∞ False COVAPGR 0.100000 -0.99 ∞ False See also -------- get_omegas : Get omega parameters get_sigmas : Get sigma parameters """ rvs_fs = model.random_variables.free_symbols thetas = [p for p in model.parameters if p.symbol not in rvs_fs] return Parameters(tuple(thetas))
[docs] def get_omegas(model: Model): """Get all omegas (variability parameters) of a model Parameters ---------- model : Model Pharmpy model object Returns ------- Parameters A copy of all omega parameters Example ------- >>> from pharmpy.modeling import * >>> model = load_example_model("pheno") >>> get_omegas(model) value lower upper fix IIV_CL 0.030963 0.0 ∞ False IIV_VC 0.031128 0.0 ∞ False See also -------- get_thetas : Get theta parameters get_sigmas : Get sigma parameters """ omegas = [p for p in model.parameters if p.symbol in model.random_variables.etas.free_symbols] return Parameters(tuple(omegas))
[docs] def get_sigmas(model: Model): """Get all sigmas (residual error variability parameters) of a model Parameters ---------- model : Model Pharmpy model object Returns ------- Parameters A copy of all sigma parameters Example ------- >>> from pharmpy.modeling import * >>> model = load_example_model("pheno") >>> get_sigmas(model) value lower upper fix SIGMA 0.013086 0.0 ∞ False See also -------- get_thetas : Get theta parameters get_omegas : Get omega parameters """ sigmas = [ p for p in model.parameters if p.symbol in model.random_variables.epsilons.free_symbols ] return Parameters(tuple(sigmas))
[docs] def set_initial_estimates( model: Model, inits: Mapping[str, float], move_est_close_to_bounds: bool = False, strict: bool = True, ): """Update initial parameter estimate for a model Updates initial estimates of population parameters for a model. If the new initial estimates are out of bounds or NaN this function will raise. Parameters ---------- model : Model Pharmpy model to update initial estimates inits : pd.Series or dict Initial parameter estimates to update move_est_close_to_bounds : bool Move estimates that are close to bounds. If correlation >0.99 the correlation will be set to 0.9, if variance is <0.001 the variance will be set to 0.01. strict : bool Whether all parameters in input need to exist in the model. Default is True Returns ------- Model Pharmpy model object Example ------- >>> from pharmpy.modeling import load_example_model, set_initial_estimates >>> from pharmpy.tools import load_example_modelfit_results >>> model = load_example_model("pheno") >>> results = load_example_modelfit_results("pheno") >>> model.parameters.inits # doctest:+ELLIPSIS {'POP_CL': 0.00469307, 'POP_VC': 1.00916, 'COVAPGR': 0.1, 'IIV_CL': 0.0309626, 'IIV_VC': ...} >>> model = set_initial_estimates(model, results.parameter_estimates) >>> model.parameters.inits # doctest:+ELLIPSIS {'POP_CL': 0.00469555, 'POP_VC': 0.984258, 'COVAPGR': 0.15892, 'IIV_CL': 0.0293508, ...} >>> model = load_example_model("pheno") >>> model = set_initial_estimates(model, {'POP_CL': 2.0}) >>> model.parameters['POP_CL'] Parameter("POP_CL", 2.0, lower=0.0, upper=∞, fix=False) See also -------- fix_parameters_to : Fixing and setting parameter initial estimates in the same function unfix_paramaters_to : Unfixing parameters and setting a new initial estimate in the same """ if strict: _check_input_params(model, inits.keys()) if move_est_close_to_bounds: inits = _move_est_close_to_bounds(model, inits) new = model.parameters.set_initial_estimates(inits) model = model.replace(parameters=new) return model.update_source()
def _get_nonfixed_rvs(model): fixed_omegas = get_omegas(model).fixed.names rvs = model.random_variables nonfixed_rvs = [rv for rv in rvs if str(list(rv.variance.free_symbols)[0]) not in fixed_omegas] return RandomVariables.create(nonfixed_rvs) def _move_est_close_to_bounds(model: Model, est_new): rvs, pset = _get_nonfixed_rvs(model), model.parameters parameter_estimates = model.parameters.inits parameter_estimates.update(est_new) # Need all numerical values for sdcorr sdcorr = rvs.parameters_sdcorr(parameter_estimates) newdict = est_new.copy() for dist in rvs: rvs = dist.names if len(rvs) > 1: sigma_sym = dist.variance for i in range(sigma_sym.rows): for j in range(sigma_sym.cols): param_name = sigma_sym[i, j].name if i != j: if sdcorr[param_name] > 0.99: name_i, name_j = sigma_sym[i, i].name, sigma_sym[j, j].name # From correlation to covariance corr_new = 0.9 sd_i, sd_j = sdcorr[name_i], sdcorr[name_j] newdict[param_name] = corr_new * sd_i * sd_j else: if param_name in est_new.keys(): if not _is_zero_fix(pset[param_name]) and est_new[param_name] < 0.001: newdict[param_name] = 0.01 else: param_name = dist.variance.name if not pset[param_name].fix: if param_name in est_new.keys(): if not _is_zero_fix(pset[param_name]) and est_new[param_name] < 0.001: newdict[param_name] = 0.01 return newdict def _is_zero_fix(param): return param.init == 0 and param.fix
[docs] def set_upper_bounds(model: Model, bounds: Mapping[str, float], strict: bool = True): """Set parameter upper bounds Parameters ---------- model : Model Pharmpy model bounds : dict A dictionary of parameter bounds for parameters to change strict : bool Whether all parameters in input need to exist in the model. Default is True Returns ------- Model Pharmpy model object Examples -------- >>> from pharmpy.modeling import load_example_model, set_upper_bounds >>> model = load_example_model("pheno") >>> model = set_upper_bounds(model, {'POP_CL': 10}) >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=0.0, upper=10, fix=False) See also -------- set_lower_bounds : Set parameter lower bounds unconstrain_parameters : Remove all constraints of parameters """ if strict: _check_input_params(model, bounds.keys()) new = [] for p in model.parameters: if p.name in bounds: newparam = Parameter( name=p.name, init=p.init, lower=p.lower, upper=bounds[p.name], fix=p.fix ) else: newparam = p new.append(newparam) model = model.replace(parameters=Parameters(tuple(new))) return model.update_source()
[docs] def set_lower_bounds(model: Model, bounds: Mapping[str, float], strict: bool = True): """Set parameter lower bounds Parameters ---------- model : Model Pharmpy model bounds : dict A dictionary of parameter bounds for parameters to change strict : bool Whether all parameters in input need to exist in the model. Default is True Returns ------- Model Pharmpy model object Examples -------- >>> from pharmpy.modeling import load_example_model, set_lower_bounds >>> model = load_example_model("pheno") >>> model = set_lower_bounds(model, {'POP_CL': -10}) >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=-10, upper=∞, fix=False) See also -------- set_upper_bounds : Set parameter upper bounds unconstrain_parameters : Remove all constraints of parameters """ if strict: _check_input_params(model, bounds.keys()) new = [] for p in model.parameters: if p.name in bounds: newparam = Parameter( name=p.name, init=p.init, lower=bounds[p.name], upper=p.upper, fix=p.fix ) else: newparam = p new.append(newparam) model = model.replace(parameters=Parameters(tuple(new))) model = model.update_source() return model
[docs] def fix_parameters(model: Model, parameter_names: Union[Iterable[str], str], strict: bool = True): """Fix parameters Fix all listed parameters Parameters ---------- model : Model Pharmpy model parameter_names : list or str one parameter name or a list of parameter names strict : bool Whether all parameters in input need to exist in the model. Default is True Returns ------- Model Pharmpy model object Example ------- >>> from pharmpy.modeling import fix_parameters, load_example_model >>> model = load_example_model("pheno") >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=0.0, upper=∞, fix=False) >>> model = fix_parameters(model, 'POP_CL') >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=0.0, upper=∞, fix=True) See also -------- fix_or_unfix_parameters : Fix or unfix parameters (given boolean) fix_parameters_to : Fixing and setting parameter initial estimates in the same function unfix_paramaters : Unfixing parameters unfix_paramaters_to : Unfixing parameters and setting a new initial estimate in the same function """ if isinstance(parameter_names, str): parameter_names = [parameter_names] if strict: _check_input_params(model, parameter_names) params = model.parameters new = [] for p in params: if p.name in parameter_names: new_param = p.replace(fix=True) else: new_param = p new.append(new_param) model = model.replace(parameters=Parameters(tuple(new))) return model.update_source()
def _check_input_params(model, parameter_names): params_not_in_model = [ p_name for p_name in parameter_names if p_name not in model.parameters.names ] if params_not_in_model: raise ValueError(f'Parameters not found in model: {params_not_in_model}')
[docs] def unfix_parameters(model: Model, parameter_names: Union[Iterable[str], str], strict: bool = True): """Unfix parameters Unfix all listed parameters Parameters ---------- model : Model Pharmpy model parameter_names : list or str one parameter name or a list of parameter names strict : bool Whether all parameters in input need to exist in the model. Default is True Returns ------- Model Pharmpy model object Examples -------- >>> from pharmpy.modeling import fix_parameters, unfix_parameters, load_example_model >>> model = load_example_model("pheno") >>> model = fix_parameters(model, ['POP_CL', 'POP_VC']) >>> model.parameters.fix # doctest: +ELLIPSIS {'POP_CL': True, 'POP_VC': True, ...} >>> model = unfix_parameters(model, 'POP_CL') >>> model.parameters.fix # doctest: +ELLIPSIS {'POP_CL': False, 'POP_VC': True, ...} See also -------- unfix_paramaters_to : Unfixing parameters and setting a new initial estimate in the same function fix_parameters : Fix parameters fix_or_unfix_parameters : Fix or unfix parameters (given boolean) fix_parameters_to : Fixing and setting parameter initial estimates in the same function unconstrain_parameters : Remove all constraints of parameters """ if isinstance(parameter_names, str): parameter_names = [parameter_names] if strict: _check_input_params(model, parameter_names) params = model.parameters new = [] for p in params: if p.name in parameter_names: new_param = p.replace(fix=False) else: new_param = p new.append(new_param) model = model.replace(parameters=Parameters(tuple(new))) model = model.update_source() return model
[docs] def fix_parameters_to(model: Model, inits: Mapping[str, float], strict: bool = True): """Fix parameters to Fix all listed parameters to specified value/values Parameters ---------- model : Model Pharmpy model inits : dict Inits for all parameters to fix and set init strict : bool Whether all parameters in input need to exist in the model. Default is True Returns ------- Model Pharmpy model object Examples -------- >>> from pharmpy.modeling import fix_parameters_to, load_example_model >>> model = load_example_model("pheno") >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=0.0, upper=∞, fix=False) >>> model = fix_parameters_to(model, {'POP_CL': 0.5}) >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.5, lower=0.0, upper=∞, fix=True) See also -------- fix_parameters : Fix parameters fix_or_unfix_parameters : Fix or unfix parameters (given boolean) unfix_paramaters : Unfixing parameters unfix_paramaters_to : Unfixing parameters and setting a new initial estimate in the same function """ model = fix_parameters(model, inits.keys(), strict=strict) model = set_initial_estimates(model, inits, strict=strict) return model
[docs] def unfix_parameters_to(model: Model, inits: Mapping[str, float], strict: bool = True): """Unfix parameters to Unfix all listed parameters to specified value/values Parameters ---------- model : Model Pharmpy model inits : dict Inits for all parameters to unfix and change init strict : bool Whether all parameters in input need to exist in the model. Default is True Examples -------- >>> from pharmpy.modeling import fix_parameters, unfix_parameters_to, load_example_model >>> model = load_example_model("pheno") >>> model = fix_parameters(model, ['POP_CL', 'POP_VC']) >>> model.parameters.fix # doctest: +ELLIPSIS {'POP_CL': True, 'POP_VC': True, 'COVAPGR': False, 'IIV_CL': False, 'IIV_VC': False, 'SIGMA': False} >>> model = unfix_parameters_to(model, {'POP_CL': 0.5}) >>> model.parameters.fix # doctest: +ELLIPSIS {'POP_CL': False, 'POP_VC': True, 'COVAPGR': False, ...} >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.5, lower=0.0, upper=∞, fix=False) Returns ------- Model Pharmpy model object See also -------- fix_parameters : Fix parameters fix_or_unfix_parameters : Fix or unfix parameters (given boolean) unfix_paramaters : Unfixing parameters fix_paramaters_to : Fixing parameters and setting a new initial estimate in the same function """ model = unfix_parameters(model, inits.keys(), strict=strict) model = set_initial_estimates(model, inits, strict=strict) return model
[docs] def fix_or_unfix_parameters(model: Model, parameters: Mapping[str, bool], strict: bool = True): """Fix or unfix parameters Set fixedness of parameters to specified values Parameters ---------- model : Model Pharmpy model parameters : dict Set fix/unfix for these parameters strict : bool Whether all parameters in input need to exist in the model. Default is True Examples -------- >>> from pharmpy.modeling import fix_or_unfix_parameters, load_example_model >>> model = load_example_model("pheno") >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=0.0, upper=∞, fix=False) >>> model = fix_or_unfix_parameters(model, {'POP_CL': True}) >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=0.0, upper=∞, fix=True) Returns ------- Model Pharmpy model object See also -------- fix_parameters : Fix parameters unfix_paramaters : Unfixing parameters fix_paramaters_to : Fixing parameters and setting a new initial estimate in the same function unfix_paramaters_to : Unfixing parameters and setting a new initial estimate in the same function """ if strict: _check_input_params(model, parameters.keys()) params = model.parameters new = [] for p in params: if p.name in parameters: new_param = p.replace(fix=parameters[p.name]) else: new_param = p new.append(new_param) model = model.replace(parameters=Parameters(tuple(new))) model = model.update_source() return model
[docs] def unconstrain_parameters(model: Model, parameter_names: Iterable[str], strict: bool = True): """Remove all constraints from parameters Parameters ---------- model : Model Pharmpy model parameter_names : list Remove all constraints for the listed parameters strict : bool Whether all parameters in input need to exist in the model. Default is True Examples -------- >>> from pharmpy.modeling import unconstrain_parameters, load_example_model >>> model = load_example_model("pheno") >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=0.0, upper=∞, fix=False) >>> model = unconstrain_parameters(model, ['POP_CL']) >>> model.parameters['POP_CL'] Parameter("POP_CL", 0.00469307, lower=-∞, upper=∞, fix=False) Returns ------- Model Pharmpy model object See also -------- set_lower_bounds : Set parameter lower bounds set_upper_bounds : Set parameter upper bounds unfix_parameters : Unfix parameters """ if isinstance(parameter_names, str): parameter_names = [parameter_names] if strict: _check_input_params(model, parameter_names) new = [] for p in model.parameters: if p.name in parameter_names: newparam = Parameter(name=p.name, init=p.init) else: newparam = p new.append(newparam) model = model.replace(parameters=Parameters(tuple(new))) model = model.update_source() return model
[docs] def add_population_parameter( model: Model, name: str, init: float, lower: Optional[float] = None, upper: Optional[float] = None, fix: bool = False, ): """Add a new population parameter to the model Parameters ---------- model : Model Pharmpy model name : str Name of the new parameter init : float Initial estimate of the new parameter lower : float Lower bound of the new parameter upper : float Upper bound of the new parameter fix : bool Should the new parameter be fixed? Returns ------- Model Pharmpy model object Examples -------- >>> from pharmpy.modeling import add_population_parameter, load_example_model >>> model = load_example_model("pheno") >>> model = add_population_parameter(model, 'POP_KA', 2) >>> model.parameters value lower upper fix POP_CL 0.004693 0.0 ∞ False POP_VC 1.009160 0.0 ∞ False COVAPGR 0.100000 -0.99 ∞ False IIV_CL 0.030963 0.0 ∞ False IIV_VC 0.031128 0.0 ∞ False SIGMA 0.013086 0.0 ∞ False POP_KA 2.000000 -∞ ∞ False """ param = Parameter.create(name, init, lower=lower, upper=upper, fix=fix) params = model.parameters + param model = model.replace(parameters=params) return model.update_source()
[docs] def replace_fixed_thetas(model: Model): """Replace all fixed thetas with constants in the model statements Parameters ---------- model : Model Pharmpy model Returns ------- Model A new model """ keep = [] new_assignments = [] for p in model.parameters: if p.fix: ass = Assignment(p.symbol, Expr.float(p.init)) new_assignments.append(ass) else: keep.append(p) model = model.replace( parameters=Parameters(tuple(keep)), statements=new_assignments + model.statements ) model = model.update_source() return model