Beispiel #1
0
def add_state_updates(state_shape_variables_updates, neuron):
    # type: (map[str, str], ASTNeuron) -> ASTNeuron
    """
    Adds all update instructions as contained in the solver output to the update block of the neuron.
    :param state_shape_variables_updates: map of variables to corresponding updates during the update step.
    :param neuron: a single neuron
    :return: a modified version of the neuron
    """
    for variable in state_shape_variables_updates:
        declaration_statement = variable + '__tmp real = ' + state_shape_variables_updates[variable]
        add_declaration_to_update_block(ModelParser.parse_declaration(declaration_statement), neuron)
    for variable in state_shape_variables_updates:
        add_assignment_to_update_block(ModelParser.parse_assignment(variable + ' = ' + variable + '__tmp'), neuron)
    return neuron
Beispiel #2
0
def replace_integrate_call(neuron, update_instructions):
    # type: (...) -> ASTNeuron
    """
    Replaces all integrate calls to the corresponding references to propagation.
    :param neuron: a single neuron instance
    :return: The neuron without an integrate calls. The function calls are replaced through an
             incremental exact solution,
    """
    integrate_call = ASTUtils.get_function_call(neuron.get_update_blocks(), PredefinedFunctions.INTEGRATE_ODES)
    # by construction of a valid neuron, only a single integrate call should be there
    if isinstance(integrate_call, list):
        integrate_call = integrate_call[0]
    if integrate_call is not None:
        small_statement = neuron.get_parent(integrate_call)
        assert (small_statement is not None and isinstance(small_statement, ASTSmallStmt))

        block = neuron.get_parent(neuron.get_parent(small_statement))
        assert (block is not None and isinstance(block, ASTBlock))

        for i in range(0, len(block.get_stmts())):
            if block.get_stmts()[i].equals(neuron.get_parent(small_statement)):
                del block.get_stmts()[i]
                block.get_stmts()[i:i] = list((ModelParser.parse_stmt(prop) for prop in update_instructions))
                break
    return neuron
Beispiel #3
0
def apply_incoming_spikes(neuron):
    """
    Adds a set of update instructions to the handed over neuron.
    :param neuron: a single neuron instance
    :type neuron: ASTNeuron
    :return: the modified neuron
    :rtype: ASTNeuron
    """
    assert (neuron is not None and isinstance(neuron, ASTNeuron)), \
        '(PyNestML.Solver.BaseTransformer) No or wrong type of neuron provided (%s)!' % type(neuron)
    conv_calls = OdeTransformer.get_sum_function_calls(neuron)
    printer = ExpressionsPrettyPrinter()
    spikes_updates = list()
    for convCall in conv_calls:
        shape = convCall.get_args()[0].get_variable().get_complete_name()
        buffer = convCall.get_args()[1].get_variable().get_complete_name()
        initial_values = (
            neuron.get_initial_values_blocks().get_declarations() if neuron.get_initial_values_blocks() is not None else list())
        for astDeclaration in initial_values:
            for variable in astDeclaration.get_variables():
                if re.match(shape + "[\']*", variable.get_complete_name()) or re.match(shape + '__[\\d]+$',
                                                                                       variable.get_complete_name()):
                    spikes_updates.append(ModelParser.parse_assignment(
                        variable.get_complete_name() + " += " + buffer + " * " + printer.print_expression(
                            astDeclaration.get_expression())))
    for update in spikes_updates:
        add_assignment_to_update_block(update, neuron)
    return neuron
 def test_function_call_with_comments(self):
     function_call = '\n/* pre */\n' \
                     'min(1,2) # in\n' \
                     '/* post */\n\n'
     model = ModelParser.parse_stmt(function_call)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(function_call, model_printer.print_node(model))
 def test_for_stmt_with_comments(self):
     stmt = '\n/*pre*/\n' \
            'for i in 10 - 3.14...10 + 3.14 step -1: # in\n' \
            'end\n' \
            '/*post*/\n\n'
     model = ModelParser.parse_for_stmt(stmt)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(stmt, model_printer.print_node(model))
 def test(self):
     # Todo: this test is not yet complete, @ptraeder complete it
     Logger.init_logger(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__),
                                                    'resources', 'MagnitudeCompatibilityTest.nestml'))))
     # Logger.setCurrentNeuron(model.getNeuronList()[0])
     ExpressionTestVisitor().handle(model)
 def test_update_block_with_comments(self):
     block = '\n/*pre*/\n' \
             'update: # in\n' \
             'end\n' \
             '/*post*/\n\n'
     model = ModelParser.parse_update_block(block)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(block, model_printer.print_node(model))
 def test_while_stmt_with_comments(self):
     stmt = '\n/*pre*/\n' \
            'while true: # in \n' \
            'end\n' \
            '/*post*/\n\n'
     model = ModelParser.parse_while_stmt(stmt)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(stmt, model_printer.print_node(model))
 def test_neuron_with_comments(self):
     neuron = '\n/*pre*/\n' \
              'neuron test: # in\n' \
              'end\n' \
              '/*post*/\n\n'
     model = ModelParser.parse_neuron(neuron)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(neuron, model_printer.print_node(model))
 def test_function_without_comments(self):
     t_function = 'function test(Tau_1 ms) real:\n' \
                  '  exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms\n' \
                  '  return normalisation_factor\n' \
                  'end\n'
     model = ModelParser.parse_function(t_function)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(t_function, model_printer.print_node(model))
 def test_declaration_with_comments(self):
     declaration = '\n' \
                   '/*pre*/\n' \
                   'test mV = 10mV # in\n' \
                   '/*post*/\n\n'
     model = ModelParser.parse_declaration(declaration)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(declaration, model_printer.print_node(model))
    def test_solve_odes_and_shapes(self):
        input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(
            os.pardir, 'models', 'iaf_psc_alpha.nestml'))))
        compilation_unit = ModelParser.parse_model(input_path)
        assert len(compilation_unit.get_neuron_list()) == 1
        ast_neuron = compilation_unit.get_neuron_list()[0]

        nestCodeGenerator = NESTCodeGenerator()
        ast_neuron = nestCodeGenerator.transform_shapes_and_odes(ast_neuron, {})
 def test_assignment_with_comments(self):
     assignment = '\n' \
                  '/* pre */\n' \
                  'a = b # in\n' \
                  '/* post */\n' \
                  '\n'
     model = ModelParser.parse_assignment(assignment)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(assignment, model_printer.print_node(model))
 def test_invalid_element_defined_after_usage(self):
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'resources')),
             'random_number_generators_test.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_neuron(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #15
0
 def test(self):
     # Todo: this test is not yet complete, @ptraeder complete it
     Logger.init_logger(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'resources',
                              'MagnitudeCompatibilityTest.nestml'))))
     # Logger.setCurrentNeuron(model.getNeuronList()[0])
     ExpressionTestVisitor().handle(model)
Beispiel #16
0
 def test_block_with_variables_with_comments(self):
     block = '# pre1\n' \
             '# pre2\n' \
             'state: # in\n' \
             'end\n' \
             '# post1\n' \
             '# post2\n\n'
     model = ModelParser.parse_block_with_variables(block)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(block, model_printer.print_node(model))
Beispiel #17
0
 def test_invalid_coco_state_variables_initialized(self):
     """
     Test that the CoCo condition is applicable for all the variables in the state block not initialized
     """
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')),
                      'CoCoStateVariablesInitialized.nestml'))
     self.assertEqual(len(
         Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 2)
Beispiel #18
0
 def test_invalid_coco_kernel_type_initial_values(self):
     """
     Test the functionality of CoCoKernelType.
     """
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__), 'invalid')),
                      'CoCoKernelTypeInitialValues.nestml'))
     self.assertEqual(len(
         Logger.get_all_messages_of_level_and_or_node(model.get_neuron_list()[0], LoggingLevel.ERROR)), 4)
Beispiel #19
0
 def test_invalid_element_defined_after_usage(self):
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'invalid')),
             'CoCoVariableDefinedAfterUsage.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_neuron(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 2)
Beispiel #20
0
def add_declaration_to_initial_values(neuron, variable, initial_value):
    # type: (ASTNeuron, str, str) -> ASTNeuron
    """
    Adds a single declaration to the initial values block of the neuron.
    :param neuron: a neuron
    :param variable: state variable to add
    :param initial_value: corresponding initial value
    :return: a modified neuron
    """
    tmp = ModelParser.parse_expression(initial_value)
    vector_variable = ASTUtils.get_vectorized_variable(tmp, neuron.get_scope())
    declaration_string = variable + ' real' + (
        '[' + vector_variable.get_vector_parameter() + ']'
        if vector_variable is not None and vector_variable.has_vector_parameter() else '') + ' = ' + initial_value
    ast_declaration = ModelParser.parse_declaration(declaration_string)
    if vector_variable is not None:
        ast_declaration.set_size_parameter(vector_variable.get_vector_parameter())
    neuron.add_to_initial_values_block(ast_declaration)
    return neuron
Beispiel #21
0
 def test_solve_odes_and_shapes(self):
     path = str(
         os.path.realpath(
             os.path.join(
                 os.path.dirname(__file__),
                 os.path.join('..', 'models', 'iaf_psc_alpha.nestml'))))
     compilation_unit = ModelParser.parse_model(path)
     assert len(compilation_unit.get_neuron_list()) == 1
     ast_neuron = compilation_unit.get_neuron_list()[0]
     ast_neuron = transform_shapes_and_odes(ast_neuron, {})
Beispiel #22
0
def process():
    """
    Returns
    -------
    errors_occurred : bool
        Flag indicating whether errors occurred during processing
    """

    errors_occurred = False

    # init log dir
    create_report_dir()
    # The handed over parameters seem to be correct, proceed with the main routine
    init_predefined()
    # now proceed to parse all models
    compilation_units = list()
    nestml_files = FrontendConfiguration.get_files()
    if not type(nestml_files) is list:
        nestml_files = [nestml_files]
    for nestml_file in nestml_files:
        parsed_unit = ModelParser.parse_model(nestml_file)
        if parsed_unit is not None:
            compilation_units.append(parsed_unit)
    if len(compilation_units) > 0:
        # generate a list of all neurons
        neurons = list()
        for compilationUnit in compilation_units:
            neurons.extend(compilationUnit.get_neuron_list())
        # check if across two files two neurons with same name have been defined
        CoCosManager.check_not_two_neurons_across_units(compilation_units)
        # now exclude those which are broken, i.e. have errors.
        if not FrontendConfiguration.is_dev:
            for neuron in neurons:
                if Logger.has_errors(neuron):
                    code, message = Messages.get_neuron_contains_errors(
                        neuron.get_name())
                    Logger.log_message(
                        node=neuron,
                        code=code,
                        message=message,
                        error_position=neuron.get_source_position(),
                        log_level=LoggingLevel.INFO)
                    neurons.remove(neuron)
                    errors_occurred = True
        # perform code generation
        _codeGenerator = CodeGenerator(
            target=FrontendConfiguration.get_target())
        _codeGenerator.generate_code(neurons)
        for neuron in neurons:
            if Logger.has_errors(neuron):
                errors_occurred = True
                break
    if FrontendConfiguration.store_log:
        store_log_to_file()
    return errors_occurred
Beispiel #23
0
def add_declaration_to_internals(neuron, variable_name, init_expression):
    # type: (ASTNeuron,  str, str) -> ASTNeuron
    """
    Adds the variable as stored in the declaration tuple to the neuron.
    :param neuron: a single neuron instance
    :param variable_name: the name of the variable to add
    :param init_expression: initialization expression
    :return: the neuron extended by the variable
    """
    tmp = ModelParser.parse_expression(init_expression)
    vector_variable = ASTUtils.get_vectorized_variable(tmp, neuron.get_scope())

    declaration_string = variable_name + ' real' + (
        '[' + vector_variable.get_vector_parameter() + ']'
        if vector_variable is not None and vector_variable.has_vector_parameter() else '') + ' = ' + init_expression
    ast_declaration = ModelParser.parse_declaration(declaration_string)
    if vector_variable is not None:
        ast_declaration.set_size_parameter(vector_variable.get_vector_parameter())
    neuron.add_to_internal_block(ast_declaration)
    return neuron
 def test(self):
     Logger.init_logger(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__),
                                                    'resources', 'ExpressionTypeTest.nestml'))))
     Logger.set_current_neuron(model.get_neuron_list()[0])
     model.accept(ExpressionTestVisitor())
     # ExpressionTestVisitor().handle(model)
     Logger.set_current_neuron(None)
     self.assertEqual(len(Logger.get_all_messages_of_level_and_or_neuron(model.get_neuron_list()[0],
                                                                         LoggingLevel.ERROR)), 2)
 def test(self):
     Logger.init_logger(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(os.path.realpath(os.path.join(os.path.dirname(__file__),
                                                    'resources', 'ExpressionTypeTest.nestml'))))
     Logger.set_current_neuron(model.get_neuron_list()[0])
     model.accept(ExpressionTestVisitor())
     # ExpressionTestVisitor().handle(model)
     Logger.set_current_neuron(None)
     self.assertEqual(len(Logger.get_all_messages_of_level_and_or_neuron(model.get_neuron_list()[0],
                                                                         LoggingLevel.ERROR)), 2)
Beispiel #26
0
 def test_valid_element_in_same_line(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoElementInSameLine.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #27
0
 def test_invalid_integrate_odes_called_if_equations_defined(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'invalid')),
             'CoCoIntegrateOdesCalledIfEquationsDefined.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 1)
Beispiel #28
0
 def test_valid_function_unique_and_defined(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoFunctionNotUnique.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #29
0
 def test_valid_vector_in_non_vector_declaration_detected(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoVectorInNonVectorDeclaration.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #30
0
 def test_valid_compound_expression_correctly_typed(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CompoundOperatorWithDifferentButCompatibleUnits.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #31
0
 def test_valid_ode_correctly_typed(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoOdeCorrectlyTyped.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #32
0
 def test_valid_no_values_assigned_to_input_ports(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoValueAssignedToInputPort.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #33
0
 def test_invalid_order_of_equations_correct(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'invalid')),
             'CoCoNoOrderOfEquations.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 2)
Beispiel #34
0
 def test_valid_parameters_assigned_only_in_parameters_block(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoParameterAssignedOutsideBlock.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #35
0
 def test_valid_no_nest_collision(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoNestNamespaceCollision.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #36
0
 def test_valid_redundant_input_port_keywords_detected(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoInputPortWithRedundantTypes.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #37
0
 def test_valid_inline_expression_has_several_lhs(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoInlineExpressionWithSeveralLhs.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #38
0
 def test_valid_spike_input_port_without_datatype(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoSpikeInputPortWithoutType.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #39
0
 def test_valid_function_with_wrong_arg_number_detected(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoFunctionCallNotConsistentWrongArgNumber.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #40
0
 def test_invalid_each_block_unique(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'invalid')),
             'CoCoEachBlockUnique.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 2)
Beispiel #41
0
 def test_invalid_convolve_correctly_parameterized(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'invalid')),
             'CoCoConvolveNotCorrectlyParametrized.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 1)
Beispiel #42
0
 def test_valid_init_values_have_rhs_and_ode(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoInitValuesWithoutOde.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.WARNING)), 2)
Beispiel #43
0
 def test_valid_incorrect_return_stmt_detected(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoIncorrectReturnStatement.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #44
0
 def test_valid_ode_vars_outside_init_block_detected(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoOdeVarNotInInitialValues.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #45
0
 def test_valid_continuous_input_ports_not_specified(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoContinuousInputPortQualifierSpecified.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
Beispiel #46
0
 def test_valid_numerator_of_unit_one(self):
     Logger.set_logging_level(LoggingLevel.INFO)
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(
                 os.path.join(os.path.dirname(__file__), 'valid')),
             'CoCoUnitNumeratorNotOne.nestml'))
     self.assertEqual(
         len(
             Logger.get_all_messages_of_level_and_or_node(
                 model.get_neuron_list()[0], LoggingLevel.ERROR)), 0)
def integrate_delta_solution(equations_block, neuron, shape, shape_to_buffers):
    def ode_is_lin_const_coeff(ode_symbol, ode_definition, shapes):
        """
        TODO: improve the original code: the function should take a list of shape names, not objects
        :param ode_symbol string encoding the LHS
        :param ode_definition string encoding RHS
        :param shapes A list with shape names
        :return true iff the ode definition is a linear and constant coefficient ODE
        """

        ode_symbol_sp = parse_expr(ode_symbol)
        ode_definition_sp = parse_expr(ode_definition)

        # Check linearity
        ddvar = diff(diff(ode_definition_sp, ode_symbol_sp), ode_symbol_sp)

        if simplify(ddvar) != 0:
            return False

        # Check coefficients
        dvar = diff(ode_definition_sp, ode_symbol_sp)

        for shape in shapes:
            for symbol in dvar.free_symbols:
                if shape == str(symbol):
                    return False
        return True

    ode_lhs = str(equations_block.get_ode_equations()[0].get_lhs().get_name())
    ode_rhs = str(equations_block.get_ode_equations()[0].get_rhs())
    shape_name = shape.get_variable().get_name()
    if not (ode_is_lin_const_coeff(ode_lhs, ode_rhs, [shape_name])):
        raise Exception("Cannot handle delta shape in a not linear constant coefficient ODE.")
    ode_lhs = parse_expr(ode_lhs)
    ode_rhs = parse_expr(ode_rhs)
    # constant input
    const_input = simplify(1 / diff(ode_rhs, parse_expr(shape_name)) *
                           (ode_rhs - diff(ode_rhs, ode_lhs) * ode_lhs) - (parse_expr(shape_name)))
    # ode var factor
    c1 = diff(ode_rhs, ode_lhs)
    # The symbol must be declared again. Otherwise, the right hand side will be used for the derivative
    c2 = diff(ode_rhs, parse_expr(shape_name))
    # tau is passed as the second argument of the 'delta' function
    tau_constant = parse_expr(str(shape.get_expression().get_function_call().get_args()[1]))
    ode_var_factor = exp(-Symbol('__h') / tau_constant)
    ode_var_update_instructions = [
        str(ode_lhs) + " = " + str(ode_var_factor * ode_lhs),
        str(ode_lhs) + " += " + str(simplify(c2 / c1 * (exp(Symbol('__h') * c1) - 1)) * const_input)]
    for k in shape_to_buffers:
        ode_var_update_instructions.append(str(ode_lhs) + " += " + shape_to_buffers[k])
    neuron.add_to_internal_block(ModelParser.parse_declaration('__h ms = resolution()'))
    replace_integrate_call(neuron, ode_var_update_instructions)
    return neuron
 def test_block_with_variables_with_comments(self):
     block = '\n' \
             '/* pre1\n' \
             '* pre2\n' \
             '*/\n' \
             'state: # in\n' \
             'end\n' \
             '/* post1\n' \
             '* post2\n' \
             '*/\n\n'
     model = ModelParser.parse_block_with_variables(block)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(block, model_printer.print_node(model))
 def test_function_with_comments(self):
     t_function = '\n' \
                  '/*pre func*/\n' \
                  'function test(Tau_1 ms) real: # in func\n\n' \
                  '  /* decl pre */\n' \
                  '  exact_integration_adjustment real = ((1 / Tau_2) - (1 / Tau_1)) * ms # decl in\n' \
                  '  /* decl post */\n' \
                  '\n' \
                  '  return normalisation_factor\n' \
                  'end\n' \
                  '/*post func*/\n\n'
     model = ModelParser.parse_function(t_function)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(t_function, model_printer.print_node(model))
    def apply_spikes_from_buffers(self, neuron, shape_to_buffers):
        """generate the equations that update the dynamical variables when incoming spikes arrive.

        For example, a resulting `assignment_string` could be "I_shape_in += (in_spikes/nS) * 1".

        The definition of the spike kernel shape is then set to 0.
        """
        spike_updates = []
        initial_values = neuron.get_initial_values_blocks()
        for declaration in initial_values.get_declarations():
            variable = declaration.get_variables()[0]
            for shape in shape_to_buffers:
                matcher_computed_shape_odes = re.compile(shape + r"(__\d+)?")
                if re.match(matcher_computed_shape_odes, str(variable)):
                    buffer_type = neuron.get_scope(). \
                        resolve_to_symbol(shape_to_buffers[shape], SymbolKind.VARIABLE).get_type_symbol()
                    assignment_string = variable.get_complete_name() + " += (" + shape_to_buffers[
                        shape] + '/' + buffer_type.print_nestml_type() + ") * " + \
                                        self._printer.print_expression(declaration.get_expression())
                    spike_updates.append(ModelParser.parse_assignment(assignment_string))
                    # the IV is applied. can be reset
                    declaration.set_expression(ModelParser.parse_expression("0"))
        for assignment in spike_updates:
            add_assignment_to_update_block(assignment, neuron)
 def make_functions_self_contained(self, functions):
     # type: (list(ASTOdeFunction)) -> list(ASTOdeFunction)
     """
     TODO: it should be a method inside of the ASTOdeFunction
     TODO by KP: this should be done by means of a visitor
     Make function definition self contained, e.g. without any references to functions from `functions`.
     :param functions: A sorted list with entries ASTOdeFunction.
     :return: A list with ASTOdeFunctions. Defining expressions don't depend on each other.
     """
     for source in functions:
         for target in functions:
             matcher = re.compile(self._variable_matching_template.format(source.get_variable_name()))
             target_definition = str(target.get_expression())
             target_definition = re.sub(matcher, "(" + str(source.get_expression()) + ")", target_definition)
             target.expression = ModelParser.parse_expression(target_definition)
     return functions
 def replace_functions_through_defining_expressions(self, definitions, functions):
     # type: (list(ASTOdeEquation), list(ASTOdeFunction)) -> list(ASTOdeFunction)
     """
     Refractors symbols form `functions` in `definitions` with corresponding defining expressions from `functions`.
     :param definitions: A sorted list with entries {"symbol": "name", "definition": "expression"} that should be made
     free from.
     :param functions: A sorted list with entries {"symbol": "name", "definition": "expression"} with functions which
     must be replaced in `definitions`.
     :return: A list with definitions. Expressions in `definitions` don't depend on functions from `functions`.
     """
     for fun in functions:
         for target in definitions:
             matcher = re.compile(self._variable_matching_template.format(fun.get_variable_name()))
             target_definition = str(target.get_rhs())
             target_definition = re.sub(matcher, "(" + str(fun.get_expression()) + ")", target_definition)
             target.rhs = ModelParser.parse_expression(target_definition)
     return definitions
 def test(self):
     model = ModelParser.parse_model(
         os.path.join(
             os.path.realpath(os.path.join(os.path.dirname(__file__), 'resources', 'ResolutionTest.nestml'))))
     scope = model.get_neuron_list()[0].get_scope()
     res1 = scope.resolve_to_all_scopes('test1', SymbolKind.VARIABLE)
     self.assertTrue(res1 is not None)
     res2 = scope.resolve_to_all_scopes('testNot', SymbolKind.VARIABLE)
     self.assertTrue(res2 is None)
     res3 = scope.resolve_to_all_scopes('test2', SymbolKind.VARIABLE)
     self.assertTrue(res3 is not None and res3.get_scope_type() == ScopeType.FUNCTION)
     res4 = scope.resolve_to_all_scopes('arg1', SymbolKind.VARIABLE)
     self.assertTrue(res4 is not None and res4.get_scope_type() == ScopeType.FUNCTION)
     res5 = scope.resolve_to_all_scopes('test3', SymbolKind.VARIABLE)
     self.assertTrue(res5 is not None and res5.get_scope_type() == ScopeType.FUNCTION)
     res6 = scope.resolve_to_all_scopes('test1', SymbolKind.FUNCTION)
     self.assertTrue(res6 is not None and res6.get_scope_type() == ScopeType.GLOBAL)
     res7 = scope.resolve_to_all_scopes('test6', SymbolKind.VARIABLE)
     self.assertTrue(res7 is not None and res7.get_scope_type() == ScopeType.UPDATE)
    def test_model_preparation(self):
        input_path = str(os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.join(
            os.pardir, 'models', 'iaf_psc_alpha.nestml'))))
        compilation_unit = ModelParser.parse_model(input_path)
        assert len(compilation_unit.get_neuron_list()) == 1
        ast_neuron = compilation_unit.get_neuron_list()[0]
        equations_block = ast_neuron.get_equations_block()
        # the idea here is to go through the rhs, print expressions, use the same mechanism as before, and reread them
        # again
        # TODO: add tests for this function
        # this function changes stuff inplace
        nestCodeGenerator = NESTCodeGenerator()
        nestCodeGenerator.make_functions_self_contained(equations_block.get_ode_functions())

        nestCodeGenerator.replace_functions_through_defining_expressions(equations_block.get_ode_equations(),
                                                       equations_block.get_ode_functions())

        json_representation = nestCodeGenerator.transform_ode_and_shapes_to_json(equations_block)
        self.assertTrue("convolve(I_shape_in, in_spikes)" in json_representation["odes"][0]["definition"])
        self.assertTrue("convolve(I_shape_ex, ex_spikes)" in json_representation["odes"][0]["definition"])
def integrate_exact_solution(neuron, exact_solution):
    # type: (ASTNeuron, map[str, list]) -> ASTNeuron
    """
    Adds a set of instructions to the given neuron as stated in the solver output.
    :param neuron: a single neuron instance
    :param exact_solution: exact solution
    :return: a modified neuron with integrated exact solution and without equations block
    """
    neuron.add_to_internal_block(ModelParser.parse_declaration('__h ms = resolution()'))
    neuron = add_declarations_to_internals(neuron, exact_solution["propagator"])

    state_shape_variables_declarations = compute_state_shape_variables_declarations(exact_solution)
    neuron = add_declarations_to_initial_values(neuron, state_shape_variables_declarations)

    state_shape_variables_updates = compute_state_shape_variables_updates(exact_solution)
    neuron = add_state_updates(state_shape_variables_updates, neuron)

    neuron = replace_integrate_call(neuron, exact_solution["ode_updates"])

    return neuron
def functional_shapes_to_odes(neuron, transformed_shapes):
    # type: (ASTNeuron, map[str, list]) -> ASTNeuron
    """
    Adds a set of instructions to the given neuron as stated in the solver output.
    :param neuron: a single neuron instance
    :param transformed_shapes: ode-toolbox output that encodes transformation of functional shapes to odes with IV
    :return: the source neuron with modified equations block without functional shapes
    """
    shape_names, shape_name_to_initial_values, shape_name_to_shape_state_variables, shape_state_variable_to_ode = \
        _convert_to_shape_specific(transformed_shapes)

    # delete original functions shapes. they will be replaced though ode-shapes computed through ode-toolbox.
    shapes_to_delete = []  # you should not delete elements from list during iterating the list
    for declaration in neuron.get_equations_block().get_declarations():
        if isinstance(declaration, ASTOdeShape):
            if declaration.get_variable().get_name() in shape_names:
                shapes_to_delete.append(declaration)
    for declaration in shapes_to_delete:
        neuron.get_equations_block().get_declarations().remove(declaration)

    state_shape_variables_declarations = {}
    for shape_name in shape_names:
        for variable, initial_value in zip(
                shape_name_to_shape_state_variables[shape_name],
                shape_name_to_initial_values[shape_name]):
            state_shape_variables_declarations[variable] = initial_value

        for variable, shape_state_ode in zip(
                shape_name_to_shape_state_variables[shape_name],
                shape_state_variable_to_ode[shape_name]):
            ode_shape = ModelParser.parse_ode_shape("shape " + variable + "' = " + shape_state_ode)
            neuron.add_shape(ode_shape)

    neuron = add_declarations_to_initial_values(neuron, state_shape_variables_declarations)

    return neuron
 def test_block_with_variables_without_comments(self):
     block = 'state:\n' \
             'end'
     model = ModelParser.parse_block_with_variables(block)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(block, model_printer.print_node(model))
 def test_unit_type(self):
     unit = '1/(mV*kg**2)'
     model = ModelParser.parse_unit_type(unit)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(unit, model_printer.print_node(model))
 def test_unary_operator(self):
     ops = {'-', '+', '~'}
     for op in ops:
         model = ModelParser.parse_unary_operator(op)
         model_printer = ASTNestMLPrinter()
         self.assertEqual(op, model_printer.print_node(model))
 def test_assignment_without_comments(self):
     assignment = 'a = b\n'
     model = ModelParser.parse_assignment(assignment)
     model_printer = ASTNestMLPrinter()
     self.assertEqual(assignment, model_printer.print_node(model))