def test_error_model(pheno_path): model_prop = Model(pheno_path) assert model_prop.error_model == 'PROP' model_add_str = re.sub( r'Y=F\+W\*EPS\(1\)', 'Y=F+EPS(1)', str(model_prop), ) model_add = Model(StringIO(model_add_str)) assert model_add.error_model == 'ADD' model_add_prop_str = re.sub( r'Y=F\+W\*EPS\(1\)', 'Y=EPS(1)*F+EPS(2)+F', str(model_prop), ) model_add_prop = Model(StringIO(model_add_prop_str)) assert model_add_prop.error_model == 'ADD_PROP' model_none_str = re.sub( r'Y=F\+W\*EPS\(1\)', 'Y=F', str(model_prop), ) model_none = Model(StringIO(model_none_str)) assert model_none.error_model == 'NONE'
def test_copy(datadir): path = datadir / 'minimal.mod' model = Model(path) copy = model.copy() assert id(model) != id(copy) assert model.statements[0].expression == \ Symbol('THETA(1)', real=True) + Symbol('ETA(1)', real=True) + Symbol('ERR(1)', real=True)
def test_combined_error_model(testdata): model = Model(testdata / 'nonmem' / 'pheno.mod') combined_error(model) model.update_source() assert str(model).split('\n')[11] == 'Y = EPS(1)*F + EPS(2) + F' assert str(model).split('\n')[17] == '$SIGMA 0.09 ; sigma_prop' assert str(model).split('\n')[18] == '$SIGMA 11.2225 ; sigma_add'
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 test_eq_modelstatements(testdata): model_min = Model(testdata / 'nonmem' / 'minimal.mod') model_pheno = Model(testdata / 'nonmem' / 'pheno_real.mod') assert model_min.statements == model_min.statements assert model_pheno.statements == model_pheno.statements assert model_min.statements != model_pheno.statements
def test_michaelis_menten_elimination(testdata): model = Model(testdata / 'nonmem' / 'pheno.mod') michaelis_menten_elimination(model) model.update_source() correct = """$PROBLEM PHENOBARB SIMPLE MODEL $DATA pheno.dta IGNORE=@ $INPUT ID TIME AMT WGT APGR DV $SUBROUTINE ADVAN6 TOL=3 $MODEL COMPARTMENT=(CENTRAL DEFDOSE) $PK CLMM = THETA(3) KM = THETA(2) V = THETA(1)*EXP(ETA(1)) S1=V $DES DADT(1) = -A(1)*CLMM*KM/(V*(A(1)/V + KM)) $ERROR Y=F+F*EPS(1) $THETA (0,1.00916) ; TVV $THETA (0,135.8) ; POP_KM $THETA (0,0.00469307) ; POP_CLMM $OMEGA 0.031128 ; IVV $SIGMA 0.013241 $ESTIMATION METHOD=1 INTERACTION """ assert str(model) == correct
def test_iiv_on_ruv(pheno_path, epsilons, same_eta, err_ref, omega_ref): model = Model(pheno_path) model_str = str(model) model_more_eps = re.sub('IPRED=F\nIRES=DV-IPRED', 'IPRED=F+EPS(2)\nIRES=DV-IPRED+EPS(3)', model_str) model_sigma = re.sub(r'\$SIGMA 0.013241', '$SIGMA 0.013241\n$SIGMA 0.1\n$SIGMA 0.1', model_more_eps) model.control_stream = NMTranParser().parse(model_sigma) iiv_on_ruv(model, epsilons, same_eta) model.update_source() err_rec = model.control_stream.get_records('ERROR')[0] assert str( err_rec) == f'$ERROR\n' f'W=F\n' f'{err_ref}' f'IWRES=IRES/W\n\n' omega_rec = ''.join( str(rec) for rec in model.control_stream.get_records('OMEGA')) assert omega_rec == (f'$OMEGA DIAGONAL(2)\n' f' 0.0309626 ; IVCL\n' f' 0.031128 ; IVV\n\n' f'{omega_ref}\n')
def test_add_parameters(pheno_path, param_new, init_expected, buf_new): model = Model(pheno_path) pset = model.parameters assert len(pset) == 6 pset.append(param_new) model.parameters = pset model.update_source() assert len(pset) == 7 assert model.parameters[param_new.name].init == init_expected parser = NMTranParser() stream = parser.parse(str(model)) assert str(model.control_stream) == str(stream) rec_ref = ( f'$THETA (0,0.00469307) ; PTVCL\n' f'$THETA (0,1.00916) ; PTVV\n' f'$THETA (-.99,.1)\n' f'{buf_new}\n' ) rec_mod = '' for rec in model.control_stream.get_records('THETA'): rec_mod += str(rec) assert rec_ref == rec_mod
def test_parameter_estimates(pheno_path): with ConfigurationContext(nonmem.conf, parameter_names=['basic']): res = Model(pheno_path).modelfit_results pe = res.parameter_estimates assert len(pe) == 6 assert pe['THETA(1)'] == 4.69555e-3 assert pe['OMEGA(2,2)'] == 2.7906e-2 pe_sd = res.parameter_estimates_sdcorr correct = pd.Series( { 'THETA(1)': 0.00469555, 'THETA(2)': 0.984258, 'THETA(3)': 0.158920, 'OMEGA(1,1)': 0.171321, 'OMEGA(2,2)': 0.167051, 'SIGMA(1,1)': 0.115069, } ) correct.name = 'estimates' pd.testing.assert_series_equal(pe_sd, correct) with ConfigurationContext(nonmem.conf, parameter_names=['comment', 'basic']): res = Model(pheno_path).modelfit_results pe = res.parameter_estimates assert len(pe) == 6 assert pe['PTVCL'] == 4.69555e-3 assert pe['IVV'] == 2.7906e-2
def test_proportional_error_model_log(testdata): model = Model(testdata / 'nonmem' / 'pheno.mod') model.statements[5] = Assignment('Y', 'F') proportional_error(model, data_trans='log(Y)') model.update_source() assert str(model).split('\n')[11] == 'Y = LOG(F) + EPS(1)' assert str(model).split('\n')[17] == '$SIGMA 0.09 ; sigma'
def test_remove_eta(pheno_path): model = Model(pheno_path) rvs = model.random_variables eta1 = rvs['ETA(1)'] del rvs[eta1] model.update_source() assert str(model).split('\n')[12] == 'V = TVV*EXP(ETA(1))'
def psn_frem_results(path, force_posdef_covmatrix=False, force_posdef_samples=500, method=None): """ Create frem results from a PsN FREM run :param path: Path to PsN frem run directory :return: A :class:`FREMResults` object """ path = Path(path) model_4_path = path / 'final_models' / 'model_4.mod' if not model_4_path.is_file(): raise IOError(f'Could not find FREM model 4: {str(model_4_path)}') model_4 = Model(model_4_path) if model_4.modelfit_results is None: raise ValueError('Model 4 has no results') cov_model = None if method == 'cov_sampling': try: model_4.modelfit_results.covariance_matrix except Exception: model_4b_path = path / 'final_models' / 'model_4b.mod' try: model_4b = Model(model_4b_path) except FileNotFoundError: pass else: cov_model = model_4b with open(path / 'covariates_summary.csv') as covsum: covsum.readline() raw_cov_list = covsum.readline() all_covariates = raw_cov_list[1:].rstrip().split(',') nunique = model_4.dataset.pharmpy.baselines[all_covariates].nunique() continuous = list(nunique.index[nunique != 2]) categorical = list(nunique.index[nunique == 2]) # FIXME: Not introducing yaml parser in pharmpy just yet. Options should be collected # differently. Perhaps using json with open(path / 'meta.yaml') as meta: for row in meta: row = row.strip() if row.startswith('rescale: 1'): rescale = True elif row.startswith('rescale: 0'): rescale = False res = calculate_results(model_4, continuous, categorical, method=method, force_posdef_covmatrix=force_posdef_covmatrix, force_posdef_samples=force_posdef_samples, cov_model=cov_model, rescale=rescale) return res
def test_update_inits(pheno_path): model = Model(pheno_path) model.update_inits() with ConfigurationContext(conf, parameter_names=['comment', 'basic']): model = Model(pheno_path) model.update_inits() model.update_source()
def test_create_model3b(testdata): model3 = Model(testdata / 'nonmem' / 'frem' / 'pheno' / 'model_3.mod') model1b = Model(testdata / 'nonmem' / 'pheno_real.mod') model3b = create_model3b(model1b, model3, 2) pset = model3b.parameters assert pset['OMEGA(3,1)'].init == approx(0.02560327) assert pset['THETA(1)'].init == 0.00469555 assert model3b.name == 'model_3b'
def test_bootstrap(tmp_path, testdata): with TemporaryDirectoryChanger(tmp_path): shutil.copy2(testdata / 'nonmem' / 'pheno.mod', tmp_path) shutil.copy2(testdata / 'nonmem' / 'pheno.dta', tmp_path) model = Model('pheno.mod') model.dataset_path = tmp_path / 'pheno.dta' res = Bootstrap(model, 3).run() assert len(res.parameter_estimates) == 3
def test_copy(datadir): path = datadir / 'minimal.mod' model = Model(path) copy = model.copy() assert id(model) != id(copy) assert model.statements[0].expression == symbol('THETA(1)') + symbol('ETA(1)') + symbol( 'EPS(1)' )
def test_additive_error_model(testdata): model = Model(testdata / 'nonmem' / 'pheno.mod') additive_error(model) model.update_source() assert str(model).split('\n')[11] == 'Y = F + EPS(1)' assert str(model).split('\n')[17] == '$SIGMA 11.2225 ; sigma' before = str(model) additive_error(model) # One more time and nothing should change assert before == str(model)
def test_find_depot(testdata): model = Model(testdata / 'nonmem' / 'modeling' / 'pheno_advan2.mod') assert model.statements.ode_system.find_depot(model.statements).name == 'DEPOT' model = Model(testdata / 'nonmem' / 'modeling' / 'pheno_advan1.mod') assert model.statements.ode_system.find_depot(model.statements) is None model = Model(testdata / 'nonmem' / 'modeling' / 'pheno_advan5_depot.mod') assert model.statements.ode_system.find_depot(model.statements).name == 'DEPOT' model = Model(testdata / 'nonmem' / 'modeling' / 'pheno_advan5_nodepot.mod') assert model.statements.ode_system.find_depot(model.statements) is None
def test_des(testdata, model_path, transformation): model_ref = Model(testdata / model_path) transformation(model_ref) model_ref.update_source() model_des = Model(StringIO(str(model_ref))) model_des.source.path = model_ref.source.path # To be able to find dataset assert model_ref.statements.ode_system == model_des.statements.ode_system
def test_fix_parameters(testdata): model = Model(testdata / 'nonmem' / 'minimal.mod') assert not model.parameters['THETA(1)'].fix fix_parameters(model, ['THETA(1)']) assert model.parameters['THETA(1)'].fix model = Model(testdata / 'nonmem' / 'minimal.mod') assert not model.parameters['THETA(1)'].fix fix_parameters(model, 'THETA(1)') assert model.parameters['THETA(1)'].fix
def test_fit_single(tmp_path, testdata): with TemporaryDirectoryChanger(tmp_path): shutil.copy2(testdata / 'nonmem' / 'pheno.mod', tmp_path) shutil.copy2(testdata / 'nonmem' / 'pheno.dta', tmp_path) model = Model('pheno.mod') model.dataset_path = tmp_path / 'pheno.dta' modeling.fit(model) rundir = tmp_path / 'modelfit_dir1' assert model.modelfit_results.ofv == pytest.approx(730.8947268137308) assert rundir.is_dir()
def test_combined_error_model_log(testdata): model = Model(testdata / 'nonmem' / 'pheno.mod') combined_error(model, data_trans='log(Y)') model.update_source() assert str(model).split('\n')[11] == 'Y = LOG(F) + EPS(2)/F + EPS(1)' assert str(model).split('\n')[17] == '$SIGMA 0.09 ; sigma_prop' assert str(model).split('\n')[18] == '$SIGMA 11.2225 ; sigma_add' before = str(model) combined_error(model) # One more time and nothing should change assert before == str(model)
def test_simeval(testdata): orig = Model(testdata / 'nonmem' / 'pheno.mod') base = Model(testdata / 'nonmem' / 'qa' / 'pheno_linbase.mod') simeval_res = read_results(testdata / 'nonmem' / 'qa' / 'simeval_results.json') cdd_res = read_results(testdata / 'nonmem' / 'qa' / 'cdd_results.json') calculate_results(orig, base, simeval_results=simeval_res, cdd_results=cdd_res)
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 test_special_models(testdata): onePROB = testdata / 'nonmem' / 'modelfit_results' / 'onePROB' withBayes = Model(onePROB / 'multEST' / 'noSIM' / 'withBayes.mod') assert (pytest.approx( withBayes.modelfit_results.standard_errors['THETA(1)'], 1e-13) == 2.51942e00) assert (pytest.approx( withBayes.modelfit_results[0].standard_errors['THETA(1)'], 1e-13) == 3.76048e-01) assert withBayes.modelfit_results[0].minimization_successful is False assert withBayes.modelfit_results[1].minimization_successful is False assert withBayes.modelfit_results[0].covariance_step == { 'requested': True, 'completed': True, 'warnings': False, } assert withBayes.modelfit_results.covariance_step == { 'requested': True, 'completed': True, 'warnings': False, } maxeval0 = Model(onePROB / 'oneEST' / 'noSIM' / 'maxeval0.mod') assert maxeval0.modelfit_results.minimization_successful is None maxeval3 = Model(onePROB / 'oneEST' / 'noSIM' / 'maxeval3.mod') assert maxeval3.modelfit_results.minimization_successful is False assert maxeval3.modelfit_results.covariance_step == { 'requested': True, 'completed': True, 'warnings': True, } nearbound = Model(onePROB / 'oneEST' / 'noSIM' / 'near_bounds.mod') correct = pd.Series( [ False, True, False, False, False, False, False, False, True, True, False ], index=[ 'THETA(1)', 'THETA(2)', 'THETA(3)', 'THETA(4)', 'OMEGA(1,1)', 'OMEGA(2,1)', 'OMEGA(2,2)', 'OMEGA(3,3)', 'OMEGA(4,4)', 'OMEGA(6,6)', 'SIGMA(1,1)', ], ) pd.testing.assert_series_equal(nearbound.modelfit_results.near_bounds(), correct)
def test_individual_parameter_statistics(testdata): model = Model(testdata / 'nonmem' / 'secondary_parameters' / 'pheno.mod') np.random.seed(103) stats = individual_parameter_statistics(model, 'CL/V') assert stats['mean'] == pytest.approx(0.00470525776968202) assert stats['variance'] == pytest.approx(8.12398122254498e-6) assert stats['stderr'] == pytest.approx(0.00344872, abs=1e-5) model = Model(testdata / 'nonmem' / 'secondary_parameters' / 'run1.mod') np.random.seed(5678)
def test_ofv(testdata): base = Model(testdata / 'nonmem' / 'pheno.mod') lin = Model(testdata / 'nonmem' / 'qa' / 'pheno_linbase.mod') res = calculate_results(base, lin) correct = """,ofv base,730.894727 lin_evaluated,730.894727 lin_estimated,730.847272 """ correct = pd.read_csv(StringIO(correct), index_col=[0]) pd.testing.assert_frame_equal(res.ofv, correct, atol=1e-6)
def update_model3b_for_psn(rundir, ncovs): """Function to update model3b from psn NOTE: This function lets pharmpy tie in to the PsN workflow and is a temporary solution """ model_path = Path(rundir) / 'm1' model1b = Model(model_path / 'model_1b.mod') model3 = Model(model_path / 'model_3.mod') model3b = create_model3b(model1b, model3, int(ncovs)) model3b.write(model_path, force=True)
def test_transit_compartments_added_mdt(testdata): model = Model(testdata / 'nonmem' / 'modeling' / 'pheno_advan5_nodepot.mod') set_transit_compartments(model, 2) transits = model.statements.ode_system.find_transit_compartments( model.statements) assert len(transits) == 2 model.update_source() correct = ("""$PROBLEM PHENOBARB SIMPLE MODEL $DATA ../pheno.dta IGNORE=@ $INPUT ID TIME AMT WGT APGR DV FA1 FA2 $SUBROUTINE ADVAN5 TRANS1 $MODEL COMPARTMENT=(TRANSIT1 DEFDOSE) COMPARTMENT=(TRANSIT2) COMPARTMENT=(CENTRAL) """ + """COMPARTMENT=(PERIPHERAL) $PK MDT = THETA(6) IF(AMT.GT.0) BTIME=TIME TAD=TIME-BTIME TVCL=THETA(1)*WGT TVV=THETA(2)*WGT IF(APGR.LT.5) TVV=TVV*(1+THETA(3)) CL=TVCL*EXP(ETA(1)) V=TVV*EXP(ETA(2)) K30 = CL/V K34 = THETA(4) K43 = THETA(5) S3 = V K12 = 2/MDT K23 = 2/MDT $ERROR W=F Y=F+W*EPS(1) IPRED=F IRES=DV-IPRED IWRES=IRES/W $THETA (0,0.00469307) ; CL $THETA (0,1.00916) ; V $THETA (-.99,.1) $THETA (0,10) $THETA (0,10) $THETA (0,0.5) ; POP_MDT $OMEGA DIAGONAL(2) 0.0309626 ; IVCL 0.031128 ; IVV $SIGMA 1e-7 $ESTIMATION METHOD=1 INTERACTION $COVARIANCE UNCONDITIONAL $TABLE ID TIME DV AMT WGT APGR IPRED PRED RES TAD CWRES NPDE NOAPPEND NOPRINT ONEHEADER FILE=sdtab1 """) assert str(model) == correct
def test_initial_individual_estimates(datadir): path = datadir / 'minimal.mod' model = Model(path) assert model.initial_individual_estimates is None path = datadir / 'pheno_etas.mod' model = Model(path) inits = model.initial_individual_estimates assert len(inits) == 59 assert len(inits.columns) == 2 assert inits['ETA(1)'][2] == -0.166321