def _create_thetas(model, effect, covariate, template): """Creates theta parameters and adds to parameter set of model. Number of parameters depends on how many thetas have been declared.""" no_of_thetas = len( re.findall(r'theta\d*', str(repr(template)), re.IGNORECASE)) pset = model.parameters theta_names = dict() theta_name = str(model.create_symbol(stem='COVEFF', force_numbering=True)) if no_of_thetas == 1: inits = _choose_param_inits(effect, model.dataset, covariate) pset.add( Parameter(theta_name, inits['init'], inits['lower'], inits['upper'])) theta_names['theta'] = theta_name else: cov_eff_number = int(re.findall(r'\d', theta_name)[0]) for i in range(1, no_of_thetas + 1): inits = _choose_param_inits(effect, model.dataset, covariate, i) pset.add( Parameter(theta_name, inits['init'], inits['lower'], inits['upper'])) theta_names[f'theta{i}'] = theta_name theta_name = f'COVEFF{cov_eff_number + i}' model.parameters = pset return theta_names
def _create_thetas(model, parameter, effect, covariate, template): """Creates theta parameters and adds to parameter set of model. Number of parameters depends on how many thetas have been declared.""" no_of_thetas = len( re.findall(r'theta\d*', str(repr(template)), re.IGNORECASE)) pset = model.parameters theta_names = dict() if no_of_thetas == 1: inits = _choose_param_inits(effect, model.dataset, covariate) theta_name = f'POP_{parameter}{covariate}' pset.append( Parameter(theta_name, inits['init'], inits['lower'], inits['upper'])) theta_names['theta'] = theta_name else: for i in range(1, no_of_thetas + 1): inits = _choose_param_inits(effect, model.dataset, covariate, i) theta_name = f'POP_{parameter}{covariate}_{i}' pset.append( Parameter(theta_name, inits['init'], inits['lower'], inits['upper'])) theta_names[f'theta{i}'] = theta_name model.parameters = pset return theta_names
def test_is_close_to_bound_pset(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3, lower=1, upper=24) p3 = Parameter('Z', 1, lower=0, upper=2) pset1 = Parameters([p1, p2, p3]) assert not pset1.is_close_to_bound().any() assert not pset1.is_close_to_bound(pd.Series({'X': 3.5, 'Y': 19})).any()
def test_pset_names(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3) p3 = Parameter('Z', 1) pset = ParameterSet([p1, p2, p3]) assert pset.names == ['Y', 'X', 'Z'] assert pset.symbols == [symbol('Y'), symbol('X'), symbol('Z')]
def set_dtbs_error(model): """Dynamic transform both sides""" theta_as_stdev(model) set_weighted_error_model(model) stats, y, f = _preparations(model) tbs_lambda = Parameter('tbs_lambda', 1) tbs_zeta = Parameter('tbs_zeta', 0.001) model.parameters.append(tbs_lambda) model.parameters.append(tbs_zeta) lam = tbs_lambda.symbol zeta = tbs_zeta.symbol for i, s in enumerate(stats): if isinstance(s, Assignment) and s.symbol == sympy.Symbol('W'): break stats.insert(i + 1, Assignment('W', (f ** zeta) * sympy.Symbol('W'))) ipred = sympy.Piecewise( ((f ** lam - 1) / lam, sympy.And(sympy.Ne(lam, 0), sympy.Ne(f, 0))), (sympy.log(f), sympy.And(sympy.Eq(lam, 0), sympy.Ne(f, 0))), (-1 / lam, sympy.And(sympy.Eq(lam, 0), sympy.Eq(f, 0))), (-1000000000, True), ) stats.insert(i + 2, Assignment('IPRED', ipred)) yexpr = stats.find_assignment(y.name) yexpr.subs({f: sympy.Symbol('IPRED')}) obs = sympy.Piecewise( (sympy.log(y), sympy.Eq(lam, 0)), ((y ** lam - 1) / lam, sympy.Ne(lam, 0)) ) model.observation_transformation = obs return model
def test_pset_getitem(): p = Parameter('Y', 9) pset = Parameters((p, )) assert len(pset) == 1 assert pset['Y'] is p p2 = Parameter('Z', 5) pset.append(p2) assert len(pset) == 2 # Check that the parameter set keeps the insertion order upon iteration for i, param in enumerate(pset): if i == 0: assert param is p else: assert param is p2 assert pset[symbol('Z')] == p2 p3 = Parameter('K', 19) with pytest.raises(KeyError): pset[p3] assert len(pset[[p]]) == 1
def test_add_random_variables_and_statements(pheno_path): model = Model(pheno_path) rvs = model.random_variables pset = model.parameters eta = RandomVariable.normal('ETA_NEW', 'iiv', 0, S('omega')) rvs.append(eta) pset.append(Parameter('omega', 0.1)) eps = RandomVariable.normal('EPS_NEW', 'ruv', 0, S('sigma')) rvs.append(eps) pset.append(Parameter('sigma', 0.1)) model.random_variables = rvs model.parameters = pset sset = model.get_pred_pk_record().statements statement_new = Assignment(S('X'), 1 + S(eps.name) + S(eta.name)) sset.append(statement_new) model.get_pred_pk_record().statements = sset model.update_source() assert str(model.get_pred_pk_record()).endswith('X = 1 + ETA(3) + EPS(2)\n\n')
def _create_new_thetas(model, transformation, no_of_thetas): pset = model.parameters thetas = dict() theta_name = str( model.create_symbol(stem=transformation, force_numbering=True)) if transformation == 'lambda': param_settings = [0.01, -3, 3] else: param_settings = [80, 3, 100] if no_of_thetas == 1: pset.append(Parameter(theta_name, *param_settings)) thetas['theta1'] = theta_name else: theta_no = int(re.findall(r'\d', theta_name)[0]) for i in range(1, no_of_thetas + 1): pset.append(Parameter(theta_name, 0.01, -3, 3)) thetas[f'theta{i}'] = theta_name theta_name = f'{transformation}{theta_no + i}' model.parameters = pset return thetas
def test_pset_nonfixed_inits(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3) p3 = Parameter('Z', 1) pset = Parameters([p1, p2, p3]) assert pset.nonfixed_inits == {'Y': 9, 'X': 3, 'Z': 1} pset['X'].fix = True assert pset.nonfixed_inits == {'Y': 9, 'Z': 1}
def test_pset_remove_fixed(): p1 = Parameter('Y', 9, fix=False) p2 = Parameter('X', 3, fix=True) p3 = Parameter('Z', 1, fix=False) pset = ParameterSet([p1, p2, p3]) pset.remove_fixed() assert len(pset) == 2 assert pset['Y'] == Parameter('Y', 9)
def test_pset_discard(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3) p3 = Parameter('Z', 1) pset1 = Parameters([p1, p2, p3]) del pset1[p2] assert len(pset1) == 2 del pset1['Y'] assert len(pset1) == 1
def test_pset_fix(): p1 = Parameter('Y', 9, fix=False) p2 = Parameter('X', 3, fix=True) p3 = Parameter('Z', 1, fix=False) pset = ParameterSet([p1, p2, p3]) assert pset.fix == {'Y': False, 'X': True, 'Z': False} fixedness = {'Y': True, 'X': True, 'Z': True} pset.fix = fixedness assert pset.fix == {'Y': True, 'X': True, 'Z': True}
def test_pset_add(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3) p3 = Parameter('Z', 1) pset1 = Parameters([p1, p2]) pset1.append(p3) assert len(pset1) == 3 with pytest.raises(ValueError): pset1.append(23)
def test_pset_eq(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3) p3 = Parameter('Z', 1) pset1 = ParameterSet([p1, p2, p3]) pset2 = ParameterSet([p1, p2]) assert pset1 != pset2 pset3 = ParameterSet([p1, p3, p2]) assert pset1 != pset3 assert pset1 == pset1
def test_pset_fix(): p1 = Parameter('Y', 9, fix=False) p2 = Parameter('X', 3, fix=True) p3 = Parameter('Z', 1, fix=False) pset = Parameters([p1, p2, p3]) assert pset.fix == {'Y': False, 'X': True, 'Z': False} fixedness = {'Y': True, 'X': True, 'Z': True} pset.fix = fixedness assert pset.fix == {'Y': True, 'X': True, 'Z': True} with pytest.raises(KeyError): pset.fix = {'K': True}
def test_copy_pset(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3, lower=1, upper=24) p3 = Parameter('Z', 1, lower=0, upper=2) pset1 = Parameters([p1, p2, p3]) pset2 = pset1.copy() assert pset1 == pset2 assert id(pset1[0]) != id(pset2[0]) p4 = p1.copy() assert p4 == p1 assert id(p4) != id(p1)
def test_insert(): p1 = Parameter('Y', 9) p2 = Parameter('X', 3, lower=1, upper=24) p3 = Parameter('Z', 1, lower=0, upper=2) pset1 = Parameters([p1, p2]) pset1.insert(0, p3) assert pset1.names == ['Z', 'Y', 'X'] p4 = Parameter('Y', 0) with pytest.raises(ValueError): pset1.insert(1, p4)
def combined_error(model, data_trans=None): r"""Set a combined error model. Initial estimates for new sigmas are :math:`(min(DV)/2)²` for proportional and 0.09 for additive. The error function being applied depends on the data transformation. +------------------------+-----------------------------------------------------+ | Data transformation | Combined error | +========================+=====================================================+ | :math:`y` | :math:`f + f \epsilon_1 + \epsilon_2` | +------------------------+-----------------------------------------------------+ | :math:`log(y)` | :math:`\log(f) + \epsilon_1 + \frac{\epsilon_2}{f}` | +------------------------+-----------------------------------------------------+ Parameters ---------- model : Model Set error model for this model data_trans : str or expression A data transformation expression or None (default) to use the transformation specified by the model. """ if has_combined_error(model): return model stats, y, f = _preparations(model) ruv_prop = model.create_symbol('epsilon_p') ruv_add = model.create_symbol('epsilon_a') data_trans = pharmpy.model.canonicalize_data_transformation(model, data_trans) if data_trans == sympy.log(model.dependent_variable): expr = sympy.log(f) + ruv_prop + ruv_add / f elif data_trans == model.dependent_variable: expr = f + f * ruv_prop + ruv_add else: raise ValueError(f"Not supported data transformation {data_trans}") stats.reassign(y, expr) model.remove_unused_parameters_and_rvs() # FIXME: Refactor to model.add_parameter sigma_prop = model.create_symbol('sigma_prop') sigma_par1 = Parameter(sigma_prop.name, init=0.09) model.parameters.append(sigma_par1) sigma_add = model.create_symbol('sigma_add') sigma_par2 = Parameter(sigma_add.name, init=_get_prop_init(model.dataset)) model.parameters.append(sigma_par2) eps_prop = RandomVariable.normal(ruv_prop.name, 'RUV', 0, sigma_prop) model.random_variables.append(eps_prop) eps_add = RandomVariable.normal(ruv_add.name, 'RUV', 0, sigma_add) model.random_variables.append(eps_add) return model
def test_pset_init(): p = Parameter('Y', 9) pset = Parameters([p]) pset2 = Parameters(pset) assert len(pset2) == 1 assert pset2['Y'].init == 9 p2 = Parameter('Y', 12) with pytest.raises(ValueError): Parameters([p, p2]) with pytest.raises(ValueError): Parameters([23])
def test_set_parameters(pheno_path): model = Model(pheno_path) params = { 'THETA(1)': 0.75, 'THETA(2)': 0.5, 'THETA(3)': 0.25, 'OMEGA(1,1)': 0.1, 'OMEGA(2,2)': 0.2, 'SIGMA(1,1)': 0.3, } model.parameters = params assert model.parameters['THETA(1)'] == Parameter('THETA(1)', 0.75, lower=0, upper=1000000) assert model.parameters['THETA(2)'] == Parameter('THETA(2)', 0.5, lower=0, upper=1000000) assert model.parameters['THETA(3)'] == Parameter('THETA(3)', 0.25, lower=-0.99, upper=1000000) assert model.parameters['OMEGA(1,1)'] == Parameter('OMEGA(1,1)', 0.1, lower=0, upper=sympy.oo) assert model.parameters['OMEGA(2,2)'] == Parameter('OMEGA(2,2)', 0.2, lower=0, upper=sympy.oo) assert model.parameters['SIGMA(1,1)'] == Parameter('SIGMA(1,1)', 0.3, lower=0, upper=sympy.oo) model.update_source() thetas = model.control_stream.get_records('THETA') assert str(thetas[0]) == '$THETA (0,0.75) ; PTVCL\n' assert str(thetas[1]) == '$THETA (0,0.5) ; PTVV\n' assert str(thetas[2]) == '$THETA (-.99,0.25)\n' omegas = model.control_stream.get_records('OMEGA') assert str(omegas[0]) == '$OMEGA DIAGONAL(2)\n 0.1 ; IVCL\n 0.2 ; IVV\n\n' sigmas = model.control_stream.get_records('SIGMA') assert str(sigmas[0]) == '$SIGMA 0.3\n' model = Model(pheno_path) params = model.parameters params['THETA(1)'].init = 18 model.parameters = params assert model.parameters['THETA(1)'] == Parameter('THETA(1)', 18, lower=0, upper=1000000) assert model.parameters['THETA(2)'] == Parameter('THETA(2)', 1.00916, lower=0, upper=1000000)
def test_pset_setitem(): p1 = Parameter('P1', 1) p2 = Parameter('P2', 2) p3 = Parameter('P3', 3) ps = Parameters([p1, p2, p3]) p4 = Parameter('P4', 4) ps[p1] = p4 assert len(ps) == 3 assert ps[0].name == 'P4' with pytest.raises(ValueError): ps[0] = 23 p5 = Parameter('P4', 0) with pytest.raises(ValueError): ps[1] = p5
def test_add_two_parameters(pheno_path): model = Model(pheno_path) pset = model.parameters assert len(pset) == 6 param_1 = Parameter('COVEFF1', 0.2) param_2 = Parameter('COVEFF2', 0.1) pset.append(param_1) pset.append(param_2) model.parameters = pset model.update_source() assert len(pset) == 8 assert model.parameters[param_1.name].init == 0.2 assert model.parameters[param_2.name].init == 0.1
def power_on_ruv(model, list_of_eps=None): """ Applies a power effect to provided epsilons. Initial estimates for new thetas are 1 if the error model is proportional, otherwise they are 0.1. Parameters ---------- model : Model Pharmpy model to create block effect on. list_of_eps : str, list Name/names of epsilons to apply power effect. If None, all epsilons will be used. None is default. """ list_of_eps = _format_input_list(list_of_eps) eps = model.random_variables.epsilons if list_of_eps is not None: eps = eps[list_of_eps] pset, sset = model.parameters, model.statements if has_proportional_error(model): theta_init = 1 else: theta_init = 0.1 for i, e in enumerate(eps): theta_name = str(model.create_symbol(stem='power', force_numbering=True)) theta = Parameter(theta_name, theta_init) pset.append(theta) sset.subs({e.name: model.individual_prediction_symbol ** S(theta.name) * e.symbol}) model.parameters = pset model.statements = sset return model
def power_on_ruv(model, list_of_eps=None): """ Applies a power effect to provided epsilons. Initial estimates for new thetas are 1 if the error model is proportional, otherwise they are 0.1. Parameters ---------- model : Model Pharmpy model to create block effect on. list_of_eps : list List of epsilons to apply power effect. If None, all epsilons will be used. None is default. """ eps = _get_epsilons(model, list_of_eps) pset, sset = model.parameters, model.statements if model.error_model == 'PROP': theta_init = 1 else: theta_init = 0.1 for i, e in enumerate(eps): theta_name = str( model.create_symbol(stem='power', force_numbering=True)) theta = Parameter(theta_name, theta_init) pset.add(theta) sset.subs( {e.name: model.individual_prediction_symbol**S(theta.name) * e}) model.parameters = pset model.statements = sset return model
def parameters(self, first_theta): """Get a parameter set for this theta record. first_theta is the number of the first theta in this record """ pset = ParameterSet() current_theta = first_theta for theta in self.root.all('theta'): init = theta.init.tokens[0].eval fix = bool(theta.find('FIX')) if theta.find('low'): if theta.low.find('NEG_INF'): lower = min_lower_bound else: lower = theta.low.tokens[0].eval else: lower = min_lower_bound if theta.find('up'): if theta.up.find('POS_INF'): upper = max_upper_bound else: upper = theta.up.tokens[0].eval else: upper = max_upper_bound multiple = theta.find('n') if multiple: n = multiple.INT else: n = 1 for i in range(0, n): new_par = Parameter(f'THETA({current_theta})', init, lower, upper, fix) current_theta += 1 pset.add(new_par) return pset
def _add_parameter(model, name, init=0.1): pops = model.create_symbol(f'POP_{name}') pop_param = Parameter(pops.name, init=init, lower=0) model.parameters.add(pop_param) symb = model.create_symbol(name) ass = Assignment(symb, pop_param.symbol) model.statements.insert(0, ass) return symb
def _create_eta(pset, number): omega = S(f'IIV_RUV{number}') pset.add(Parameter(str(omega), 0.09)) eta = stats.Normal(f'RV{number}', 0, sympy.sqrt(omega)) eta.variability_level = VariabilityLevel.IIV return eta
def test_pset_repr(): p1 = Parameter('Y', 9, fix=False) pset = ParameterSet([p1]) assert type(repr(pset)) == str assert type(pset._repr_html_()) == str pset = ParameterSet() assert type(repr(pset)) == str assert type(pset._repr_html_()) == str
def test_pset_index(): p = Parameter('Y', 9) pset = ParameterSet((p, )) assert len(pset) == 1 assert pset['Y'] is p p2 = Parameter('Z', 5) pset.add(p2) assert len(pset) == 2 # Check that the parameter set keeps the insertion order upon iteration for i, param in enumerate(pset): if i == 0: assert param is p else: assert param is p2
def test_unconstrain(): param = Parameter('X', 2, lower=0, upper=23) param.unconstrain() assert param.lower == -sympy.oo assert param.upper == sympy.oo fixed_param = Parameter('Y', 0, fix=True) fixed_param.unconstrain() assert fixed_param.lower == -sympy.oo assert fixed_param.upper == sympy.oo