Ejemplo n.º 1
0
        def fixed_step_integration():
            try:
                while solver.successful() and solver.t <= end_t:
                    y_solution.append(solver.y)
                    t_solution.append(solver.t)
                    solver.integrate(solver.t + self.delta_t)
            except SystemError as integration_error:
                self._logger.exception("Integration process failed",
                                       integration_error)
                messages.print_solver_done(name,
                                           method_name=self.method.name,
                                           was_failure=True)
                return SimulationOutput(
                    name, (self.initial_t, end_t),
                    self._simulator.symbols,
                    dependent=y_solution,
                    independent=t_solution,
                    errors=(SimulationError("Integration failure"), ))

            self._logger.debug("Solving finished using fixed step integration")
            messages.print_solver_done(name, method_name=self.method.name)
            return SimulationOutput(name,
                                    user_sim_range=(self.initial_t, end_t),
                                    dependent=y_solution,
                                    independent=t_solution,
                                    symbols=self._simulator.symbols,
                                    ignore=self._simulator.ignored,
                                    solver_method=self.method)
Ejemplo n.º 2
0
        def variable_step_integration():
            def solution_getter(t, y):
                y_solution.append(y.copy())
                t_solution.append(t)

            solver.set_solout(solout=solution_getter)

            try:
                while solver.successful() and solver.t < end_t:
                    solver.integrate(end_t, step=True)
            except SystemError as integration_error:
                self._logger.exception("Integration process failed",
                                       integration_error)
                messages.print_solver_done(name,
                                           method_name=self.method.name,
                                           was_failure=True)
                return SimulationOutput(
                    name, (self.initial_t, end_t),
                    self._simulator.symbols,
                    dependent=y_solution,
                    independent=t_solution,
                    errors=(SimulationError("Integration failure"), ))

            self._logger.debug(
                "Solving finished using variable step integration")
            messages.print_solver_done(name, method_name=self.method.name)
            return SimulationOutput(name, (self.initial_t, end_t),
                                    dependent=y_solution,
                                    independent=t_solution,
                                    symbols=self._simulator.symbols,
                                    ignore=self._simulator.ignored,
                                    solver_method=self.method)
Ejemplo n.º 3
0
        def collect_multiple_output(trajectories_paths, errors=()):
            for tpath in trajectories_paths:
                try:
                    header, independent, dependent = read_output(tpath)

                    yield SimulationOutput(name, (0, end_t), header,
                                           independent=independent, dependent=dependent,
                                           solver_method=self.method, errors=errors)
                except FileNotFoundError as e:
                    yield SimulationOutput(name, (0, end_t), self._simulator.symbols,
                                           solver_method=self.method, errors=(e,) + errors)
Ejemplo n.º 4
0
    def simulate(self, end_t, initial_conditions, rate_parameters, drain_parameters=None, *args, **kwargs):
        simulation_parameter_validate(end_t=end_t, initial_conditions=initial_conditions,
                                      rates_params=rate_parameters, drain_params=drain_parameters)

        ode_function = get_matlab_lambda(simulator=self._simulator, parameter_substitutions=rate_parameters,
                                         drain_substitutions=drain_parameters)

        if ode_function is None or len(ode_function) == 0:
            self._logger.error("Matlab ode function was not generated")
            messages.print_solver_done(name, method_name=self.method.name, was_failure=True)
            return SimulationOutput(name, (self.initial_t, end_t), self._simulator.symbols,
                                    errors=(SimulationError("Ode function could not be generated"),))

        self._logger.debug("Solving ode using MATLAB")

        conditions = get_initial_values(initial_conditions, self._simulator.symbols)

        if isinstance(conditions, (list, tuple)):
            self.add_to_workspace('y0', matlab.double(conditions))
        else:
            # python 3 returns a view not a list of values
            self.add_to_workspace('y0', matlab.double(list(conditions)))

        self.add_to_workspace('tspan', matlab.double((self.initial_t, end_t)))

        eval_str = "ode" + str(self.method.value) + "(" + ode_function + ", tspan, y0)"
        self._logger.debug("evaluating matlab \
expression: {} with tspan: {} and y0: {}".format(eval_str, (self.initial_t, end_t), initial_conditions))

        t_result, y_result = self.engine.eval(eval_str, nargout=2)
        if len(t_result) >= 2:
            self.delta_t = t_result._data[1] - t_result._data[0]
        self.engine.clear(nargout=0)
        self._logger.debug("Successfully solved")

        # http://stackoverflow.com/questions/30013853/convert-matlab-double-array-to-python-array
        def convert_matrix(double_matrix):
            row_width = double_matrix.size[0]
            for x in range(row_width):
                yield double_matrix._data[x::row_width].tolist()

        # flat that list
        t_result = tuple(a for i in t_result for a in i)
        y_result = tuple(convert_matrix(y_result))

        self._logger.info("Return output object")
        messages.print_solver_done(name, method_name=self.method.name)
        return SimulationOutput(solved_by=name, user_sim_range=(self.initial_t, end_t),
                                symbols=self._simulator.symbols,
                                dependent=y_result, independent=t_result,
                                ignore=self._simulator.ignored, solver_method=self.method)
Ejemplo n.º 5
0
    def simulate(self,
                 end_t,
                 initial_conditions,
                 rate_parameters,
                 drain_parameters=None,
                 *args,
                 **kwargs):
        simulation_parameter_validate(end_t=end_t,
                                      initial_conditions=initial_conditions,
                                      rates_params=rate_parameters,
                                      drain_params=drain_parameters)

        ode_function = get_scipy_lambda(self._simulator, rate_parameters,
                                        drain_parameters)

        if not ode_function:
            if config.getboolean('Logging', 'ENABLED_LOGGING'):
                self._logger.error("Scipy ode function was not generated")
            messages.print_solver_done(name,
                                       method_name=self.method.name,
                                       was_failure=True)
            return SimulationOutput(
                name,
                end_t,
                symbols=self._simulator.symbols,
                errors=(
                    SimulationError("Ode function could not be generated"), ))

        try:
            ode_function = eval(ode_function)
        except SyntaxError:
            if config.getboolean('Logging', 'ENABLE_LOGGING'):
                self._logger.error(
                    "Scipy ode function was not generated; syntax error")
            messages.print_solver_done(name,
                                       method_name=self.method.name,
                                       was_failure=True)
            return SimulationOutput(
                name,
                end_t,
                self._simulator.symbols,
                errors=(SimulationError("Internal syntax error encountered")))

        initial_y = get_initial_values(initial_conditions,
                                       self._simulator.symbols)

        self._logger.debug("Started solving using Scipy with method {}".format(
            self.method.value))
        self._logger.debug(
            "Initial conditions are {}, range: {} and dt: {} ".format(
                initial_conditions, end_t, self.delta_t))

        y_solution = list()
        t_solution = list()
        solver = scipy.integrate.ode(ode_function).set_integrator(
            self.method.value, **kwargs)
        solver.set_initial_value(y=initial_y, t=self.initial_t)
        solver.t = self.initial_t

        def fixed_step_integration():
            try:
                while solver.successful() and solver.t <= end_t:
                    y_solution.append(solver.y)
                    t_solution.append(solver.t)
                    solver.integrate(solver.t + self.delta_t)
            except SystemError as integration_error:
                self._logger.exception("Integration process failed",
                                       integration_error)
                messages.print_solver_done(name,
                                           method_name=self.method.name,
                                           was_failure=True)
                return SimulationOutput(
                    name, (self.initial_t, end_t),
                    self._simulator.symbols,
                    dependent=y_solution,
                    independent=t_solution,
                    errors=(SimulationError("Integration failure"), ))

            self._logger.debug("Solving finished using fixed step integration")
            messages.print_solver_done(name, method_name=self.method.name)
            return SimulationOutput(name,
                                    user_sim_range=(self.initial_t, end_t),
                                    dependent=y_solution,
                                    independent=t_solution,
                                    symbols=self._simulator.symbols,
                                    ignore=self._simulator.ignored,
                                    solver_method=self.method)

        def variable_step_integration():
            def solution_getter(t, y):
                y_solution.append(y.copy())
                t_solution.append(t)

            solver.set_solout(solout=solution_getter)

            try:
                while solver.successful() and solver.t < end_t:
                    solver.integrate(end_t, step=True)
            except SystemError as integration_error:
                self._logger.exception("Integration process failed",
                                       integration_error)
                messages.print_solver_done(name,
                                           method_name=self.method.name,
                                           was_failure=True)
                return SimulationOutput(
                    name, (self.initial_t, end_t),
                    self._simulator.symbols,
                    dependent=y_solution,
                    independent=t_solution,
                    errors=(SimulationError("Integration failure"), ))

            self._logger.debug(
                "Solving finished using variable step integration")
            messages.print_solver_done(name, method_name=self.method.name)
            return SimulationOutput(name, (self.initial_t, end_t),
                                    dependent=y_solution,
                                    independent=t_solution,
                                    symbols=self._simulator.symbols,
                                    ignore=self._simulator.ignored,
                                    solver_method=self.method)

        if self.method == ScipyOdeSolvers.DOP853 or self.method == ScipyOdeSolvers.DOPRI5:
            return variable_step_integration()
        else:
            return fixed_step_integration()
Ejemplo n.º 6
0
def show_plots(*args, **kwargs):
    SimulationOutput.show(block=True, *args, **kwargs)
Ejemplo n.º 7
0
    def simulate(self,
                 end_t,
                 initial_conditions,
                 rate_parameters,
                 drain_parameters=None,
                 timeout=None,
                 rel_tol=None,
                 abs_tol=None):

        self._logger.info("Starting on SPiM simulation")
        self._logger.info("End_t: {} resolution: {}".format(
            end_t, self.resolution))
        self._logger.info("Initial conditions: {}".format(initial_conditions))
        self._logger.info("Rates: {}".format(rate_parameters))
        self._logger.info("Drains: {}".format(drain_parameters))

        simulation_parameter_validate(end_t=end_t,
                                      initial_conditions=initial_conditions,
                                      rates_params=rate_parameters,
                                      drain_params=drain_parameters)

        def collect_data(errors=None):
            errors = [] if errors is None else errors
            ignore_pad = [(i, initial_conditions[label])
                          for label, i in self._simulator.ignored]
            res_indep, res_dep = [], []
            with open(csv_file_path) as file:
                reader = csv.reader(file)
                next(reader)
                old_time = 0.0
                for line in reader:
                    new_time = float(line[0])
                    if new_time > old_time or math.isclose(
                            new_time,
                            old_time,
                            rel_tol=self.relative_float_tolerance,
                            abs_tol=self.absolute_float_tolerance):
                        res_indep.append(new_time)
                        dep = list(map(float, line[1:]))
                        for index, val in ignore_pad:
                            dep.insert(index, val)
                        res_dep.append(dep)
                        old_time = new_time
                    else:
                        errors.append(
                            SimulationError(
                                "Simulation time regression detected"))

            return numpy.array(res_indep), numpy.array(res_dep)

        errors = list()
        self.timeout = timeout if timeout is not None else self.timeout
        self.relative_float_tolerance = rel_tol if rel_tol is not None else self.relative_float_tolerance
        self.absolute_float_tolerance = abs_tol if abs_tol is not None else self.absolute_float_tolerance

        with tempfile.TemporaryDirectory() as tmpdir:

            file_path_code = os.path.join(tmpdir, "spim.spi")
            csv_file_path = os.path.join(tmpdir, "spim.spi.csv")
            with open(file_path_code, mode="w") as script:
                self.generate_code_file(script, (end_t, self.resolution),
                                        initial_conditions, rate_parameters,
                                        drain_parameters)

            if logging_is_enabled():
                with open(file_path_code) as debug_file:
                    self._logger.info("SPiM simulation file:\n{}".format(
                        debug_file.read()))

            run_parameters = [
                self._ocamlrun_path, self._spim_path, file_path_code
            ]
            try:
                process = subprocess.Popen(run_parameters,
                                           stdin=subprocess.PIPE,
                                           stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE,
                                           universal_newlines=True)
                stdout, stderr = process.communicate(input="\n",
                                                     timeout=self.timeout)

                self._logger.info("SPiM stdout:\n{}".format(stdout))
            except subprocess.TimeoutExpired:
                process.kill()
                process.communicate()
                errors.append(SimulationError("Simulation time out"))
                messages.print_solver_done(name, was_failure=True)
                independent, dependent = collect_data(errors)
                return SimulationOutput(name, (0, end_t),
                                        symbols=self._simulator.symbols,
                                        ignore=self._simulator.ignored,
                                        independent=independent,
                                        dependent=dependent,
                                        errors=errors)

            if not os.path.isfile(csv_file_path):
                if logging_is_enabled():
                    self._logger.error("Missing SPiM output")
                errors.append(SimulationError("Missing SPiM output"))
                messages.print_solver_done(name, was_failure=True)
                return SimulationOutput(name, (0, end_t),
                                        symbols=self._simulator.symbols,
                                        errors=errors)

            independent, dependent = collect_data(errors)
            if errors:
                messages.print_solver_done(name, was_failure=True)
                return SimulationOutput(name, (0, end_t),
                                        symbols=self._simulator.symbols,
                                        independent=independent,
                                        dependent=dependent,
                                        ignore=self._simulator.ignored,
                                        errors=errors)
            else:
                messages.print_solver_done(name, was_failure=False)
                return SimulationOutput(name, (0, end_t),
                                        symbols=self._simulator.symbols,
                                        ignore=self._simulator.ignored,
                                        independent=independent,
                                        dependent=dependent)
Ejemplo n.º 8
0
    def simulate(self, end_t, initial_conditions, rate_parameters, drain_parameters=None, *args, **kwargs):
        model_filename = "model.xml"
        output_dirname = "model_output"
        self._logger.info("Starting on StochKit2 simulation with {} trajectories, "
                         "{} method, end time: {}, and {} sample points".format(self.trajectories, self.method,
                                                                                end_t, self.resolution))

        simulation_parameter_validate(end_t=end_t, initial_conditions=initial_conditions,
                                      rates_params=rate_parameters, drain_params=drain_parameters)

        def read_output(filepath):
            independent = array.array('d')
            dependent = tuple()
            label_translator = {v.replace('$', ''): k for k, v in self._simulator.internal_symbol_dict.items()}
            with open(filepath, mode="r") as rfile:
                white_space = re.compile(r"\s+")
                header = white_space.split(next(rfile).strip())
                for line in rfile:
                    splitted = array.array('d', map(float, white_space.split(line.strip())))
                    independent.append(splitted[:1][0])
                    dependent += (splitted[1:],)
            return tuple(label_translator[sym] for sym in header[1:]), independent, dependent

        def collect_multiple_output(trajectories_paths, errors=()):
            for tpath in trajectories_paths:
                try:
                    header, independent, dependent = read_output(tpath)

                    yield SimulationOutput(name, (0, end_t), header,
                                           independent=independent, dependent=dependent,
                                           solver_method=self.method, errors=errors)
                except FileNotFoundError as e:
                    yield SimulationOutput(name, (0, end_t), self._simulator.symbols,
                                           solver_method=self.method, errors=(e,) + errors)

        self._logger.info("started on StochKit2 simulation")

        with tempfile.TemporaryDirectory() as tmp_dir:
            model_path = path.join(tmp_dir, model_filename)
            model_home_dir = path.join(tmp_dir, output_dirname)
            model = self.model(initial_conditions, rate_parameters, drain_parameters)

            self._logger.info("Stochkit2 model:\n{}".format(model))
            with open(model_path, mode="w") as model_file:
                model_file.write(model)

            if self.method == StochKit2StochasticSolvers.SSA:
                program_name = "ssa"
            elif self.method == StochKit2StochasticSolvers.tauLeaping:
                program_name = "tau_leaping"
            else:
                raise util_exceptions.SimulationError("Unknown stochkit2 method selected")

            program_path = path.join(self.stochkit2_path, program_name)
            self._logger.info("Using stochkit2 driver at {}".format(program_name))
            execution_args = [program_path, '-m {}'.format(model_path),
                              '-r {}'.format(self.trajectories), '-t {}'.format(end_t),
                              '-i {}'.format(self.resolution),
                              '--epsilon {}'.format(self.tau_leaping_epsilon),
                              '--threshold {}'.format(self.switch_threshold),
                              *self.flag_options]
            self._logger.info("Execution arguments are {!r}".format(" ".join(execution_args)))

            with subprocess.Popen(" ".join(execution_args), shell=True, stdout=subprocess.PIPE,
                                  stderr=subprocess.STDOUT, preexec_fn=os.setsid) as process:
                try:
                    output, unused_err = process.communicate(timeout=self.timeout)
                    self._logger.info(output)
                except subprocess.TimeoutExpired as exception:
                    # Time out path
                    os.killpg(os.getpgid(process.pid), signal.SIGINT)
                    messages.print_solver_done(name, self.method.name, was_failure=True)
                    try:
                        partial_trajectories = os.listdir(path.join(model_home_dir, 'trajectories'))
                    except FileNotFoundError:
                        # Error in listing trajectory files
                        messages.print_solver_done(name, self.method.name, True)
                        return SimulationOutput(name, (0, end_t), self._simulator.symbols,
                                                solver_method=self.method, errors=(exception,
                                                                                   util_exceptions.
                                                                                   SimulationError(
                                                                                       "No partial trajectories")))

                    if len(partial_trajectories) == 0:
                        # There was no trajectory files
                        messages.print_solver_done(name, self.method.name, True)
                        return SimulationOutput(name, (0, end_t), self._simulator.symbols,
                                                solver_method=self.method, errors=(exception,))
                    else:
                        # Collected from all partial trajectory files
                        messages.print_solver_done(name, self.method.name, True)
                        return SimulationOutputSet(collect_multiple_output(partial_trajectories,
                                                                           errors=(exception,)))

                if process.returncode != 0:
                    # Error in process execution
                    exception = util_exceptions.SimulationError("Error in simulation: {}".format(output.decode()))
                    messages.print_solver_done(name, self.method.name, was_failure=True)
                    return SimulationOutput(name, (0, end_t), self._simulator.symbols,
                                            solver_method=self.method, errors=(exception,))
            output_trajectories_path = path.join(model_home_dir, 'trajectories')
            trajectory_paths = tuple(os.path.join(output_trajectories_path, t)
                                     for t in os.listdir(output_trajectories_path))

            if len(trajectory_paths) != self.trajectories:
                # Partial trajectories
                with open(path.join(model_home_dir, 'log.txt')) as log:
                    log_message = log.readlines()
                    if settings.logging_is_enabled():
                        self._logger.warn(log_message)
                    if len(trajectory_paths) == 0:
                        messages.print_solver_done(name, self.method.name, True)
                        return SimulationOutput(name, (0, end_t), self._simulator.symbols,
                                                solver_method=self.method, errors=(util_exceptions
                                                                                   .SimulationError("Simulation ended "
                                                                                                    "with no output"),))
                    else:
                        messages.print_solver_done(name, self.method.name, True)
                        return SimulationOutputSet(collect_multiple_output(trajectory_paths, errors=(util_exceptions
                                                                                                     .SimulationError(
                                                                                                      log_message),),))
            elif self.trajectories == 1:
                # Only one trajectory was requested so don't pack to set
                messages.print_solver_done(name, self.method.name)
                return list(collect_multiple_output(trajectory_paths))[0]
            else:
                # We got all the trajectories!
                messages.print_solver_done(name, self.method.name)
                return SimulationOutputSet(collect_multiple_output(trajectory_paths))