Пример #1
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)
Пример #2
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)
Пример #3
0
        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)
Пример #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)
Пример #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()
Пример #6
0
def do_sim_and_measure(run_number,
                       params,
                       plugin,
                       plugin_name,
                       method,
                       plot_file=None):
    """Do a simulation run and get the measurements"""
    plugin.method = method

    if hasattr(plugin, "delta_t"):
        # For most ODEs we have delta
        plugin.delta_t = 1
    else:
        # For stochastic sim we set the resolution (that is the number of sample numbers needed)
        plugin.resolution = sim_end_time

    out = plugin(sim_end_time, initial_conditions, params, drain_params)

    assert out is not None, "Output from run {} was None".format(run_number)

    if out.has_errors and len(out.dependent) == len(out.independent) == 0:
        warnings.warn("Simulation Error encountered using plugin: {}".format(
            plugin_name))
        raise SimulationError(*[m for err in out.errors for m in err.args])

    analytics = DynamicAnalysisDevice(out)
    sim_end = out.independent[-1]
    n_sample_points = len(out.dependent)

    print("Is data equally spaced?", out.is_data_evenly_spaced())
    print("Stop prematurely?", out.has_sim_prematurely_stopped())

    if not out.is_data_evenly_spaced():
        print("Data was not equally spaced. Applying linear interpolation...")
        out = out.interpolate_data(new_sample_resolution=sim_end_time)

    freqs = analytics.fourier_frequencies
    amp_spec = analytics.amplitude_spectra

    print("Frequency bins: {}".format(len(freqs)))
    freqs, amp_spec = analytics.cutoff_dc_component(freqs, amp_spec)

    variance_measurement = np.array([data.var() for data in out.dependent.T])
    print("Variance measurements: {}".format(variance_measurement))
    pair_diff = analytics.pair_distance_measurement()
    print("Pair distance measurements: {}".format(pair_diff))
    fourier_amplitude_measurement = np.array([], dtype=float)
    fourier_frequency_measurement = np.array([], dtype=float)

    for i in range(ode.species_count):
        arg_max_fourier = amp_spec[i].argmax()
        fourier_amplitude_measurement = np.append(
            fourier_amplitude_measurement, amp_spec[i, arg_max_fourier])
        fourier_frequency_measurement = np.append(
            fourier_frequency_measurement, freqs[arg_max_fourier])

    assert len(fourier_amplitude_measurement) == len(
        fourier_frequency_measurement)
    assert len(fourier_amplitude_measurement) == len(variance_measurement)
    print("Fourier maximum amplitude measurements: {}".format(
        fourier_amplitude_measurement))
    print("Fourier maximum frequency measurements: {}".format(
        fourier_frequency_measurement))

    if plot_file is not None:
        std_m, famp_m, ffreq_m, pd_m = max(np.sqrt(variance_measurement)), max(fourier_amplitude_measurement), \
                                       max(fourier_frequency_measurement), max(pair_diff)
        status = "s"
        if not out.has_sim_prematurely_stopped():
            title = "{} {} - Run: {} / {}, measures: (std-dev: {}, amp: {}, freq: {}, pd: {})"\
                .format(out.solver_used.name, method, run_number + 1, runs, std_m, famp_m, ffreq_m, pd_m)

            image_path = os.path.join(
                output_dir,
                "{}_{}_{}_plot{}_{}_{}.png".format(file_prefix, plugin_name,
                                                   method_name, run_number + 1,
                                                   runs, dt))
            out.plot(filename=image_path, figure_size=(46, 24), title=title)

            image_path = os.path.join(
                output_dir, "{}_fourier_{}_{}_plot{}_{}_{}.png".format(
                    file_prefix, plugin_name, method_name, run_number + 1,
                    runs, dt))
            analytics.plot_spectra(amp_spec,
                                   freqs,
                                   title=title,
                                   filename=image_path,
                                   figure_size=(46, 24))
            plt.close('all')  # we don't need to show the figures
        else:
            status = "a"
            title = "{} {} - Run: {} / {}, measures: " \
                    "(std-dev: {}, amp: {}, freq: {}, pair_diff: {}), aborted at ({}, {})" \
                .format(out.solver_used.name, method, run_number + 1, runs, std_m, famp_m, ffreq_m, pd_m,
                        out.independent[-1], out.dependent[-1])

            image_path = os.path.join(
                output_dir, "aborted_{}_{}_{}_plot{}_{}_{}.png".format(
                    file_prefix, plugin_name, method_name, run_number + 1,
                    runs, dt))
            out.plot(filename=image_path, figure_size=(46, 24), title=title)
            plt.close('all')

        plot_file.write("{}\t{}\t{}\t{}\t{}\t{}\n".format(
            run_number + 1, status, fp(std_m), fp(famp_m), fp(ffreq_m),
            fp(pd_m)))

    measurement_output['n_sample'].append(n_sample_points)
    measurement_output['end_t'].append(sim_end)
    measurement_output['variance'].append(variance_measurement)
    measurement_output['fourier_freq'].append(fourier_frequency_measurement)
    measurement_output['fourier_amp'].append(fourier_amplitude_measurement)
    measurement_output['pair_diff'].append(pair_diff)
Пример #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)