Exemple #1
0
    def test_inheritance(self):
        import libcellml
        from libcellml import Analyser

        x = Analyser()
        self.assertIsInstance(x, libcellml.logger.Logger)

        # Test access to inherited methods.
        self.assertIsNone(x.issue(0))
        self.assertIsNone(x.issue(-1))
        self.assertEqual(x.issueCount(), 0)
Exemple #2
0
    def test_algebraic_eqn_computed_var_on_rhs(self):
        from libcellml import Analyser
        from libcellml import AnalyserModel
        from libcellml import Generator
        from libcellml import GeneratorProfile
        from libcellml import Parser
        from test_resources import file_contents

        p = Parser()
        m = p.parseModel(
            file_contents(
                'generator/algebraic_eqn_computed_var_on_rhs/model.cellml'))

        a = Analyser()
        a.analyseModel(m)

        am = a.model()

        self.assertEqual(AnalyserModel.Type.ALGEBRAIC, am.type())

        g = Generator()

        self.assertIsNone(g.model())

        g.setModel(am)

        self.assertIsNotNone(g.model())

        self.assertEqual(
            file_contents(
                "generator/algebraic_eqn_computed_var_on_rhs/model.h"),
            g.interfaceCode())
        self.assertEqual(
            file_contents(
                "generator/algebraic_eqn_computed_var_on_rhs/model.c"),
            g.implementationCode())

        self.assertEqual(GeneratorProfile.Profile.C, g.profile().profile())

        profile = GeneratorProfile(GeneratorProfile.Profile.PYTHON)
        g.setProfile(profile)

        self.assertEqual("", g.interfaceCode())
        self.assertEqual(
            file_contents(
                "generator/algebraic_eqn_computed_var_on_rhs/model.py"),
            g.implementationCode())

        self.assertEqual(GeneratorProfile.Profile.PYTHON,
                         g.profile().profile())
Exemple #3
0
    def test_analyse_model(self):
        from libcellml import Analyser
        from libcellml import AnalyserModel
        from libcellml import Model

        # Analyse an empty model and make sure that we get no errors and an
        # UNKNOWN type for the analyser model.

        m = Model('my_model')
        a = Analyser()

        a.analyseModel(m)

        self.assertEqual(0, a.errorCount())
        self.assertEqual(AnalyserModel.Type.UNKNOWN, a.model().type())
    print('----------------------------------------------------------')
    print('   STEP 3: Validate and analyse the flattened model       ')
    print('----------------------------------------------------------')

    #  3.a
    #      Create a Validator instance, pass in the flattened model, and check that
    #      there are no issues raised.
    validator = Validator()
    validator.validateModel(flatModel)
    print_issues(validator)

    #  3.b
    #      Create an Analyser instance, pass in the flattened model, and check that
    #      there are no issues raised.
    analyser = Analyser()
    analyser.analyseModel(flatModel)
    print_issues(analyser)

    #  end 3

    print('----------------------------------------------------------')
    print('   STEP 4: Generate code and output                       ')
    print('----------------------------------------------------------')

    #  4.a
    #       Create a Generator instance.
    generator = Generator()

    #  4.b
    #       The generator uses a GeneratorProfile item to set up a translation between the
Exemple #5
0
    # Fix the validation errors.

    # Add units to the variable 'b' in component 'validationErrors'.
    model.component('validationErrors').variable('b').setUnits('dimensionless')

    # Change the name of the variable 'iShouldBeNamed_c' to be 'c'.
    model.component('validationErrors').variable('iShouldBeNamed_c').setName('c')

    # Check again.
    validator.validateModel(model)
    print('The validator found {} issues.'.format(validator.issueCount()))

    # STEP 5
    # The Analyser will find errors in the logic or mathematical formulation of the model's equations,
    # so may return issues even when the model is valid (syntactically correct).
    analyser = Analyser()
    analyser.analyseModel(model)

    print('The analyser found {} issues.'.format(analyser.issueCount()))
    for i in range(0, analyser.issueCount()):
        issue = analyser.issue(i)
        print(issue.description())

    # STEP 6
    # Fix the analysis errors.  This may need several iterations of checking before all errors have been 
    # resolved.

    # Variable 'd' in component 'importedComponent' is initialised using variable 'e', but it is not a constant.
    model.component('importedComponent').variable('d').setInitialValue(22)

    analyser.analyseModel(model)
    print('------------------------------------------------------------')

    # STEP 6: We will introduce the Analyser class here so that its use as a debugging 
    #         tool can be demonstrated.  Of course, we know ahead of time that there
    #         is still a lot of connections to be created between the components, but
    #         an analyser can help us to find them.

    # A reminder: we're aiming for a potassium channel component which can accept two external
    # parameters - time, t (ms) and voltage, V (mV) - and use them to calculate a potassium 
    # current, i_K (microA_per_cm2). 
    # A utility function print_model has been provided to help you to see what's going 
    # on inside your model.

    #  6.a 
    #      Create an Analyser item and pass it the model for checking with the analyseModel function.
    analyser = Analyser()
    analyser.analyseModel(model)

    #  6.b 
    #      The analyser is similar to the Validator and keeps a record of issues it encounters.
    #      Retrieve these and print to the terminal, just as you've done for the validator.
    #      Expect messages related to un-computed variables.
    print_issues(analyser)

    #  end 6

    #  Even though all of the messages we see are 'variable not calculated' errors, we can divide
    #  them into different categories:
    #  - those variables which are constants whose value has not been set yet
    #  - those variables whose calculation depends on as-yet un-calculated variables
    #  - those variables which need to be connected to where their calculation happens and
Exemple #7
0
    def test_create_destroy(self):
        from libcellml import Analyser

        x = Analyser()
        del x
Exemple #8
0
    def test_coverage(self):
        from libcellml import Analyser
        from libcellml import AnalyserEquation
        from libcellml import AnalyserEquationAst
        from libcellml import AnalyserExternalVariable
        from libcellml import AnalyserModel
        from libcellml import AnalyserVariable
        from libcellml import Model
        from libcellml import Parser
        from test_resources import file_contents

        # Try to create an analyser equation/model/variable, something that is not allowed.

        self.assertRaises(AttributeError, AnalyserEquation)
        self.assertRaises(AttributeError, AnalyserModel)
        self.assertRaises(AttributeError, AnalyserVariable)

        # Analyse a model, so we can then do some coverage.

        p = Parser()
        m = p.parseModel(file_contents('generator/noble_model_1962/model.cellml'))

        a = Analyser()
        a.analyseModel(m)

        # Ensure coverage for Analyser.

        c = m.component(1)
        v0 = c.variable(0)

        aev = AnalyserExternalVariable(v0)

        self.assertTrue(a.addExternalVariable(aev))

        self.assertTrue(a.containsExternalVariable(aev))
        self.assertTrue(a.containsExternalVariable(m, c.name(), v0.name()))

        self.assertEqual(aev.variable().name(), a.externalVariable(0).variable().name())
        self.assertEqual(aev.variable().name(), a.externalVariable(m, c.name(), v0.name()).variable().name())

        v2 = c.variable(2)

        self.assertTrue(a.addExternalVariable(AnalyserExternalVariable(c.variable(1))))
        self.assertTrue(a.addExternalVariable(AnalyserExternalVariable(v2)))
        self.assertTrue(a.addExternalVariable(AnalyserExternalVariable(c.variable(3))))

        self.assertEqual(4, a.externalVariableCount())

        self.assertTrue(a.removeExternalVariable(1))
        self.assertTrue(a.removeExternalVariable(aev))
        self.assertTrue(a.removeExternalVariable(m, c.name(), v2.name()))

        a.removeAllExternalVariables()

        # Ensure coverage for AnalyserModel.

        am = a.model()

        self.assertTrue(am.isValid())

        self.assertFalse(am.hasExternalVariables())

        self.assertIsNotNone(am.voi())

        self.assertEqual(4, am.stateCount())
        self.assertIsNotNone(am.states())
        self.assertIsNotNone(am.state(3))

        self.assertEqual(17, am.variableCount())
        self.assertIsNotNone(am.variables())
        self.assertIsNotNone(am.variable(3))

        self.assertEqual(16, am.equationCount())
        self.assertIsNotNone(am.equations())
        self.assertIsNotNone(am.equation(3))

        self.assertFalse(am.needEqFunction())
        self.assertFalse(am.needNeqFunction())
        self.assertFalse(am.needLtFunction())
        self.assertFalse(am.needLeqFunction())
        self.assertFalse(am.needGtFunction())
        self.assertFalse(am.needGeqFunction())
        self.assertFalse(am.needAndFunction())
        self.assertFalse(am.needOrFunction())
        self.assertFalse(am.needXorFunction())
        self.assertFalse(am.needNotFunction())
        self.assertFalse(am.needMinFunction())
        self.assertFalse(am.needMaxFunction())
        self.assertFalse(am.needSecFunction())
        self.assertFalse(am.needCscFunction())
        self.assertFalse(am.needCotFunction())
        self.assertFalse(am.needSechFunction())
        self.assertFalse(am.needCschFunction())
        self.assertFalse(am.needCothFunction())
        self.assertFalse(am.needAsecFunction())
        self.assertFalse(am.needAcscFunction())
        self.assertFalse(am.needAcotFunction())
        self.assertFalse(am.needAsechFunction())
        self.assertFalse(am.needAcschFunction())
        self.assertFalse(am.needAcothFunction())

        self.assertTrue(am.areEquivalentVariables(am.voi().variable(), am.voi().variable()))

        # Ensure coverage for AnalyserVariable.

        av = am.variable(3)

        self.assertEqual(AnalyserVariable.Type.CONSTANT, av.type())
        self.assertEqual(3, av.index())
        self.assertIsNotNone(av.initialisingVariable())
        self.assertIsNotNone(av.variable())
        self.assertIsNone(av.equation())

        # Ensure coverage for AnalyserEquation.

        ae = am.equation(3)

        self.assertEqual(AnalyserEquation.Type.RATE, ae.type())
        self.assertIsNotNone(ae.ast())
        self.assertIsNotNone(ae.dependencies())
        self.assertTrue(ae.isStateRateBased())
        self.assertIsNotNone(ae.variable())

        # Ensure coverage for AnalyserEquationAst.

        aea = ae.ast()

        self.assertEqual(AnalyserEquationAst.Type.ASSIGNMENT, aea.type())
        self.assertEqual('', aea.value())
        self.assertIsNone(aea.variable())
        self.assertIsNone(aea.parent())
        self.assertIsNotNone(aea.leftChild())
        self.assertIsNotNone(aea.rightChild())

        aea.setType(AnalyserEquationAst.Type.EQ)
        aea.setValue(AnalyserTestCase.VALUE)
        aea.setVariable(av.variable())
        aea.setParent(aea)
        aea.setLeftChild(None)
        aea.setRightChild(None)

        self.assertEqual(AnalyserEquationAst.Type.EQ, aea.type())
        self.assertEqual(AnalyserTestCase.VALUE, aea.value())
        self.assertIsNotNone(aea.variable())
        self.assertIsNotNone(aea.parent())
        self.assertIsNone(aea.leftChild())
        self.assertIsNone(aea.rightChild())
Exemple #9
0
    #      As with the validator, the Analyser class is a diagnostic class which will check
    #      whether the mathematical representation is ready for simulation.  This involves
    #      making sure that variables are contained in equations, that integrated variables
    #      have initial conditions, and that there are no over- or under-constrained sets
    #      of equations.
    #      Since this model uses imports, the real mathematical model is hidden from the
    #      Analyser (just as it was from the validator).  The way around this is to
    #      use the Importer class to create a flat (ie: import-free) version of the same
    #      model.  If the flat model meets the analyser's checks, then the importing version
    #      will too.

    #  6.a
    #      Create an Analyser instance and pass in the model for analysis.
    #      Useful functions: Analyser.analyseModel(Model)
    analyser = Analyser()
    analyser.analyseModel(model)

    #  6.b
    #      Retrieve and print the issues from the analysis to the screen.  We expect to see
    #      messages related to un-computed variables, since anything which is imported is
    #      missing from this model.
    print_issues(analyser)

    print()
    #  6.c
    #      Create a flattened version of the model print it to the screen.
    #      Notice that any comments indicating that a component was an import have been
    #      removed as these components have been instantiated in the flattened model.
    #      Useful functions:
    #          - Importer.flattenModel(Model) will return a flattened copy.
Exemple #10
0
    # model they do not look into any of the imported items, so they can't check them.
    # In order to retain the import structure but be able to use the diagnostic tools, 
    # we can create a flattened copy of the model for testing.  This can be used to
    # identify mistakes in the unflattened model too.  

    # Create a Validator and Analyser and submit the original, unflattened model.
    # We don't expect either of these to report any issues.
    validator = Validator()
    validator.validateModel(original_model)

    print('Investigating the original model:')
    print(' - the validator found {} issues'.format(validator.issueCount()))
    for i in range(0, validator.issueCount()):
        print('    - {}'.format(validator.issue(i).description()))
    
    analyser = Analyser()
    analyser.analyseModel(original_model)
    print(' - the analyser found {} issues'.format(analyser.issueCount()))
    for i in range(0, analyser.issueCount()):
        print('    - {}'.format(analyser.issue(i).description()))
    print()

    # Create a flattened version for diagnostics.
    flat_model = importer.flattenModel(original_model)

    # Repeat the validation and analysis above on the flattened model.
    validator.validateModel(flat_model)
    print('Investigating the flattened model:')
    print(' - the validator found {} issues'.format(validator.issueCount()))
    for i in range(0, validator.issueCount()):
        print('    - {}'.format(validator.issue(i).description()))