Exemplo n.º 1
0
CASE_NO = sys.argv[2]
TARG_DIR = sys.argv[3]
SBML_LVL = sys.argv[4]
SBML_VER = sys.argv[5]
if len(sys.argv) > 6 and sys.argv[6] == '-d': debug = True
else: debug = False
TEST_DIR = os.path.join(TEST_PATH, CASE_NO)
TEST_FILE = os.path.join(
    TEST_DIR, '{0}-sbml-l{1}v{2}.xml'.format(CASE_NO, SBML_LVL, SBML_VER))
SETTINGS_FILE = os.path.join(TEST_DIR, '{0}-settings.txt'.format(CASE_NO))
TARG_FILE = os.path.join(TARG_DIR, '{0}-results.csv'.format(CASE_NO))
EXPECTED_RESULTS_FILE = os.path.join(TEST_DIR,
                                     '{0}-results.csv'.format(CASE_NO))

solver = NumPySSASolver()
model, errors = gillespy2.import_SBML(TEST_FILE)

# retrieve simulation times from settings file
start, duration, steps = [0] * 3
with open(SETTINGS_FILE, 'r') as settings:
    for line in settings:
        if 'start' in line: start = float(line.split(': ')[1])
        elif 'duration' in line: duration = float(line.split(': ')[1])
        elif 'steps' in line: steps = int(line.split(': ')[1])

# Run simulation and store results
model.tspan = np.linspace(start, duration, steps + 1)
results = model.run(solver=solver, show_labels=False)

# Create headers for csv file
headers = ['time']
Exemplo n.º 2
0
def preprocess_sed_task(task, variables, config=None):
    """ Preprocess a SED task, including its possible model changes and variables. This is useful for avoiding
    repeatedly initializing tasks on repeated calls of :obj:`exec_sed_task`.

    Args:
        task (:obj:`Task`): task
        variables (:obj:`list` of :obj:`Variable`): variables that should be recorded
        config (:obj:`Config`, optional): BioSimulators common configuration

    Returns:
        :obj:`dict`: preprocessed information about the task
    """
    config = config or get_config()

    sim = task.simulation

    if config.VALIDATE_SEDML:
        raise_errors_warnings(validation.validate_task(task),
                              error_summary='Task `{}` is invalid.'.format(
                                  task.id))
        raise_errors_warnings(
            validation.validate_model_language(task.model.language,
                                               ModelLanguage.SBML),
            error_summary='Language for model `{}` is not supported.'.format(
                task.model.id))
        raise_errors_warnings(
            validation.validate_model_change_types(task.model.changes,
                                                   (ModelAttributeChange, )),
            error_summary='Changes for model `{}` are not supported.'.format(
                task.model.id))
        raise_errors_warnings(
            *validation.validate_model_changes(task.model),
            error_summary='Changes for model `{}` are invalid.'.format(
                task.model.id))
        raise_errors_warnings(validation.validate_simulation_type(
            sim, (UniformTimeCourseSimulation, )),
                              error_summary='{} `{}` is not supported.'.format(
                                  sim.__class__.__name__, sim.id))
        raise_errors_warnings(
            *validation.validate_simulation(sim),
            error_summary='Simulation `{}` is invalid.'.format(sim.id))
        raise_errors_warnings(
            *validation.validate_data_generator_variables(variables),
            error_summary='Data generator variables for task `{}` are invalid.'
            .format(task.id))

    model_etree = lxml.etree.parse(task.model.source)
    change_target_sbml_id_map = validation.validate_target_xpaths(
        task.model.changes, model_etree, attr='id')
    variable_target_sbml_id_map = validation.validate_target_xpaths(
        variables, model_etree, attr='id')

    # Read the SBML-encoded model located at `task.model.source`
    model, errors = gillespy2.import_SBML(task.model.source)
    if model is None or errors:
        raise ValueError('Model at {} could not be imported:\n  - {}'.format(
            task.model.source,
            '\n  - '.join(message for message, code in errors)))

    # preprocess model changes
    parameters = model.get_all_parameters()
    species = model.get_all_species()
    change_target_model_obj_map = {}
    invalid_changes = []
    for change in task.model.changes:
        sbml_id = change_target_sbml_id_map[change.target]
        model_obj = parameters.get(sbml_id, species.get(sbml_id, None))
        if model_obj is None:
            invalid_changes.append(change.target)
        else:
            change_target_model_obj_map[change.target] = model_obj

    if invalid_changes:
        raise ValueError(''.join([
            'The following model targets cannot be changed:\n  - {}\n\n'.
            format('\n  - '.join(sorted(invalid_changes)), ),
            'Model change targets must have one of the following SBML ids:\n  - {}'
            .format(
                '\n  - '.join(
                    sorted(list(parameters.keys()) + list(species.keys()))), ),
        ]))

    # Load the algorithm specified by `sim.algorithm`
    algorithm_substitution_policy = get_algorithm_substitution_policy(
        config=config)
    exec_kisao_id = get_preferred_substitute_algorithm_by_ids(
        sim.algorithm.kisao_id,
        KISAO_ALGORITHM_MAP.keys(),
        substitution_policy=algorithm_substitution_policy)
    algorithm = KISAO_ALGORITHM_MAP[exec_kisao_id]

    solver = algorithm.solver
    if solver == gillespy2.SSACSolver and (model.get_all_events() or
                                           model.get_all_assignment_rules()):
        solver = gillespy2.NumPySSASolver

    # Apply the algorithm parameter changes specified by `sim.algorithm.parameter_changes`
    algorithm_params = {}
    if exec_kisao_id == sim.algorithm.kisao_id:
        for change in sim.algorithm.changes:
            parameter = algorithm.parameters.get(change.kisao_id, None)
            if parameter:
                try:
                    parameter.set_value(algorithm_params, change.new_value)
                except (NotImplementedError, ValueError) as exception:
                    if (ALGORITHM_SUBSTITUTION_POLICY_LEVELS[
                            algorithm_substitution_policy] <=
                            ALGORITHM_SUBSTITUTION_POLICY_LEVELS[
                                AlgorithmSubstitutionPolicy.NONE]):
                        raise
                    else:
                        warn(
                            'Unsuported value `{}` for algorithm parameter `{}` was ignored:\n  {}'
                            .format(change.new_value, change.kisao_id,
                                    str(exception).replace('\n', '\n  ')),
                            BioSimulatorsWarning)
            else:
                if (ALGORITHM_SUBSTITUTION_POLICY_LEVELS[
                        algorithm_substitution_policy] <=
                        ALGORITHM_SUBSTITUTION_POLICY_LEVELS[
                            AlgorithmSubstitutionPolicy.NONE]):
                    msg = "".join([
                        "Algorithm parameter with KiSAO id '{}' is not supported. "
                        .format(change.kisao_id),
                        "Parameter must have one of the following KiSAO ids:\n  - {}"
                        .format('\n  - '.join(
                            '{}: {}'.format(kisao_id, parameter.name)
                            for kisao_id, parameter in
                            algorithm.parameters.items())),
                    ])
                    raise NotImplementedError(msg)
                else:
                    msg = "".join([
                        "Algorithm parameter with KiSAO id '{}' was ignored because it is not supported. "
                        .format(change.kisao_id),
                        "Parameter must have one of the following KiSAO ids:\n  - {}"
                        .format('\n  - '.join(
                            '{}: {}'.format(kisao_id, parameter.name)
                            for kisao_id, parameter in
                            algorithm.parameters.items())),
                    ])
                    warn(msg, BioSimulatorsWarning)

    # determine allowed variable targets
    predicted_ids = list(species.keys()) + list(parameters.keys())
    unpredicted_symbols = set()
    unpredicted_targets = set()
    for variable in variables:
        if variable.symbol:
            if variable.symbol != Symbol.time:
                unpredicted_symbols.add(variable.symbol)

        else:
            if variable_target_sbml_id_map[
                    variable.target] not in predicted_ids:
                unpredicted_targets.add(variable.target)

    if unpredicted_symbols:
        raise NotImplementedError("".join([
            "The following variable symbols are not supported:\n  - {}\n\n".
            format('\n  - '.join(sorted(unpredicted_symbols)), ),
            "Symbols must be one of the following:\n  - {}".format(
                Symbol.time),
        ]))

    if unpredicted_targets:
        raise ValueError(''.join([
            'The following variable targets could not be recorded:\n  - {}\n\n'
            .format('\n  - '.join(sorted(unpredicted_targets)), ),
            'Targets must have one of the following SBML ids:\n  - {}'.format(
                '\n  - '.join(sorted(predicted_ids)), ),
        ]))

    # return preprocessed information about the task
    return {
        'model': {
            'model': model,
            'change_target_model_obj_map': change_target_model_obj_map,
            'variable_target_sbml_id_map': variable_target_sbml_id_map,
        },
        'simulation': {
            'algorithm_kisao_id': exec_kisao_id,
            'solver': solver,
            'solver_args': dict(**algorithm.solver_args, **algorithm_params),
        }
    }
    def test_exec_sed_task_with_model_changes(self):
        task = sedml_data_model.Task(
            model=sedml_data_model.Model(
                source=os.path.join(os.path.dirname(__file__), 'fixtures', 'BIOMD0000000297.edited', 'ex1', 'BIOMD0000000297.xml'),
                language=sedml_data_model.ModelLanguage.SBML.value,
                changes=[
                    sedml_data_model.ModelAttributeChange(
                        target="/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='kswe_prime']",
                        target_namespaces=self.NAMESPACES,
                        new_value=None,
                    ),
                ],
            ),
            simulation=sedml_data_model.UniformTimeCourseSimulation(
                algorithm=sedml_data_model.Algorithm(
                    kisao_id='KISAO_0000088',
                ),
                initial_time=0.,
                output_start_time=0.,
                output_end_time=20.,
                number_of_points=20,
            ),
        )

        variables = [
            sedml_data_model.Variable(
                id='kswe_prime',
                target="/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='kswe_prime']",
                target_namespaces=self.NAMESPACES,
                task=task,
            ),
        ]

        model, errors = gillespy2.import_SBML(task.model.source)
        for sbml_id in model.get_all_species().keys():
            if sbml_id in ['kswe', 'kmih', 'IEin', 'Cdh1in', 'Mih1', 'Mcmin', 'SBFin', 'BUD', 'flag', 'Swe1T']:
                target = "/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='{}']".format(sbml_id)
            else:
                target = "/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='{}']".format(sbml_id)
            task.model.changes.append(sedml_data_model.ModelAttributeChange(
                target=target,
                target_namespaces=self.NAMESPACES,
                new_value=None,
            ))
            variables.append(sedml_data_model.Variable(
                id=sbml_id,
                target=target,
                target_namespaces=self.NAMESPACES,
                task=task,
            ))

        preprocessed_task = core.preprocess_sed_task(task, variables)

        task.model.changes = []
        results, _ = core.exec_sed_task(task, variables, preprocessed_task=preprocessed_task)
        numpy.testing.assert_allclose(results['kswe_prime'][0], 2.)
        numpy.testing.assert_allclose(results['Clg'][0], 0.053600963)

        results_2, _ = core.exec_sed_task(task, variables, preprocessed_task=preprocessed_task)
        for variable in variables:
            numpy.testing.assert_allclose(results_2[variable.id], results[variable.id])

        task.simulation.output_end_time /= 2
        task.simulation.number_of_points = int(task.simulation.number_of_points / 2)
        results_2a, _ = core.exec_sed_task(task, variables, preprocessed_task=preprocessed_task)
        for sbml_id in model.get_all_species().keys():
            if sbml_id in ['kswe', 'kmih', 'IEin', 'Cdh1in', 'Mih1', 'Mcmin', 'SBFin', 'BUD', 'flag', 'Swe1T']:
                target = "/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='{}']".format(sbml_id)
            else:
                target = "/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='{}']".format(sbml_id)
            task.model.changes.append(sedml_data_model.ModelAttributeChange(
                target=target,
                target_namespaces=self.NAMESPACES,
                new_value=results_2a[sbml_id][-1],
            ))
        results_2b, _ = core.exec_sed_task(task, variables, preprocessed_task=preprocessed_task)
        for variable in variables:
            numpy.testing.assert_allclose(results_2b[variable.id], results[variable.id]
                                          [-(task.simulation.number_of_points + 1):], rtol=1e-3)

        task.model.changes = [
            sedml_data_model.ModelAttributeChange(
                target="/sbml:sbml/sbml:model/sbml:listOfParameters/sbml:parameter[@id='kswe_prime']",
                target_namespaces=self.NAMESPACES,
                new_value=3.,
            ),
            sedml_data_model.ModelAttributeChange(
                target="/sbml:sbml/sbml:model/sbml:listOfSpecies/sbml:species[@id='Clg']",
                target_namespaces=self.NAMESPACES,
                new_value=0.0001,
            ),
        ]

        results_2, _ = core.exec_sed_task(task, variables, preprocessed_task=preprocessed_task)
        numpy.testing.assert_allclose(results_2['kswe_prime'][0], 3.)
        numpy.testing.assert_allclose(results_2['Clg'][0], 0.0001)

        task.model.changes[0].new_value = '0.3'
        task.model.changes[1].new_value = '0.0003'

        results_2, _ = core.exec_sed_task(task, variables, preprocessed_task=preprocessed_task)
        numpy.testing.assert_allclose(results_2['kswe_prime'][0], 0.3)
        numpy.testing.assert_allclose(results_2['Clg'][0], 0.0003)

        task.model.changes[0].target = '/sbml:sbml/sbml:model'
        with self.assertRaisesRegex(ValueError, 'cannot be changed'):
            preprocessed_task = core.preprocess_sed_task(task, variables)