コード例 #1
0
ファイル: test_petab_suite.py プロジェクト: ICB-DCM/parPE
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)
コード例 #2
0
    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],
        ]
コード例 #3
0
 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
コード例 #4
0
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)
コード例 #5
0
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
コード例 #6
0
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
コード例 #7
0
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)
コード例 #8
0
    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())
コード例 #9
0
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
コード例 #10
0
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
コード例 #11
0
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)
コード例 #12
0
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