Exemple #1
0
    def ode_toolbox_analysis(self, neuron: ASTNeuron,
                             kernel_buffers: Mapping[ASTKernel, ASTInputPort]):
        """
        Prepare data for ODE-toolbox input format, invoke ODE-toolbox analysis via its API, and return the output.
        """
        assert isinstance(
            neuron.get_equations_blocks(),
            ASTEquationsBlock), "only one equation block should be present"

        equations_block = neuron.get_equations_block()

        if len(equations_block.get_kernels()) == 0 and len(
                equations_block.get_ode_equations()) == 0:
            # no equations defined -> no changes to the neuron
            return None, None

        code, message = Messages.get_neuron_analyzed(neuron.get_name())
        Logger.log_message(neuron, code, message, neuron.get_source_position(),
                           LoggingLevel.INFO)

        parameters_block = neuron.get_parameter_blocks()
        odetoolbox_indict = self.transform_ode_and_kernels_to_json(
            neuron, parameters_block, kernel_buffers)
        odetoolbox_indict["options"] = {}
        odetoolbox_indict["options"]["output_timestep_symbol"] = "__h"
        solver_result = analysis(
            odetoolbox_indict,
            disable_stiffness_check=True,
            debug=FrontendConfiguration.logging_level == "DEBUG")
        analytic_solver = None
        analytic_solvers = [
            x for x in solver_result if x["solver"] == "analytical"
        ]
        assert len(
            analytic_solvers
        ) <= 1, "More than one analytic solver not presently supported"
        if len(analytic_solvers) > 0:
            analytic_solver = analytic_solvers[0]

        # if numeric solver is required, generate a stepping function that includes each state variable
        numeric_solver = None
        numeric_solvers = [
            x for x in solver_result if x["solver"].startswith("numeric")
        ]
        if numeric_solvers:
            solver_result = analysis(
                odetoolbox_indict,
                disable_stiffness_check=True,
                disable_analytic_solver=True,
                debug=FrontendConfiguration.logging_level == "DEBUG")
            numeric_solvers = [
                x for x in solver_result if x["solver"].startswith("numeric")
            ]
            assert len(
                numeric_solvers
            ) <= 1, "More than one numeric solver not presently supported"
            if len(numeric_solvers) > 0:
                numeric_solver = numeric_solvers[0]

        return analytic_solver, numeric_solver
    def transform_shapes_and_odes(self, neuron, shape_to_buffers):
        # type: (ASTNeuron, map(str, str)) -> ASTNeuron
        """
        Solves all odes and equations in the handed over neuron.

        Precondition: it should be ensured that most one equations block is present.

        :param neuron: a single neuron instance.
        :param shape_to_buffers: Map of shape names to buffers to which they were connected.
        :return: A transformed version of the neuron that can be passed to the GSL.
        """

        assert isinstance(
            neuron.get_equations_blocks(), ASTEquationsBlock
        ), "Precondition violated: only one equation block should be present"

        equations_block = neuron.get_equations_block()

        if len(equations_block.get_ode_shapes()) == 0:
            code, message = Messages.get_neuron_solved_by_solver(
                neuron.get_name())
            Logger.log_message(neuron, code, message,
                               neuron.get_source_position(), LoggingLevel.INFO)
            return neuron
        elif len(equations_block.get_ode_shapes()) == 1 and \
                str(equations_block.get_ode_shapes()[0].get_expression()).strip().startswith(
                    "delta"):  # assume the model is well formed
            shape = equations_block.get_ode_shapes()[0]
            integrate_delta_solution(equations_block, neuron, shape,
                                     shape_to_buffers)
            return neuron
        elif len(equations_block.get_ode_equations()) == 1:
            code, message = Messages.get_neuron_analyzed(neuron.get_name())
            Logger.log_message(neuron, code, message,
                               neuron.get_source_position(), LoggingLevel.INFO)
            solver_result = self.solve_ode_with_shapes(equations_block)

            if solver_result["solver"] is "analytical":
                neuron = integrate_exact_solution(neuron, solver_result)
                neuron.remove_equations_block()
            elif (solver_result["solver"] is "numeric"
                  and self.is_functional_shape_present(
                      equations_block.get_ode_shapes())):
                functional_shapes_to_odes(neuron, solver_result)

            return neuron
        else:
            code, message = Messages.get_neuron_solved_by_solver(
                neuron.get_name())
            Logger.log_message(neuron, code, message,
                               neuron.get_source_position(), LoggingLevel.INFO)

            if self.is_functional_shape_present(
                    equations_block.get_ode_shapes()):
                ode_shapes = self.solve_functional_shapes(equations_block)
                functional_shapes_to_odes(neuron, ode_shapes)

            return neuron
def transform_shapes_and_odes(neuron, shape_to_buffers):
    # type: (ASTNeuron, map(str, str)) -> ASTNeuron
    """
    Solves all odes and equations in the handed over neuron.
    :param neuron: a single neuron instance.
    :param shape_to_buffers: Map of shape names to buffers to which they were connected.
    :return: A transformed version of the neuron that can be passed to the GSL.
    """
    # it should be ensured that most one equations block is present
    result = neuron

    if isinstance(neuron.get_equations_blocks(), ASTEquationsBlock):
        equations_block = neuron.get_equations_block()

        if len(equations_block.get_ode_shapes()) == 0:
            code, message = Messages.get_neuron_solved_by_solver(neuron.get_name())
            Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO)
            result = neuron
        if len(equations_block.get_ode_shapes()) == 1 and \
                str(equations_block.get_ode_shapes()[0].get_expression()).strip().startswith(
                    "delta"):  # assume the model is well formed
            shape = equations_block.get_ode_shapes()[0]

            integrate_delta_solution(equations_block, neuron, shape, shape_to_buffers)
            return result
        elif len(equations_block.get_ode_equations()) == 1:
            code, message = Messages.get_neuron_analyzed(neuron.get_name())
            Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO)
            solver_result = solve_ode_with_shapes(equations_block)

            if solver_result["solver"] is "analytical":
                result = integrate_exact_solution(neuron, solver_result)
                result.remove_equations_block()
            elif solver_result["solver"] is "numeric":
                at_least_one_functional_shape = False
                for shape in equations_block.get_ode_shapes():
                    if shape.get_variable().get_differential_order() == 0:
                        at_least_one_functional_shape = True
                if at_least_one_functional_shape:
                    functional_shapes_to_odes(result, solver_result)
            else:
                result = neuron
        else:
            code, message = Messages.get_neuron_solved_by_solver(neuron.get_name())
            Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO)
            at_least_one_functional_shape = False
            for shape in equations_block.get_ode_shapes():
                if shape.get_variable().get_differential_order() == 0:
                    at_least_one_functional_shape = True
                    break
            if at_least_one_functional_shape:
                ode_shapes = solve_functional_shapes(equations_block)
                functional_shapes_to_odes(result, ode_shapes)

        apply_spikes_from_buffers(result, shape_to_buffers)
    return result
    def transform_shapes_and_odes(self, neuron, shape_to_buffers):
        # type: (ASTNeuron, map(str, str)) -> ASTNeuron
        """
        Solves all odes and equations in the handed over neuron.

        Precondition: it should be ensured that most one equations block is present.

        :param neuron: a single neuron instance.
        :param shape_to_buffers: Map of shape names to buffers to which they were connected.
        :return: A transformed version of the neuron that can be passed to the GSL.
        """

        assert isinstance(neuron.get_equations_blocks(), ASTEquationsBlock), "Precondition violated: only one equation block should be present"

        equations_block = neuron.get_equations_block()

        if len(equations_block.get_ode_shapes()) == 0:
            code, message = Messages.get_neuron_solved_by_solver(neuron.get_name())
            Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO)
            return neuron
        elif len(equations_block.get_ode_shapes()) == 1 and \
                str(equations_block.get_ode_shapes()[0].get_expression()).strip().startswith(
                    "delta"):  # assume the model is well formed
            shape = equations_block.get_ode_shapes()[0]
            integrate_delta_solution(equations_block, neuron, shape, shape_to_buffers)
            return neuron
        elif len(equations_block.get_ode_equations()) == 1:
            code, message = Messages.get_neuron_analyzed(neuron.get_name())
            Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO)
            solver_result = self.solve_ode_with_shapes(equations_block)

            if solver_result["solver"] is "analytical":
                neuron = integrate_exact_solution(neuron, solver_result)
                neuron.remove_equations_block()
            elif (solver_result["solver"] is "numeric"
                  and self.is_functional_shape_present(equations_block.get_ode_shapes())):
                functional_shapes_to_odes(neuron, solver_result)

            return neuron
        else:
            code, message = Messages.get_neuron_solved_by_solver(neuron.get_name())
            Logger.log_message(neuron, code, message, neuron.get_source_position(), LoggingLevel.INFO)

            if self.is_functional_shape_present(equations_block.get_ode_shapes()):
                ode_shapes = self.solve_functional_shapes(equations_block)
                functional_shapes_to_odes(neuron, ode_shapes)

            return neuron