def test_get_etas(pheno_path, testdata): model = Model(pheno_path) etas = _get_etas(model, ['ETA(1)']) assert len(etas) == 1 etas = _get_etas(model, ['ETA(1)', 'CL'], include_symbols=True) assert len(etas) == 1 etas = _get_etas(model, ['ETA(1)', 'V'], include_symbols=True) assert len(etas) == 2 with pytest.raises(KeyError): _get_etas(model, ['ETA(23)']) model = Model(testdata / 'nonmem' / 'pheno_block.mod') rvs = _get_etas(model, None) assert rvs[0].name == 'ETA(1)' model.parameters.fix = {'OMEGA(1,1)': True} rvs = _get_etas(model, None) assert rvs[0].name == 'ETA(2)' model = Model(testdata / 'nonmem' / 'pheno_block.mod') model.random_variables['ETA(1)'].level = 'IOV' rvs = _get_etas(model, None) assert rvs[0].name == 'ETA(2)'
def split_rv_block(model, list_of_rvs=None): """ Splits a block structure given a list of etas to separate. Parameters ---------- model : Model Pharmpy model to create block effect on. list_of_rvs : str, list Name/names of etas to split from block structure. If None, all etas that are IIVs and non-fixed will become single. None is default. """ rvs = model.random_variables list_of_rvs = _get_etas(model, list_of_rvs) parameters_before = rvs.parameter_names rvs.unjoin(list_of_rvs) parameters_after = rvs.parameter_names removed_parameters = set(parameters_before) - set(parameters_after) pset = model.parameters for param in removed_parameters: del pset[param] return model
def tdist(model, list_of_etas=None): """ Applies a t-distribution transformation to specified etas from a :class:`pharmpy.model`. Initial estimate for degrees of freedom is 80 with bounds (3, 100). Parameters ---------- model : Model Pharmpy model to apply t distribution transformation to. list_of_etas : str, list Name/names of etas to transform. If None, all etas will be transformed (default). """ list_of_etas = _format_input_list(list_of_etas) etas = _get_etas(model, list_of_etas) eta_transformation = EtaTransformation.tdist(len(etas)) _transform_etas(model, eta_transformation, etas) return model
def boxcox(model, list_of_etas=None): """ Applies a boxcox transformation to specified etas from a :class:`pharmpy.model`. Initial estimate for lambda is 0.1 with bounds (-3, 3). Parameters ---------- model : Model Pharmpy model to apply boxcox transformation to. list_of_etas : str, list Name/names of etas to transform. If None, all etas will be transformed (default). """ list_of_etas = _format_input_list(list_of_etas) etas = _get_etas(model, list_of_etas) eta_transformation = EtaTransformation.boxcox(len(etas)) _transform_etas(model, eta_transformation, etas) return model
def john_draper(model, list_of_etas=None): """ Applies a John Draper transformation [1]_ to specified etas from a :class:`pharmpy.model`. Initial estimate for lambda is 0.1 with bounds (-3, 3). .. [1] John, J., Draper, N. (1980). An Alternative Family of Transformations. Journal of the Royal Statistical Society. Series C (Applied Statistics), 29(2), 190-197. doi:10.2307/2986305 Parameters ---------- model : Model Pharmpy model to apply John Draper transformation to. list_of_etas : str, list Name/names of etas to transform. If None, all etas will be transformed (default). """ list_of_etas = _format_input_list(list_of_etas) etas = _get_etas(model, list_of_etas) eta_transformation = EtaTransformation.john_draper(len(etas)) _transform_etas(model, eta_transformation, etas) return model
def add_iov(model, occ, list_of_parameters=None, eta_names=None): """ Adds IOVs to :class:`pharmpy.model`. Initial estimate of new IOVs are 10% of the IIV eta it is based on. Parameters ---------- model : Model Pharmpy model to add new IOVs to. occ : str Name of occasion column. list_of_parameters : str, list List of names of parameters and random variables. Accepts random variable names, parameter names, or a mix of both. eta_names: str, list Custom names of new etas. Must be equal to the number of input etas times the number of categories for occasion. """ rvs, pset, sset = model.random_variables, model.parameters, model.statements list_of_parameters = _format_input_list(list_of_parameters) etas = _get_etas(model, list_of_parameters, include_symbols=True) categories = _get_occ_levels(model.dataset, occ) if eta_names and len(eta_names) != len(etas) * len(categories): raise ValueError( f'Number of provided names incorrect, need {len(etas) * len(categories)} names.' ) elif len(categories) == 1: raise ValueError(f'Only one value in {occ} column.') iovs, etais = ModelStatements(), ModelStatements() for i, eta in enumerate(etas, 1): omega_name = str( next(iter(eta.sympy_rv.pspace.distribution.free_symbols))) omega = S(f'OMEGA_IOV_{i}') # TODO: better name pset.append(Parameter(str(omega), init=pset[omega_name].init * 0.1)) iov = S(f'IOV_{i}') values, conditions = [], [] for j, cat in enumerate(categories, 1): if eta_names: eta_name = eta_names[j - 1] else: eta_name = f'ETA_IOV_{i}{j}' eta_new = RandomVariable.normal(eta_name, 'iov', 0, omega) rvs.append(eta_new) values += [S(eta_new.name)] conditions += [Eq(cat, S(occ))] expression = Piecewise(*zip(values, conditions)) iovs.append(Assignment(iov, sympy.sympify(0))) iovs.append(Assignment(iov, expression)) etais.append(Assignment(S(f'ETAI{i}'), eta.symbol + iov)) sset.subs({eta.name: S(f'ETAI{i}')}) iovs.extend(etais) iovs.extend(sset) model.random_variables, model.parameters, model.statements = rvs, pset, iovs return model