Esempio n. 1
0
    def test_regime(self):
        # Signature: name(self, name=None)
        # Find a regime in the component by name
        # from nineml.abstraction.component.componentqueryer import
        # ComponentClassQueryer

        c = Dynamics(name='cl',
                     regimes=[
                          Regime('dX/dt=1/t',
                                 name='r1',
                                 transitions=On('X>X1', do=['X=X0'],
                                                to='r2')),
                          Regime('dX/dt=1/t',
                                 name='r2',
                                 transitions=On('X>X1', do=['X=X0'],
                                                to='r3')),
                          Regime('dX/dt=1/t',
                                 name='r3',
                                 transitions=On('X>X1', do=['X=X0'],
                                                to='r4')),
                          Regime('dX/dt=1/t',
                                 name='r4',
                                 transitions=On('X>X1', do=['X=X0'],
                                                to='r1'))])
        self.assertEqual(c.regime(name='r1').name, 'r1')
        self.assertEqual(c.regime(name='r2').name, 'r2')
        self.assertEqual(c.regime(name='r3').name, 'r3')
        self.assertEqual(c.regime(name='r4').name, 'r4')
Esempio n. 2
0
 def test_regime_aliases(self):
     a = Dynamics(
         name='a',
         aliases=[Alias('A', '4/t')],
         regimes=[
             Regime('dX/dt=1/t + A',
                    name='r1',
                    transitions=On('X>X1', do=['X=X0'], to='r2')),
             Regime('dX/dt=1/t + A',
                    name='r2',
                    transitions=On('X>X1', do=['X=X0'],
                                   to='r1'),
                    aliases=[Alias('A', '8 / t')])])
     self.assertEqual(a.regime('r2').alias('A'), Alias('A', '8 / t'))
     self.assertRaises(
         NineMLUsageError,
         Dynamics,
         name='a',
         regimes=[
             Regime('dX/dt=1/t + A',
                    name='r1',
                    transitions=On('X>X1', do=['X=X0'], to='r2')),
             Regime('dX/dt=1/t + A',
                    name='r2',
                    transitions=On('X>X1', do=['X=X0'],
                                   to='r1'),
                    aliases=[Alias('A', '8 / t')])])
     document = Document()
     a_xml = a.serialize(format='xml', version=1, document=document)
     b = Dynamics.unserialize(a_xml, format='xml', version=1,
                              document=Document(un.dimensionless.clone()))
     self.assertEqual(a, b,
                      "Dynamics with regime-specific alias failed xml "
                      "roundtrip:\n{}".format(a.find_mismatch(b)))
Esempio n. 3
0
    def test_transitions(self):

        c = Dynamics(name='cl',
                           regimes=[
                               Regime('dX1/dt=1/t',
                                      name='r1',
                                      transitions=[On('X>X1', do=['X=X0'],
                                                      to='r2'),
                                                   On('X>X2', do=['X=X0'],
                                                      to='r3'), ]
                                      ),
                               Regime('dX1/dt=1/t',
                                      name='r2',
                                      transitions=On('X>X1', do=['X=X0'],
                                                     to='r3'),),
                               Regime('dX2/dt=1/t',
                                      name='r3',
                                      transitions=[On('X>X1', do=['X=X0'],
                                                      to='r4'),
                                                   On('X>X2', do=['X=X0'],
                                                      to=None)]),
                               Regime('dX2/dt=1/t',
                                      name='r4',
                                      transitions=On('X>X1', do=['X=X0'],
                                                     to=None))])

        self.assertEquals(len(list(c.all_transitions())), 6)

        r1 = c.regime('r1')
        r2 = c.regime('r2')
        r3 = c.regime('r3')
        r4 = c.regime('r4')

        self.assertEquals(len(list(r1.transitions)), 2)
        self.assertEquals(len(list(r2.transitions)), 1)
        self.assertEquals(len(list(r3.transitions)), 2)
        self.assertEquals(len(list(r4.transitions)), 1)

        def target_regimes(regime):
            return unique_by_id(t.target_regime for t in regime.transitions)
        self.assertEquals(target_regimes(r1), [r2, r3])
        self.assertEquals(target_regimes(r2), [r3])
        self.assertEquals(target_regimes(r3), [r3, r4])
        self.assertEquals(target_regimes(r4), [r4])
Esempio n. 4
0
class TestUnitAssignment(TestCase):

    test_units = [old_div(un.mV, un.uF),
                  un.ms * un.C / un.um,
                  old_div(un.K ** 2, (un.uF * un.mV ** 2)),
                  old_div(un.uF ** 3, un.um),
                  old_div(un.cd, un.A)]

    test_unit_mapped = [old_div(un.mV, un.uF),
                        un.ms * un.C / un.um,
                        old_div(un.K ** 2, (un.uF * un.mV ** 2)),
                        old_div(un.uF ** 3, un.um),
                        old_div(un.cd, un.A)]

    def setUp(self):
        self.a = Dynamics(
            name='A',
            aliases=['A1 := P1 / P2', 'A2 := ARP2 + P3', 'A3 := P4 * P5',
                     'A4 := 1 / (P2 * P6) + ARP3', 'A5 := P7 * P8',
                     'A6 := P9/P10'],
            regimes=[
                Regime('dSV1/dt = -A1 / A2',
                       ('dSV2/dt = C1 * SV2 ** 2 + C2 * SV2 + C3 + SV3 + '
                        'ARP4 / P11'),
                       'dSV3/dt = P12*(SV2*P13 - SV3)',
                       name='R1')],
            state_variables=[StateVariable('SV1', dimension=un.dimensionless),
                             StateVariable('SV2', dimension=un.voltage),
                             StateVariable('SV3',
                                           dimension=old_div(un.voltage, un.time))],
            analog_ports=[AnalogReceivePort('ARP1', dimension=un.resistance),
                          AnalogReceivePort('ARP2', dimension=un.charge),
                          AnalogReceivePort('ARP3',
                                            dimension=un.conductanceDensity),
                          AnalogReceivePort('ARP4', dimension=un.current)],
            parameters=[Parameter('P1', dimension=un.voltage),
                        Parameter('P2', dimension=un.resistance),
                        Parameter('P3', dimension=un.charge),
                        Parameter('P4', dimension=old_div(un.length, un.current ** 2)),
                        Parameter('P5', dimension=old_div(un.current ** 2, un.length)),
                        Parameter('P6', dimension=un.length ** 2),
                        Parameter('P7', dimension=old_div(un.current, un.capacitance)),
                        Parameter('P8', dimension=un.time),
                        Parameter('P9',
                                  dimension=old_div(un.capacitance, un.length ** 2)),
                        Parameter('P10',
                                  dimension=old_div(un.conductance, un.length ** 2)),
                        Parameter('P11', dimension=un.capacitance),
                        Parameter('P12', dimension=un.per_time),
                        Parameter('P13', dimension=un.per_time)],
            constants=[Constant('C1', 0.04, units=(old_div(un.unitless,
                                                   (un.mV * un.ms)))),
                       Constant('C2', 5.0, units=old_div(un.unitless, un.ms)),
                       Constant('C3', 140.0, units=old_div(un.mV, un.ms))]
        )

    def test_dimension_to_units(self):
        test_units = {old_div(un.mV, un.uF): old_div(un.mV, un.nF),
                      old_div(un.mV, un.ms): old_div(un.mV, un.ms),
                      old_div(un.nA, un.pF): old_div(un.mV, un.ms),
                      old_div(un.cd, un.A): old_div(un.cd, un.nA),
                      old_div(un.A, un.uF): old_div(un.nA, un.nF),
                      old_div(un.nF, (un.m ** 2 * un.s)): old_div(un.S, un.cm ** 2)}
        TestUnitHandler1.clear_cache()
        for unit, unit_mapped in test_units.items():
            new_unit = TestUnitHandler1.dimension_to_units(unit.dimension)
            self.assertEqual(new_unit, unit_mapped,
                             "New unit mapped incorrectly {}->{} ({})"
                             .format(unit, new_unit, unit_mapped))

    def test_conversions(self):
        test_units = [old_div(un.mV, un.uF),
                      un.ms * un.C / un.um,
                      old_div(un.K ** 2, (un.uF * un.mV ** 2)),
                      old_div(un.uF ** 3, un.um),
                      old_div(un.cd, un.A)]
        for unit in test_units:
            scale, compound = TestUnitHandler1.dimension_to_units_compound(
                unit.dimension)
            new_scale = numpy.sum([p * u.power for u, p in compound])
            self.assertEqual(scale - new_scale, 0,
                              "Scale doesn't match in unit conversion of unit "
                              "'{}': orig={}, inverted={}".format(unit, scale,
                                                                  new_scale))
            x = numpy.sum(numpy.array([numpy.array(list(u.dimension)) * p
                                       for u, p in compound]), axis=0)
            self.assertEqual(list(unit.dimension), list(x),
                             "Dimensions do not match original conversion of "
                             "unit '{}'".format(unit))

    def test_scaling_and_assignment(self):
        handler1 = TestUnitHandler1(self.a)
        handler2 = NestUnitHandler(self.a)
        self.assertEqual(handler1.scale_alias('A2'),
                         (Expression('ARP2 + P3'), 'ms*nA'),
                         "Difference in scaled alias {} vs {}:\n{}"
                         .format(handler1.scale_alias('A2'),
                                 (Expression('ARP2 + P3'), 'ms*nA'),
                                 handler1.scale_alias('A2')[0].find_mismatch(
                                     Expression('ARP2 + P3'))))
        self.assertEqual(handler1.scale_alias('A4'),
                         (Expression('ARP3 + 100/(P2*P6)'), 'S/cm2'))
        self.assertEqual(handler1.scale_alias('A5'),
                         (Expression('P7 * P8'), 'mV'))
        self.assertEqual(handler1.scale_alias('A6'),
                         (Expression('1e-3 * P9/P10'), 'ms'))
        self.assertEqual(
            handler2.scale_time_derivative(self.a.regime('R1').element('SV2')),
            (Expression('C1 * SV2 ** 2 + C2 * SV2 + C3 + SV3 + '
                        'ARP4 / P11'), 'mV/ms'))
        self.assertEqual(
            handler2.scale_time_derivative(self.a.regime('R1').element('SV3')),
            (Expression('P12*(SV2*P13 - SV3)'), 'mV/ms^2'))
        self.assertEqual(handler1.assign_units_to_variable('P2'), '1/uS')
        self.assertEqual(handler1.assign_units_to_variable('P6'), 'um^2')

    def test_pq_round_trip(self):
        for unit in self.test_units:
            qty = Quantity(1.0, unit)
            pq_qty = TestUnitHandler1.to_pq_quantity(qty)
            new_qty = TestUnitHandler1.from_pq_quantity(pq_qty)
            self.assertEqual(qty.units.dimension, new_qty.units.dimension,
                             "Python-quantities roundtrip of '{}' changed "
                             "dimension".format(unit.name))
            new_power = int(math.log10(new_qty.value) + new_qty.units.power)
            self.assertEqual(unit.power, new_power,
                             "Python-quantities roundtrip of '{}' changed "
                             "scale ({} -> {})".format(unit.name, unit.power,
                                                       new_power))
Esempio n. 5
0
class TestUnitAssignment(TestCase):

    test_units = [
        old_div(un.mV, un.uF), un.ms * un.C / un.um,
        old_div(un.K**2, (un.uF * un.mV**2)),
        old_div(un.uF**3, un.um),
        old_div(un.cd, un.A)
    ]

    test_unit_mapped = [
        old_div(un.mV, un.uF), un.ms * un.C / un.um,
        old_div(un.K**2, (un.uF * un.mV**2)),
        old_div(un.uF**3, un.um),
        old_div(un.cd, un.A)
    ]

    def setUp(self):
        self.a = Dynamics(
            name='A',
            aliases=[
                'A1 := P1 / P2', 'A2 := ARP2 + P3', 'A3 := P4 * P5',
                'A4 := 1 / (P2 * P6) + ARP3', 'A5 := P7 * P8', 'A6 := P9/P10'
            ],
            regimes=[
                Regime('dSV1/dt = -A1 / A2',
                       ('dSV2/dt = C1 * SV2 ** 2 + C2 * SV2 + C3 + SV3 + '
                        'ARP4 / P11'),
                       'dSV3/dt = P12*(SV2*P13 - SV3)',
                       name='R1')
            ],
            state_variables=[
                StateVariable('SV1', dimension=un.dimensionless),
                StateVariable('SV2', dimension=un.voltage),
                StateVariable('SV3', dimension=old_div(un.voltage, un.time))
            ],
            analog_ports=[
                AnalogReceivePort('ARP1', dimension=un.resistance),
                AnalogReceivePort('ARP2', dimension=un.charge),
                AnalogReceivePort('ARP3', dimension=un.conductanceDensity),
                AnalogReceivePort('ARP4', dimension=un.current)
            ],
            parameters=[
                Parameter('P1', dimension=un.voltage),
                Parameter('P2', dimension=un.resistance),
                Parameter('P3', dimension=un.charge),
                Parameter('P4', dimension=old_div(un.length, un.current**2)),
                Parameter('P5', dimension=old_div(un.current**2, un.length)),
                Parameter('P6', dimension=un.length**2),
                Parameter('P7', dimension=old_div(un.current, un.capacitance)),
                Parameter('P8', dimension=un.time),
                Parameter('P9',
                          dimension=old_div(un.capacitance, un.length**2)),
                Parameter('P10',
                          dimension=old_div(un.conductance, un.length**2)),
                Parameter('P11', dimension=un.capacitance),
                Parameter('P12', dimension=un.per_time),
                Parameter('P13', dimension=un.per_time)
            ],
            constants=[
                Constant('C1',
                         0.04,
                         units=(old_div(un.unitless, (un.mV * un.ms)))),
                Constant('C2', 5.0, units=old_div(un.unitless, un.ms)),
                Constant('C3', 140.0, units=old_div(un.mV, un.ms))
            ])

    def test_dimension_to_units(self):
        test_units = {
            old_div(un.mV, un.uF): old_div(un.mV, un.nF),
            old_div(un.mV, un.ms): old_div(un.mV, un.ms),
            old_div(un.nA, un.pF): old_div(un.mV, un.ms),
            old_div(un.cd, un.A): old_div(un.cd, un.nA),
            old_div(un.A, un.uF): old_div(un.nA, un.nF),
            old_div(un.nF, (un.m**2 * un.s)): old_div(un.S, un.cm**2)
        }
        TestUnitHandler1.clear_cache()
        for unit, unit_mapped in test_units.items():
            new_unit = TestUnitHandler1.dimension_to_units(unit.dimension)
            self.assertEqual(
                new_unit, unit_mapped,
                "New unit mapped incorrectly {}->{} ({})".format(
                    unit, new_unit, unit_mapped))

    def test_conversions(self):
        test_units = [
            old_div(un.mV, un.uF), un.ms * un.C / un.um,
            old_div(un.K**2, (un.uF * un.mV**2)),
            old_div(un.uF**3, un.um),
            old_div(un.cd, un.A)
        ]
        for unit in test_units:
            scale, compound = TestUnitHandler1.dimension_to_units_compound(
                unit.dimension)
            new_scale = numpy.sum([p * u.power for u, p in compound])
            self.assertEqual(
                scale - new_scale, 0,
                "Scale doesn't match in unit conversion of unit "
                "'{}': orig={}, inverted={}".format(unit, scale, new_scale))
            x = numpy.sum(numpy.array(
                [numpy.array(list(u.dimension)) * p for u, p in compound]),
                          axis=0)
            self.assertEqual(
                list(unit.dimension), list(x),
                "Dimensions do not match original conversion of "
                "unit '{}'".format(unit))

    def test_scaling_and_assignment(self):
        handler1 = TestUnitHandler1(self.a)
        handler2 = NestUnitHandler(self.a)
        self.assertEqual(
            handler1.scale_alias('A2'), (Expression('ARP2 + P3'), 'ms*nA'),
            "Difference in scaled alias {} vs {}:\n{}".format(
                handler1.scale_alias('A2'), (Expression('ARP2 + P3'), 'ms*nA'),
                handler1.scale_alias('A2')[0].find_mismatch(
                    Expression('ARP2 + P3'))))
        self.assertEqual(handler1.scale_alias('A4'),
                         (Expression('ARP3 + 100/(P2*P6)'), 'S/cm2'))
        self.assertEqual(handler1.scale_alias('A5'),
                         (Expression('P7 * P8'), 'mV'))
        self.assertEqual(handler1.scale_alias('A6'),
                         (Expression('1e-3 * P9/P10'), 'ms'))
        self.assertEqual(
            handler2.scale_time_derivative(self.a.regime('R1').element('SV2')),
            (Expression('C1 * SV2 ** 2 + C2 * SV2 + C3 + SV3 + '
                        'ARP4 / P11'), 'mV/ms'))
        self.assertEqual(
            handler2.scale_time_derivative(self.a.regime('R1').element('SV3')),
            (Expression('P12*(SV2*P13 - SV3)'), 'mV/ms^2'))
        self.assertEqual(handler1.assign_units_to_variable('P2'), '1/uS')
        self.assertEqual(handler1.assign_units_to_variable('P6'), 'um^2')

    def test_pq_round_trip(self):
        for unit in self.test_units:
            qty = Quantity(1.0, unit)
            pq_qty = TestUnitHandler1.to_pq_quantity(qty)
            new_qty = TestUnitHandler1.from_pq_quantity(pq_qty)
            self.assertEqual(
                qty.units.dimension, new_qty.units.dimension,
                "Python-quantities roundtrip of '{}' changed "
                "dimension".format(unit.name))
            new_power = int(math.log10(new_qty.value) + new_qty.units.power)
            self.assertEqual(
                unit.power, new_power,
                "Python-quantities roundtrip of '{}' changed "
                "scale ({} -> {})".format(unit.name, unit.power, new_power))