def check_derivatives(problem: petab.Problem, model: amici.Model) -> None: """Check derivatives using finite differences for all experimental conditions Arguments: problem: PEtab problem model: AMICI model matching ``problem`` """ problem_parameters = { t.Index: getattr(t, petab.NOMINAL_VALUE) for t in problem.parameter_df.itertuples() } solver = model.getSolver() solver.setSensitivityMethod(amici.SensitivityMethod_forward) solver.setSensitivityOrder(amici.SensitivityOrder_first) # Required for case 9 to not fail in # amici::NewtonSolver::computeNewtonSensis model.setSteadyStateSensitivityMode( SteadyStateSensitivityMode_simulationFSA) def assert_true(x): assert x for edata in create_parameterized_edatas( amici_model=model, petab_problem=problem, problem_parameters=problem_parameters): # check_derivatives does currently not support parameters in ExpData model.setParameters(edata.parameters) model.setParameterScale(edata.pscale) edata.parameters = [] edata.pscale = amici.parameterScalingFromIntVector([]) amici_check_derivatives(model, solver, edata, assert_true)
def setUp(self): self.resetdir = os.getcwd() self.default_path = copy.copy(sys.path) pysb.SelfExporter.cleanup() # reset pysb pysb.SelfExporter.do_export = True sys.path.insert( 0, os.path.join(os.path.dirname(__file__), '..', 'python', 'examples', 'example_presimulation')) if 'createModelPresimulation' in sys.modules: importlib.reload(sys.modules['createModelPresimulation']) model_module = sys.modules['createModelPresimulation'] else: model_module = importlib.import_module('createModelPresimulation') model = copy.deepcopy(model_module.model) model.name = 'test_model_presimulation_pysb' amici.pysb2amici(model, model.name, verbose=False, observables=['pPROT_obs'], constant_parameters=['DRUG_0', 'KIN_0']) sys.path.insert(0, model.name) import test_model_presimulation_pysb as modelModulePYSB self.model = modelModulePYSB.getModel() self.solver = self.model.getSolver() self.solver.setSensitivityOrder(amici.SensitivityOrder_first) self.solver.setSensitivityMethod(amici.SensitivityMethod_forward) self.edata = get_data(self.model) self.edata.fixedParametersPresimulation = () self.edata_preeq = amici.ExpData(self.edata) self.edata_preeq.setTimepoints([0]) self.edata_sim = amici.ExpData(self.edata) self.edata_sim.fixedParametersPreequilibration = () self.pscales = [ amici.ParameterScaling_log10, amici.ParameterScaling_ln, amici.ParameterScaling_none, amici.parameterScalingFromIntVector([ amici.ParameterScaling_log10, amici.ParameterScaling_ln, amici.ParameterScaling_none, amici.ParameterScaling_log10, amici.ParameterScaling_ln, amici.ParameterScaling_none ]) ] self.plists = [ [3, 1, 2, 4], [0, 1, 2, 3, 4, 5], [5, 3, 2, 0, 4, 1], [1, 2, 3, 4, 5], [1, 1, 1], ]
def test_parameterScalingFromIntVector(self): """Ensure we can generate a ParameterScaling vector from Python""" scale_vector = amici.parameterScalingFromIntVector([ amici.ParameterScaling_log10, amici.ParameterScaling_ln, amici.ParameterScaling_none ]) assert scale_vector[0] == amici.ParameterScaling_log10 assert scale_vector[1] == amici.ParameterScaling_ln assert scale_vector[2] == amici.ParameterScaling_none
def preeq_fixture(pysb_example_presimulation_module): model = pysb_example_presimulation_module.getModel() model.setReinitializeFixedParameterInitialStates(True) solver = model.getSolver() solver.setSensitivityOrder(amici.SensitivityOrder.first) solver.setSensitivityMethod(amici.SensitivityMethod.forward) edata = get_data(model) edata.t_presim = 2 edata.fixedParameters = [10, 2] edata.fixedParametersPresimulation = [3, 2] edata.fixedParametersPreequilibration = [3, 0] edata.setTimepoints([1, 5]) edata_preeq = amici.ExpData(edata) edata_preeq.t_presim = 0 edata_preeq.setTimepoints([np.infty]) edata_preeq.fixedParameters = \ edata.fixedParametersPreequilibration edata_preeq.fixedParametersPresimulation = () edata_preeq.fixedParametersPreequilibration = () edata_presim = amici.ExpData(edata) edata_presim.t_presim = 0 edata_presim.setTimepoints([edata.t_presim]) edata_presim.fixedParameters = \ edata.fixedParametersPresimulation edata_presim.fixedParametersPresimulation = () edata_presim.fixedParametersPreequilibration = () edata_sim = amici.ExpData(edata) edata_sim.t_presim = 0 edata_sim.setTimepoints(edata.getTimepoints()) edata_sim.fixedParameters = \ edata.fixedParameters edata_sim.fixedParametersPresimulation = () edata_sim.fixedParametersPreequilibration = () pscales = [ amici.ParameterScaling.log10, amici.ParameterScaling.ln, amici.ParameterScaling.none, amici.parameterScalingFromIntVector([ amici.ParameterScaling.log10, amici.ParameterScaling.ln, amici.ParameterScaling.none, amici.ParameterScaling.log10, amici.ParameterScaling.ln, amici.ParameterScaling.none ]) ] plists = [ [3, 1, 2, 4], [0, 1, 2, 3, 4, 5], [5, 3, 2, 0, 4, 1], [1, 2, 3, 4, 5], [1, 1, 1], ] return (model, solver, edata, edata_preeq, edata_presim, edata_sim, pscales, plists)
def test_parameter_in_expdata(preeq_fixture): """Test parameter in ExpData""" model, solver, edata, edata_preeq, edata_presim, \ edata_sim, pscales, plists = preeq_fixture rdata = amici.runAmiciSimulation(model, solver, edata) # get initial states will compute initial states if nothing is set, # this needs go first as we need unmodified model. Also set to # preequilibration fixpars first as this is where initial states would be # computed otherwise model.setFixedParameters(edata.fixedParametersPreequilibration) edata.x0 = model.getInitialStates() edata.sx0 = model.getInitialStateSensitivities() # perturb model initial states model.setInitialStates(rdata['x_ss'] * 4) model.setInitialStateSensitivities(rdata['sx_ss'].flatten() / 2) # set ExpData plist edata.plist = model.getParameterList() # perturb model parameter list model.setParameterList([ i for i in reversed(model.getParameterList()) ]) # set ExpData parameters edata.parameters = model.getParameters() # perturb model parameters model.setParameters(tuple( p * 2 for p in model.getParameters() )) # set ExpData pscale edata.pscale = model.getParameterScale() # perturb model pscale, needs to be done after getting parameters, # otherwise we will mess up parameter value model.setParameterScale(amici.parameterScalingFromIntVector([ amici.ParameterScaling.log10 if scaling == amici.ParameterScaling.none else amici.ParameterScaling.none for scaling in model.getParameterScale() ])) rdata_edata = amici.runAmiciSimulation( model, solver, edata ) for variable in ['x', 'sx']: assert np.isclose( rdata[variable][0, :], rdata_edata[variable][0, :], 1e-6, 1e-6 ).all(), variable
def test_parameter_in_expdata(preeq_fixture): """Test parameter in ExpData""" model, solver, edata, edata_preeq, edata_presim, \ edata_sim, pscales, plists = preeq_fixture rdata = amici.runAmiciSimulation(model, solver, edata) # set ExpData plist edata.plist = model.getParameterList() # perturb model parameter list model.setParameterList([ i for i in reversed(model.getParameterList()) ]) # set ExpData parameters edata.parameters = model.getParameters() # perturb model parameters model.setParameters(tuple( p * 2 for p in model.getParameters() )) # set ExpData pscale edata.pscale = model.getParameterScale() # perturb model pscale, needs to be done after getting parameters, # otherwise we will mess up parameter value model.setParameterScale(amici.parameterScalingFromIntVector([ amici.ParameterScaling_log10 if scaling == amici.ParameterScaling_none else amici.ParameterScaling_none for scaling in model.getParameterScale() ])) edata.x0 = rdata['x_ss'] edata.sx0 = rdata['sx_ss'].flatten() # perturb model initial states model.setInitialStates(rdata['x_ss'] * 4) model.setInitialStateSensitivities(rdata['sx_ss'].flatten() / 2) rdata_edata = amici.runAmiciSimulation( model, solver, edata ) for variable in ['x', 'sx']: assert np.isclose( rdata[variable][0, :], rdata_edata[variable][0, :], 1e-6, 1e-6 ).all(), variable
def test_sympy_exp_monkeypatch(): """ This model contains a removeable discontinuity at t=0 that requires monkeypatching sympy.Pow._eval_derivative in order to be able to compute non-nan sensitivities """ url = 'https://www.ebi.ac.uk/biomodels/model/download/BIOMD0000000529.2?' \ 'filename=BIOMD0000000529_url.xml' importer = amici.SbmlImporter(urlopen(url).read().decode('utf-8'), from_file=False) module_name = 'BIOMD0000000529' outdir = 'BIOMD0000000529' importer.sbml2amici(module_name, outdir) model_module = amici.import_model_module(module_name=module_name, module_path=outdir) model = model_module.getModel() model.setTimepoints(np.linspace(0, 8, 250)) model.requireSensitivitiesForAllParameters() model.setAlwaysCheckFinite(True) model.setParameterScale( amici.parameterScalingFromIntVector([ amici.ParameterScaling.none if re.match(r'n[0-9]+$', par_id) else amici.ParameterScaling.log10 for par_id in model.getParameterIds() ])) solver = model.getSolver() solver.setSensitivityMethod(amici.SensitivityMethod.forward) solver.setSensitivityOrder(amici.SensitivityOrder.first) rdata = amici.runAmiciSimulation(model, solver) # print sensitivity-related results assert rdata['status'] == amici.AMICI_SUCCESS check_derivatives(model, solver, None, assert_fun, atol=1e-2, rtol=1e-2, epsilon=1e-3)
def test_parameter_in_expdata(self): rdata = amici.runAmiciSimulation(self.model, self.solver, self.edata) # set ExpData plist self.edata.plist = self.model.getParameterList() # perturb model parameter list self.model.setParameterList( [i for i in reversed(self.model.getParameterList())]) # set ExpData parameters self.edata.parameters = self.model.getParameters() # perturb model parameters self.model.setParameters( tuple(p * 2 for p in self.model.getParameters())) # set ExpData pscale self.edata.pscale = self.model.getParameterScale() # perturb model pscale, needs to be done after getting parameters, # otherwise we will mess up parameter value self.model.setParameterScale( amici.parameterScalingFromIntVector([ amici.ParameterScaling_log10 if scaling == amici.ParameterScaling_none else amici.ParameterScaling_none for scaling in self.model.getParameterScale() ])) self.edata.x0 = rdata['x_ss'] self.edata.sx0 = rdata['sx_ss'].flatten() # perturb model initial states self.model.setInitialStates(rdata['x_ss'] * 4) self.model.setInitialStateSensitivities(rdata['sx_ss'].flatten() / 2) rdata_edata = amici.runAmiciSimulation(self.model, self.solver, self.edata) for variable in ['x', 'sx']: with self.subTest(variable=variable): self.assertTrue( np.isclose(rdata[variable][0, :], rdata_edata[variable][0, :], 1e-6, 1e-6).all())
def fill_in_parameters_for_condition( edata: amici.ExpData, problem_parameters: Dict[str, numbers.Number], scaled_parameters: bool, parameter_mapping: ParameterMappingForCondition, amici_model: AmiciModel) -> None: """Fill fixed and dynamic parameters into the edata for condition (in-place). :param edata: Experimental data object to fill parameters into. :param problem_parameters: Problem parameters as parameterId=>value dict. Only parameters included here will be set. Remaining parameters will be used as already set in `amici_model` and `edata`. :param scaled_parameters: If True, problem_parameters are assumed to be on the scale provided in the parameter mapping. If False, they are assumed to be in linear scale. :param parameter_mapping: Parameter mapping for current condition. :param amici_model: AMICI model """ map_sim_var = parameter_mapping.map_sim_var scale_map_sim_var = parameter_mapping.scale_map_sim_var map_preeq_fix = parameter_mapping.map_preeq_fix scale_map_preeq_fix = parameter_mapping.scale_map_preeq_fix map_sim_fix = parameter_mapping.map_sim_fix scale_map_sim_fix = parameter_mapping.scale_map_sim_fix # Parameter mapping may contain parameter_ids as values, these *must* # be replaced def _get_par(model_par, value): """Replace parameter IDs in mapping dicts by values from problem_parameters where necessary""" if isinstance(value, str): # estimated parameter # (condition table overrides must have been handled already, # e.g. by the PEtab parameter mapping) return problem_parameters[value] if model_par in problem_parameters: # user-provided return problem_parameters[model_par] # constant value return value map_preeq_fix = { key: _get_par(key, val) for key, val in map_preeq_fix.items() } map_sim_fix = {key: _get_par(key, val) for key, val in map_sim_fix.items()} map_sim_var = {key: _get_par(key, val) for key, val in map_sim_var.items()} # If necessary, (un)scale parameters if scaled_parameters: unscale_parameters_dict(map_preeq_fix, scale_map_preeq_fix) unscale_parameters_dict(map_sim_fix, scale_map_sim_fix) if not scaled_parameters: # We scale all parameters to the scale they are estimated on, and pass # that information to amici via edata.{parameters,pscale}. # The scaling is necessary to obtain correct derivatives. scale_parameters_dict(map_sim_var, scale_map_sim_var) # We can skip preequilibration parameters, because they are identical # with simulation parameters, and only the latter are used from here # on. ########################################################################## # variable parameters and parameter scale # parameter list from mapping dict parameters = [ map_sim_var[par_id] for par_id in amici_model.getParameterIds() ] # scales list from mapping dict scales = [ petab_to_amici_scale(scale_map_sim_var[par_id]) for par_id in amici_model.getParameterIds() ] if parameters: edata.parameters = parameters if scales: edata.pscale = amici.parameterScalingFromIntVector(scales) ########################################################################## # fixed parameters preequilibration if map_preeq_fix: fixed_pars_preeq = [ map_preeq_fix[par_id] for par_id in amici_model.getFixedParameterIds() ] edata.fixedParametersPreequilibration = fixed_pars_preeq ########################################################################## # fixed parameters simulation if map_sim_fix: fixed_pars_sim = [ map_sim_fix[par_id] for par_id in amici_model.getFixedParameterIds() ] edata.fixedParameters = fixed_pars_sim
def generate_synthetic_data(pathway_name: str, latent_dimension: int = 2, n_samples: int = 20) -> str: """ Generates sample data using the mechanistic model. :param pathway_name: name of pathway to use for model :param latent_dimension: number of latent dimensions that is used to generate the parameters that vary across samples :param n_samples: number of samples to generate :return: path to csv where generated data was saved """ model, solver = load_model('pw_' + pathway_name, force_compile=True) # setup model parameter scales model.setParameterScale( amici.parameterScalingFromIntVector([ amici.ParameterScaling.none if par_id.startswith(MODEL_FEATURE_PREFIX) or parameter_boundaries_scales[par_id.split('_')[-1]][2] == 'lin' else amici.ParameterScaling.log10 for par_id in model.getParameterIds() ])) # run simulations to equilibrium model.setTimepoints([np.inf]) # set numpy random seed to ensure reproducibility np.random.seed(0) # generate static parameters that are consistent across samples static_pars = dict() for par_id in model.getParameterIds(): if par_id.startswith(MODEL_FEATURE_PREFIX): continue lb, ub, _ = parameter_boundaries_scales[par_id.split('_')[-1]] static_pars[par_id] = np.random.random() * (ub - lb) + lb # identify which parameters may vary across samples sample_pars = [ par_id for par_id in model.getParameterIds() if par_id.startswith(MODEL_FEATURE_PREFIX) ] encoder = AutoEncoder(np.zeros((1, model.ny)), n_hidden=latent_dimension, n_params=len(sample_pars)) tt_pars = np.random.random(encoder.n_encoder_pars) for ip, name in enumerate(encoder.x_names): lb, ub, _ = parameter_boundaries_scales[name.split('_')[-1]] tt_pars[ip] = tt_pars[ip] * (ub - lb) + lb samples = [] embeddings = [] while len(samples) < n_samples: # generate new fake data encoder.data = np.random.random(encoder.data.shape) if len(samples) < n_samples / 2: encoder.data += 1 else: encoder.data -= 1 # generate parameters from fake data embedding = encoder.compute_embedded_pars(tt_pars) sample_par_vals = np.power(10, encoder.compute_inflated_pars(tt_pars)) sample_pars = dict(zip(sample_pars, sample_par_vals[0, :])) # set parameters in model for par_id, val in {**static_pars, **sample_pars}.items(): model.setParameterById(par_id, val) # run simulations, only add to samples if no integration error rdata = amici.runAmiciSimulation(model, solver) if rdata['status'] == amici.AMICI_SUCCESS: sample = amici.getSimulationObservablesAsDataFrame( model, [amici.ExpData(model)], [rdata]) sample['Sample'] = len(samples) for pid, val in sample_pars.items(): sample[pid] = val samples.append(sample) embeddings.append(embedding) # create dataframe df = pd.concat(samples) df[list(model.getObservableIds())].rename( columns={o: o.replace('_obs', '') for o in model.getObservableIds()}).boxplot(rot=90) # format according to reference example formatted_df = pd.melt(df[list(model.getObservableIds()) + ['Sample']], id_vars=['Sample']) formatted_df.rename(columns={ 'variable': 'site', 'value': 'LogFoldChange', }, inplace=True) formatted_df['site'] = formatted_df['site'].apply( lambda x: x.replace('_obs', '')[1:]) formatted_df['Gene'] = formatted_df['site'].apply( lambda x: x.split('_')[0]) formatted_df['Peptide'] = 'X.XXXXX*XXXXX.X' formatted_df['site'] = formatted_df['site'].apply( lambda x: x.replace('_', '-') + (x.split('_')[1][0].lower() if len(x.split('_')) > 1 else '')) # save to csv datadir = os.path.join(basedir, 'data') os.makedirs(datadir, exist_ok=True) datafile = os.path.join(datadir, f'synthetic__{pathway_name}.csv') plot_and_save_fig(os.path.join(datadir, f'synthetic__{pathway_name}.pdf')) fig, ax = plt.subplots(1, 1) plot_embedding(np.vstack(embeddings), ax) plot_and_save_fig( os.path.join(datadir, f'synthetic__{pathway_name}__embedding.pdf')) inputs = df[[ col for col in df.columns if col.startswith(MODEL_FEATURE_PREFIX) ]] fig, ax = plt.subplots(1, 1) plot_pca_inputs(np.log10(inputs.values), ax) plot_and_save_fig( os.path.join(datadir, f'synthetic__{pathway_name}__input_pca.pdf')) inputs = df[[ col for col in df.columns if col.startswith(MODEL_FEATURE_PREFIX) or col == 'Sample' ]] inputs = pd.melt(inputs, id_vars=['Sample']) inputs.index = inputs['variable'] + \ inputs['Sample'].apply(lambda x: f'_sample_{x}') ref = pd.concat([pd.Series(static_pars), inputs.value]) ref.to_csv( os.path.join(datadir, f'synthetic__{pathway_name}__reference_inputs.csv')) fig, axes = plt.subplots(1, 2) plot_pca_inputs(df[list(model.getObservableIds())].values, axes[0], axes[1]) plot_and_save_fig( os.path.join(datadir, f'synthetic__{pathway_name}__data_pca.pdf')) formatted_df.to_csv(datafile) return datafile
def test_compare_to_pysb_simulation(example): pysb = pytest.importorskip("pysb") atol = 1e-8 rtol = 1e-8 with amici.add_path(os.path.dirname(pysb.examples.__file__)): with amici.add_path( os.path.join(os.path.dirname(__file__), '..', 'tests', 'pysb_test_models')): if example == 'earm_1_3' \ and platform.sys.version_info[0] == 3 \ and platform.sys.version_info[1] < 7: return # load example pysb.SelfExporter.cleanup() # reset pysb pysb.SelfExporter.do_export = True module = importlib.import_module(example) pysb_model = module.model pysb_model.name = pysb_model.name.replace('pysb.examples.', '') # avoid naming clash for custom pysb models pysb_model.name += '_amici' # pysb part tspan = np.linspace(0, 100, 101) sim = ScipyOdeSimulator(pysb_model, tspan=tspan, integrator_options={ 'rtol': rtol, 'atol': atol }, compiler='python') pysb_simres = sim.run() # amici part outdir = pysb_model.name if pysb_model.name in ['move_connected_amici']: with pytest.raises(Exception): pysb2amici(pysb_model, outdir, verbose=logging.INFO, compute_conservation_laws=True) compute_conservation_laws = False else: compute_conservation_laws = True pysb2amici(pysb_model, outdir, verbose=logging.INFO, compute_conservation_laws=compute_conservation_laws, observables=list(pysb_model.observables.keys())) amici_model_module = amici.import_model_module( pysb_model.name, outdir) model_pysb = amici_model_module.getModel() model_pysb.setTimepoints(tspan) solver = model_pysb.getSolver() solver.setMaxSteps(int(1e6)) solver.setAbsoluteTolerance(atol) solver.setRelativeTolerance(rtol) rdata = amici.runAmiciSimulation(model_pysb, solver) # check agreement of species simulation assert np.isclose(rdata['x'], pysb_simres.species, 1e-4, 1e-4).all() if example not in [ 'fricker_2010_apoptosis', 'fixed_initial', 'bngwiki_egfr_simple_deletemolecules' ]: if example in [ 'tyson_oscillator', 'bax_pore_sequential', 'bax_pore', 'kinase_cascade', 'bngwiki_egfr_simple', 'bngwiki_enzymatic_cycle_mm', 'bngwiki_simple' ]: solver.setAbsoluteTolerance(1e-14) solver.setRelativeTolerance(1e-14) epsilon = 1e-4 else: solver.setAbsoluteTolerance(1e-10) solver.setRelativeTolerance(1e-10) epsilon = 1e-3 model_pysb.setParameterScale( parameterScalingFromIntVector([ ParameterScaling.log10 if p > 0 else ParameterScaling.none for p in model_pysb.getParameters() ])) check_derivatives(model_pysb, solver, epsilon=epsilon, rtol=1e-2, atol=1e-2, skip_zero_pars=True) shutil.rmtree(outdir, ignore_errors=True)
def generate_synthetic_data(pathway_name: str, latent_dimension: int = 2, n_samples: int = 20) -> Tuple[str, str, str]: """ Generates sample data using the mechanistic model. :param pathway_name: name of pathway to use for model :param latent_dimension: number of latent dimensions that is used to generate the parameters that vary across samples :param n_samples: number of samples to generate :return: path to csv where generated data was saved """ model, solver = load_model('pw_' + pathway_name, force_compile=True, add_observables=True) # setup model parameter scales model.setParameterScale( amici.parameterScalingFromIntVector([ amici.ParameterScaling.none if par_id.startswith(MODEL_FEATURE_PREFIX) or par_id.endswith('_0') or parameter_boundaries_scales[par_id.split('_')[-1]][2] == 'lin' else amici.ParameterScaling.log10 for par_id in model.getParameterIds() ])) # run simulations to equilibrium model.setTimepoints([np.inf]) # set numpy random seed to ensure reproducibility np.random.seed(0) sample_pars = [ par_id for par_id in model.getParameterIds() if par_id.startswith(MODEL_FEATURE_PREFIX) ] # generate static parameters that are consistent across samples static_pars = dict() for par_id in model.getParameterIds(): if par_id in sample_pars: continue if par_id.endswith('_0'): static_pars[par_id] = 0.0 continue lb, ub, _ = parameter_boundaries_scales[par_id.split('_')[-1]] static_pars[par_id] = np.random.random() * (ub - lb) + lb encoder = AutoEncoder(np.zeros((1, model.ny)), n_hidden=latent_dimension, n_params=len(sample_pars)) tt_pars = np.random.random(encoder.n_encoder_pars) for ip, name in enumerate(encoder.x_names): lb, ub, _ = parameter_boundaries_scales[name.split('_')[-1]] tt_pars[ip] = tt_pars[ip] * (ub - lb) + lb samples = [] embeddings = [] while len(samples) < n_samples: # generate new fake data encoder.data = np.random.random(encoder.data.shape) if len(samples) < n_samples / 2: encoder.data += 1 else: encoder.data -= 1 # generate parameters from fake data embedding = encoder.compute_embedded_pars(tt_pars) sample_par_vals = np.power(10, encoder.compute_inflated_pars(tt_pars)) sample_pars = dict(zip(sample_pars, sample_par_vals[0, :])) # set parameters in model for par_id, val in {**static_pars, **sample_pars}.items(): model.setParameterById(par_id, val) # run simulations, only add to samples if no integration error rdata = amici.runAmiciSimulation(model, solver) if rdata['status'] == amici.AMICI_SUCCESS: sample = amici.getSimulationObservablesAsDataFrame( model, [amici.ExpData(model)], [rdata]) sample['Sample'] = len(samples) for pid, val in sample_pars.items(): sample[pid] = val samples.append(sample) embeddings.append(embedding) # prepare petab datadir = os.path.join(basedir, 'data') os.makedirs(datadir, exist_ok=True) df = pd.concat(samples) df[list(model.getObservableIds())].rename( columns={o: o.replace('_obs', '') for o in model.getObservableIds()}).boxplot(rot=90) plot_and_save_fig(os.path.join(datadir, f'synthetic__{pathway_name}.pdf')) fig, ax = plt.subplots(1, 1) plot_embedding(np.vstack(embeddings), ax) plot_and_save_fig( os.path.join(datadir, f'synthetic__{pathway_name}__embedding.pdf')) inputs = df[[ col for col in df.columns if col.startswith(MODEL_FEATURE_PREFIX) ]] fig, ax = plt.subplots(1, 1) plot_pca_inputs(np.log10(inputs.values), ax) plot_and_save_fig( os.path.join(datadir, f'synthetic__{pathway_name}__input_pca.pdf')) inputs = df[[ col for col in df.columns if col.startswith(MODEL_FEATURE_PREFIX) or col == 'Sample' ]] inputs = pd.melt(inputs, id_vars=['Sample']) inputs.index = inputs['variable'] + \ inputs['Sample'].apply(lambda x: f'_sample_{x}') ref = pd.concat([pd.Series(static_pars), inputs.value]) ref.to_csv( os.path.join(datadir, f'synthetic__{pathway_name}__reference_inputs.csv')) fig, axes = plt.subplots(1, 2) plot_pca_inputs(df[list(model.getObservableIds())].values, axes[0], axes[1]) plot_and_save_fig( os.path.join(datadir, f'synthetic__{pathway_name}__data_pca.pdf')) # create petab & save to csv # MEASUREMENTS measurements = df[[ 'Sample', petab.TIME, ] + list(model.getObservableIds())] measurements = pd.melt(measurements, id_vars=[petab.TIME, 'Sample'], value_name=petab.MEASUREMENT, var_name=petab.OBSERVABLE_ID) measurements[petab.TIME] = 0.0 measurements[petab.SIMULATION_CONDITION_ID] = \ measurements['Sample'].apply( lambda x: f'sample_{x}' ) measurements[petab.PREEQUILIBRATION_CONDITION_ID] = \ measurements['Sample'].apply( lambda x: f'sample_{x}' ) measurements.drop(columns=['Sample'], inplace=True) measurement_file = os.path.join( datadir, f'synthetic__{pathway_name}__measurements.tsv') measurements.to_csv(measurement_file, sep='\t') # CONDITIONS condition_file = os.path.join( datadir, f'synthetic__{pathway_name}__conditions.tsv') conditions = pd.DataFrame({ petab.CONDITION_ID: measurements[petab.SIMULATION_CONDITION_ID].unique() }) for name, value in static_pars.items(): if name.endswith('_0'): conditions[name] = value conditions.set_index(petab.CONDITION_ID, inplace=True) conditions.to_csv(condition_file, sep='\t') # OBSERVABLES observables = pd.DataFrame({ petab.OBSERVABLE_ID: model.getObservableIds(), petab.OBSERVABLE_NAME: model.getObservableNames(), }) observables[petab.OBSERVABLE_FORMULA] = '0.0' observables[petab.NOISE_DISTRIBUTION] = 'normal' observables[petab.NOISE_FORMULA] = '1.0' observable_file = os.path.join( datadir, f'synthetic__{pathway_name}__observables.tsv') observables.set_index(petab.OBSERVABLE_ID, inplace=True) observables.to_csv(observable_file, sep='\t') return measurement_file, condition_file, observable_file