Exemplo n.º 1
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)))
Exemplo n.º 2
0
    def test_is_alias(self):
        # Signature: name(cls, alias_string)
        # Returns True if the string could be an alias
        for expr_str, _ in Aliases:
            self.assertTrue(Alias.is_alias_str(expr_str))

        for expr_str, _ in TimeDerivatives:
            self.assertFalse(Alias.is_alias_str(expr_str))

        for expr_str, _ in Assignments:
            self.assertFalse(Alias.is_alias_str(expr_str))
Exemplo n.º 3
0
    def test_is_alias(self):
        # Signature: name(cls, alias_string)
                # Returns True if the string could be an alias
        for expr_str, _ in Aliases:
            self.assertTrue(Alias.is_alias_str(expr_str))

        for expr_str, _ in TimeDerivatives:
            self.assertFalse(Alias.is_alias_str(expr_str))

        for expr_str, _ in Assignments:
            self.assertFalse(Alias.is_alias_str(expr_str))
Exemplo n.º 4
0
 def test_sympify(self):
     a = sympy.Symbol('a')
     self.assertEqual(a, sympy.sympify(Alias('a', 'b + c')))
     self.assertEqual(a, sympy.sympify(AnalogReceivePort('a')))
     self.assertEqual(a, sympy.sympify(AnalogReducePort('a')))
     self.assertEqual(a, sympy.sympify(Constant('a', 1.0,
                                                units=un.unitless)))
Exemplo n.º 5
0
    def setUp(self):
        self.parameters = ['P4', 'P1', 'P3', 'P5', 'P2']
        self.state_variables = ['SV3', 'SV5', 'SV4', 'SV2', 'SV1']
        self.regimes = ['R2', 'R3', 'R1']
        self.time_derivatives = {
            'R1': ['SV5', 'SV1', 'SV4', 'SV3', 'SV2'],
            'R2': ['SV2', 'SV4'],
            'R3': ['SV4', 'SV2', 'SV1']
        }
        self.aliases = ['A4', 'A3', 'A1', 'A2']

        # Create a dynamics object with elements in a particular order
        self.d = Dynamics(
            name='d',
            parameters=[Parameter(p) for p in self.parameters],
            state_variables=[StateVariable(sv) for sv in self.state_variables],
            regimes=[
                Regime(name=r,
                       time_derivatives=[
                           TimeDerivative(td, '{}/t'.format(td))
                           for td in self.time_derivatives[r]
                       ],
                       transitions=[
                           OnCondition('SV1 > P5',
                                       target_regime_name=self.regimes[
                                           self.regimes.index(r) - 1])
                       ]) for r in self.regimes
            ],
            aliases=[
                Alias(a, 'P{}'.format(i + 1))
                for i, a in enumerate(self.aliases)
            ])
Exemplo n.º 6
0
    def test_get_rhs_substituted(self):
        # Signature: name(cls, expr_obj, namemap)
        # from nineml.abstraction.component.util import MathUtil

        e = Alias.from_str('a := b*c + b1 + e_*exp(-12*g) + '
                           'd/(e*sin(f + g/e))')

        rhs_sub = e.rhs_substituted({'b': 'B', 'e': 'E'})
        self.assertEqual(
            rhs_sub,
            sympy.sympify('B*c + b1 + e_*exp(-12*g) + d/(E*sin(f + g/E))',
                          locals={'E': sympy.Symbol('E')}))
Exemplo n.º 7
0
    def test_get_rhs_substituted(self):
        # Signature: name(cls, expr_obj, namemap)
        # from nineml.abstraction.component.util import MathUtil

        e = Alias.from_str('a := b*c + b1 + e_*exp(-12*g) + '
                           'd/(e*sin(f + g/e))')

        rhs_sub = e.rhs_substituted({'b': 'B', 'e': 'E'})
        self.assertEqual(
            rhs_sub,
            sympy.sympify('B*c + b1 + e_*exp(-12*g) + d/(E*sin(f + g/E))',
                          locals={'E': sympy.Symbol('E')}))
Exemplo n.º 8
0
    def test_get_prefixed_rhs_string(self):
        # Signature: name(cls, expr_obj, prefix='', exclude=None)
        # No Docstring
        # from nineml.abstraction.component.util import MathUtil

        e = Alias.from_str('a := b*c + d/(e_*sin(f+g/e_)) + b1 + '
                           'e_ / exp(12*g)')

        rhs_sub = e.rhs_suffixed(suffix='', prefix='U_', excludes=['c', 'e_'])
        self.assertEqual(
            rhs_sub,
            sympy.sympify('U_b*c + U_d/(e_*sin(U_f+U_g/e_)) + U_b1 +'
                          ' e_ / exp(12*U_g)'))
Exemplo n.º 9
0
    def test_get_prefixed_rhs_string(self):
        # Signature: name(cls, expr_obj, prefix='', exclude=None)
                # No Docstring
        # from nineml.abstraction.component.util import MathUtil

        e = Alias.from_str('a := b*c + d/(e_*sin(f+g/e_)) + b1 + '
                           'e_ / exp(12*g)')

        rhs_sub = e.rhs_suffixed(suffix='', prefix='U_', excludes=['c', 'e_'])
        self.assertEqual(
            rhs_sub,
            sympy.sympify('U_b*c + U_d/(e_*sin(U_f+U_g/e_)) + U_b1 +'
                          ' e_ / exp(12*U_g)')
        )
Exemplo n.º 10
0
    def setUp(self):

        self.a = Dynamics(name='A',
                          aliases=['A1:=P1', 'A2 := ARP2', 'A3 := SV1'],
                          regimes=[
                              Regime('dSV1/dt = -SV1 / (P2*t)',
                                     'dSV2/dt = A2/t + A3/t + ARP1/t',
                                     name='R1',
                                     transitions=On('input', 'SV1 = SV1 + 1'))
                          ],
                          analog_ports=[
                              AnalogReceivePort('ARP1'),
                              AnalogReceivePort('ARP2'),
                              AnalogSendPort('A1'),
                              AnalogSendPort('A2')
                          ],
                          parameters=['P1', 'P2'])

        self.b = Dynamics(name='B',
                          aliases=['A1:=P1', 'A2 := ARP1 + SV2', 'A3 := SV1'],
                          regimes=[
                              Regime(
                                  'dSV1/dt = -SV1 / (P2*t)',
                                  'dSV2/dt = SV1 / (ARP1*t) + SV2 / (P1*t)',
                                  transitions=[
                                      On('SV1 > P1', do=[OutputEvent('emit')]),
                                      On('spikein', do=[OutputEvent('emit')])
                                  ],
                                  aliases=[Alias('A1', 'P1 * 2')],
                                  name='R1',
                              ),
                              Regime(name='R2',
                                     transitions=On(
                                         'SV1 > 1',
                                         'SV1 = SV1 * random.normal()',
                                         to='R1'))
                          ],
                          analog_ports=[
                              AnalogReceivePort('ARP1'),
                              AnalogReceivePort('ARP2'),
                              AnalogSendPort('A1'),
                              AnalogSendPort('A2')
                          ],
                          parameters=['P1', 'P2'])
Exemplo n.º 11
0
 def test_remove(self):
     # Copy templates
     a = copy(self.a)
     b = copy(self.b)
     # Add missing items
     b.remove(b.alias('A4'))
     b.remove(b.state_variable('SV3'))
     b.regime('R1').remove(b.regime('R1').time_derivative('SV3'))
     b.regime('R1').on_event('spikein').remove(
         b.regime('R1').on_event('spikein').state_assignment('SV1'))
     b.regime('R2').remove(b.regime('R2').on_condition('SV3 < 0.001'))
     b.remove(b.analog_send_port('SV3'))
     b.remove(b.parameter('P3'))
     b.validate()
     self.assertEqual(
         a, b,
         "Did not transform 'b' into 'a':\n {}".format(a.find_mismatch(b)))
     b.add(Alias('A5', 'P1 + P2'))
     self.assertNotEqual(a, b, "Added Alias was not detected")
Exemplo n.º 12
0
 def test_equals_with_annotations_ns(self):
     a = Dynamics(name='D',
                  parameters=[Parameter('P', dimension=un.dimensionless)],
                  aliases=[Alias('A', 'P')])
     b = a.clone()
     c = a.clone()
     d = a.clone()
     e = a.clone()
     a.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 1.0)
     b.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 1.0)
     c.parameter('P').annotations.set(('annot1', 'dummy_ns'), 'val1', 2.0)
     e.parameter('P').annotations.set(('annot1', 'dummy_ns2'), 'val1', 1.0)
     self.assertTrue(a.equals(b, annotations_ns=['dummy_ns']))
     self.assertTrue(a.equals(c))
     self.assertFalse(a.equals(c, annotations_ns=['dummy_ns']))
     self.assertTrue(a.equals(d))
     self.assertFalse(a.equals(d, annotations_ns=['dummy_ns']))
     self.assertTrue(a.equals(e))
     self.assertFalse(a.equals(e, annotations_ns=['dummy_ns']))
Exemplo n.º 13
0
 def test_add(self):
     # Copy templates
     a = self.a.clone()
     b = self.b.clone()
     # Add missing items
     a.add(Alias('A4', 'SV1^3 + SV2^-3'))
     a.add(StateVariable('SV3'))
     a.regime('R1').add(TimeDerivative('SV3', '-SV3/t + P3/t'))
     a.regime('R1').on_event('spikein').add(StateAssignment('SV1', 'P1'))
     a.regime('R2').add(
         OnCondition('SV3 < 0.001',
                     target_regime_name='R2',
                     state_assignments=[StateAssignment('SV3', 1)]))
     a.add(Parameter('P3'))
     a.add(AnalogSendPort('SV3'))
     a.bind()
     a.validate()
     self.assertEqual(
         b, a,
         "Did not transform 'a' into 'b':\n {}".format(b.find_mismatch(a)))
Exemplo n.º 14
0
    def setUp(self):

        self.a = Dynamics(
            name='A',
            aliases=['A1:=P1 / P2', 'A2 := ARP2 + P3', 'A3 := P4 * P5'],
            regimes=[
                Regime('dSV1/dt = -A1 / A2',
                       aliases=[Alias('A1', 'P1 / P2 * 2')],
                       name='R1')
            ],
            analog_ports=[
                AnalogReceivePort('ARP1', dimension=un.resistance),
                AnalogReceivePort('ARP2', dimension=un.charge)
            ],
            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))
            ])
Exemplo n.º 15
0
    def test_alias(self):
        for expr_str, (exp_lhs, exp_rhs) in Aliases:
            alias = Alias.from_str(expr_str)

            self.assertEqual(alias.lhs, exp_lhs)
            self.assertEqual(str(alias.rhs), exp_rhs)
Exemplo n.º 16
0
    def test_alias(self):
        for expr_str, (exp_lhs, exp_rhs) in Aliases:
            alias = Alias.from_str(expr_str)

            self.assertEqual(alias.lhs, exp_lhs)
            self.assertEqual(str(alias.rhs), exp_rhs)
Exemplo n.º 17
0
    def transform_for_build(self, name, component_class, **kwargs):
        """
        Copies and transforms the component class to match the format of the
        simulator (overridden in derived class)

        Parameters
        ----------
        name : str
            The name of the transformed component class
        component_class : nineml.Dynamics
            The component class to be transformed
        """
        self._set_build_props(component_class, **kwargs)
        if not isinstance(component_class, WithSynapses):
            raise Pype9RuntimeError(
                "'component_class' must be a DynamicsWithSynapses object")
        # ---------------------------------------------------------------------
        # Clone original component class
        # ---------------------------------------------------------------------
        trfrm = component_class.dynamics.flatten()
        # ---------------------------------------------------------------------
        # Get the membrane voltage and convert it to 'v'
        # ---------------------------------------------------------------------
        try:
            name = kwargs['membrane_voltage']
            try:
                orig_v = component_class.element(
                    name, nineml_children=Dynamics.nineml_children)
            except KeyError:
                raise Pype9BuildError(
                    "Could not find specified membrane voltage '{}'"
                    .format(name))
        except KeyError:  # Guess voltage from its dimension if not supplied
            candidate_vs = [cv for cv in component_class.state_variables
                            if cv.dimension == un.voltage]
            if len(candidate_vs) == 0:
                candidate_vs = [
                    cv for cv in component_class.analog_receive_ports
                    if cv.dimension == un.voltage]
            if len(candidate_vs) == 1:
                orig_v = candidate_vs[0]
                logger.info("Guessing that '{}' is the membrane voltage"
                            .format(orig_v))
            elif len(candidate_vs) > 1:
                try:
                    orig_v = next(c for c in candidate_vs if c.name == 'v')
                    logger.info("Guessing that '{}' is the membrane voltage"
                                .format(orig_v))
                except StopIteration:
                    raise Pype9BuildError(
                        "Could not guess the membrane voltage, candidates: "
                        "'{}'" .format("', '".join(v.name
                                                   for v in candidate_vs)))
            else:
                orig_v = None
                logger.info(
                    "Can't find candidate for the membrane voltage in "
                    "state_variables '{}' or analog_receive_ports '{}', "
                    "treating '{}' as an \"artificial cell\"".format(
                        "', '".join(
                            sv.name for sv in component_class.state_variables),
                        "', '".join(
                            p.name
                            for p in component_class.analog_receive_ports),
                        component_class.name))
        if orig_v is not None:
            # Map voltage to hard-coded 'v' symbol
            if orig_v.name != 'v':
                trfrm.rename_symbol(orig_v.name, 'v')
                v = trfrm.state_variable('v')
                v.annotations.set((BUILD_TRANS, PYPE9_NS),
                                  TRANSFORM_SRC, orig_v)
            else:
                v = trfrm.state_variable('v')
            # Add annotations to the original and build models
            component_class.annotations.set((BUILD_TRANS, PYPE9_NS),
                                            MEMBRANE_VOLTAGE, orig_v.name)  # @IgnorePep8
            trfrm.annotations.set((BUILD_TRANS, PYPE9_NS),
                                  MEMBRANE_VOLTAGE, 'v')
            # Remove associated analog send port if present
            try:
                trfrm.remove(trfrm.analog_send_port('v'))
            except KeyError:
                pass
            # Need to convert to AnalogReceivePort if v is a StateVariable
            if isinstance(v, StateVariable):
                self._transform_full_component(trfrm, component_class, v,
                                               **kwargs)
                trfrm.annotations.set((BUILD_TRANS, PYPE9_NS),
                                      MECH_TYPE, FULL_CELL_MECH)
            else:
                raise NotImplementedError(
                    "Build sub-components is not supported in PyPe9 v0.1")
        else:
            trfrm.annotations.set((BUILD_TRANS, PYPE9_NS), MECH_TYPE,
                                  ARTIFICIAL_CELL_MECH)

        # -----------------------------------------------------------------
        # Insert dummy aliases for parameters (such as capacitance) that
        # now do not show up in the inferred interface for the transformed
        # class (i.e. that were only # present in the voltage time derivative)
        # -----------------------------------------------------------------

        # Infer required parameters
        inferred = DynamicsInterfaceInferer(trfrm)

        for parameter in list(trfrm.parameters):
            if parameter.name not in inferred.parameter_names:
                trfrm.add(Alias(parameter.name + '___dummy', parameter.name))

        # -----------------------------------------------------------------
        # Validate the transformed component class and construct prototype
        # -----------------------------------------------------------------

        trfrm.validate()
        trfrm_with_syn = DynamicsWithSynapses(
            name, trfrm, component_class.synapses,
            component_class.connection_parameter_sets)
        # Retun a prototype of the transformed class
        return trfrm_with_syn
Exemplo n.º 18
0
 def _transform_full_component(self, trfrm, component_class, v, **kwargs):
     # -----------------------------------------------------------------
     # Remove all analog send ports with 'current' dimension so they
     # don't get confused with the converted voltage time derivative
     # expression
     # -----------------------------------------------------------------
     for port in list(trfrm.analog_send_ports):
         if port.dimension == un.current:
             trfrm.remove(port)
     # -----------------------------------------------------------------
     # Insert membrane capacitance if not present
     # -----------------------------------------------------------------
     # Get or guess the location of the membrane capacitance
     try:
         name = kwargs['membrane_capacitance']
         try:
             orig_cm = component_class.parameter(name)
         except KeyError:
             raise Pype9BuildError(
                 "Could not find specified membrane capacitance '{}'"
                 .format(name))
         cm = trfrm.parameter(orig_cm.name)
     except KeyError:  # 'membrane_capacitance' was not specified
         candidate_cms = [ccm for ccm in component_class.parameters
                          if ccm.dimension == un.capacitance]
         if len(candidate_cms) == 1:
             orig_cm = candidate_cms[0]
             cm = trfrm.parameter(orig_cm.name)
             logger.info("Guessing that '{}' is the membrane capacitance"
                         .format(orig_cm))
         elif len(candidate_cms) > 1:
             raise Pype9BuildError(
                 "Could not guess the membrane capacitance, candidates:"
                 " '{}'".format("', '".join(candidate_cms)))
         else:
             cm = Parameter("cm___pype9", dimension=un.capacitance)
             trfrm.add(cm)
         cm.annotations.set((BUILD_TRANS, PYPE9_NS), TRANSFORM_SRC, None)
     trfrm.annotations.set((BUILD_TRANS, PYPE9_NS),
                           MEMBRANE_CAPACITANCE, cm.name)
     # -----------------------------------------------------------------
     # Replace membrane voltage equation with membrane current
     # -----------------------------------------------------------------
     # Determine the regimes in which each state variables has a time
     # derivative in
     has_td = defaultdict(list)
     # List which regimes need to be clamped to their last voltage
     # (as it has no time derivative)
     clamped_regimes = []
     # The voltage clamp equation where v_clamp is the last voltage
     # value and g_clamp_ is a large conductance
     clamp_i = sympy.sympify('g_clamp___pype9 * (v - v_clamp___pype9)')
     memb_is = []
     for regime in trfrm.regimes:
         # Add an appropriate membrane current
         try:
             # Convert the voltage time derivative into a membrane
             # current
             dvdt = regime.time_derivative(v.name)
             regime.remove(dvdt)
             i = -dvdt.rhs * cm
             memb_is.append(i)
         except KeyError:
             i = clamp_i
             clamped_regimes.append(regime)
         regime.add(Alias('i___pype9', i))
         # Record state vars that have a time deriv. in this regime
         for var in regime.time_derivative_variables:
             if var != 'v':
                 has_td[var].append(regime)
     # Pick the most popular membrane current to be the alias in
     # the global scope
     assert memb_is, "No regimes contain voltage time derivatives"
     memb_i = Alias('i___pype9', max(memb_is, key=memb_is.count))
     # Add membrane current along with a analog send port
     trfrm.add(memb_i)
     i_port = AnalogSendPort('i___pype9', dimension=un.current)
     i_port.annotations.set((BUILD_TRANS, PYPE9_NS), ION_SPECIES,
                            NONSPECIFIC_CURRENT)
     trfrm.add(i_port)
     # Remove membrane currents that match the membrane current in the
     # outer scope
     for regime in trfrm.regimes:
         if regime.alias('i___pype9') == memb_i:
             regime.remove(regime.alias('i___pype9'))
     # If there are clamped regimes add extra parameters and set the
     # voltage to clamp to in the regimes that trfrmition to them
     if clamped_regimes:
         trfrm.add(StateVariable('v_clamp___pype9', un.voltage))
         trfrm.add(Constant('g_clamp___pype9', 1e8, un.uS))
         for trans in trfrm.transitions:
             if trans.target_regime in clamped_regimes:
                 # Assign v_clamp_ to the value
                 try:
                     v_clamp_rhs = trans.state_assignment('v').rhs
                 except KeyError:
                     v_clamp_rhs = 'v'
                 trans.add(StateAssignment('v_clamp___pype9',
                                           v_clamp_rhs))
     # -----------------------------------------------------------------
     trfrm.annotations.set(
         (BUILD_TRANS, PYPE9_NS), NO_TIME_DERIVS,
         ','.join(['v'] + [sv for sv in trfrm.state_variable_names
                           if sv not in has_td]))
     trfrm.annotations.set((BUILD_TRANS, PYPE9_NS), NUM_TIME_DERIVS,
                           len(has_td))
     # -----------------------------------------------------------------
     # Remove the external input currents
     # -----------------------------------------------------------------
     # Analog receive or reduce ports that are of dimension current and
     # are purely additive to the membrane current and nothing else
     # (actually subtractive as it is outward current)
     try:
         ext_is = []
         for i_name in kwargs['external_currents']:
             try:
                 ext_i = trfrm.analog_receive_port(i_name)
             except KeyError:
                 try:
                     ext_i = trfrm.analog_reduce_port(i_name)
                 except KeyError:
                     raise Pype9BuildError(
                         "Did not find specified external current port "
                         "'{}'".format(i_name))
             if ext_i.dimension != un.current:
                 raise Pype9BuildError(
                     "Analog receive port matching specified external "
                     "current '{}' does not have 'current' dimension "
                     "({})".format(ext_i.name, ext_i.dimension))
             ext_is.append(ext_i)
     except KeyError:
         ext_is = []
         for port in chain(component_class.analog_receive_ports,
                           component_class.analog_reduce_ports):
             # Check to see if the receive/reduce port has current dimension
             if port.dimension != un.current:
                 continue
             # Check to see if the current appears in the membrane current
             # expression
             # FIXME: This test should check to to see if the port is
             #        additive to the membrane current and substitute all
             #        aliases.
             if port.name not in memb_i.rhs_symbol_names:
                 continue
             # Get the number of expressions the receive port appears in
             # an expression
             if len([e for e in component_class.all_expressions
                     if port.symbol in e.free_symbols]) > 1:
                 continue
             # If all those conditions are met guess that port is a external
             # current that can be removed (ports that don't meet these
             # conditions will have to be specified separately)
             ext_is.append(port)
         if ext_is:
             logger.info("Guessing '{}' are external currents to be removed"
                         .format(ext_is))
     trfrm.annotations.set((BUILD_TRANS, PYPE9_NS), EXTERNAL_CURRENTS,
                           ','.join(p.name for p in ext_is))
     # Remove external input current ports (as NEURON handles them)
     for ext_i in ext_is:
         trfrm.remove(ext_i)
         for expr in chain(trfrm.aliases, trfrm.all_time_derivatives()):
             expr.subs(ext_i, 0)
             expr.simplify()
Exemplo n.º 19
0
    event_send_ports=[EventSendPort('ESP1')],
    event_receive_ports=[EventReceivePort('ERP1')],
    parameters=['P1', 'P2', 'P3'])

dynC = Dynamics(
    name='dynC',
    aliases=['A1:=P1', 'A2 := ARP1 + SV2', 'A3 := SV1'],
    regimes=[
        Regime(
            'dSV1/dt = -SV1 / (P2*t)',
            'dSV2/dt = SV1 / (ARP1*t) + SV2 / (P1*t)',
            on_conditions=[
                OnCondition('SV1 > P1', output_events=[OutputEvent('ESP1')])
            ],
            on_events=[OnEvent('ERP1', output_events=[OutputEvent('ESP1')])],
            aliases=[Alias('A1', 'P1 * 2')],
            name='R1',
        ),
        Regime(name='R2', transitions=On('SV1 > 1', to='R1'))
    ],
    ports=[
        AnalogReceivePort('ARP1'),
        AnalogReceivePort('ARP2'),
        AnalogSendPort('A1'),
        AnalogSendPort('A2')
    ],
    parameters=['P1', 'P2'])

dynD = Dynamics(
    name='dynD',
    state_variables=[StateVariable('SV1', dimension=un.voltage)],
Exemplo n.º 20
0
    def setUp(self):

        self.a = Dynamics(
            name='A',
            aliases=[
                'A1:=P1 / P2', 'A2 := ARP2 + P3', 'A3 := A4 * P4 * P5',
                'A4:=P6 ** 2 + ADP1', 'A5:=SV1 * SV2 * P8',
                'A6:=SV1 * P1 / P8', 'A7:=A1 / P8'
            ],
            regimes=[
                Regime('dSV1/dt = -A1 / A2',
                       'dSV2/dt = -ADP1 / P7',
                       'dSV3/dt = -A1 * A3 / (A2 * C1)',
                       transitions=[
                           OnCondition('SV1 > 10', target_regime_name='R2')
                       ],
                       aliases=[
                           Alias('A1', 'P1 / P2 * 2'),
                           Alias('A5', 'SV1 * SV2 * P8 * 2')
                       ],
                       name='R1'),
                Regime('dSV1/dt = -A1 / A2',
                       'dSV3/dt = -A1 / A2 * A4',
                       transitions=[
                           OnCondition('C2 > A6',
                                       state_assignments=[
                                           StateAssignment('SV1', 'SV1 - A7')
                                       ],
                                       target_regime_name='R1')
                       ],
                       name='R2')
            ],
            analog_ports=[
                AnalogReceivePort('ARP1', dimension=un.resistance),
                AnalogReceivePort('ARP2', dimension=un.charge),
                AnalogReducePort('ADP1', dimension=un.dimensionless),
                AnalogSendPort('A5', 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.dimensionless),
                Parameter('P7', dimension=un.time),
                Parameter('P8', dimension=un.current)
            ],
            constants=[
                Constant('C1', value=10.0, units=un.unitless),
                Constant('C2', value=1.0, units=un.ohm)
            ])

        self.ref_substituted_a = Dynamics(
            name='substituted_A',
            aliases=['A5:=SV1 * SV2 * P8'],
            regimes=[
                Regime('dSV1/dt = -2 * (P1 / P2) / (ARP2 + P3)',
                       'dSV2/dt = -ADP1 / P7',
                       ('dSV3/dt = -2 * (P1 / P2) * ((P6 ** 2 + ADP1) * P4 * '
                        'P5) / ((ARP2 + P3) * C1)'),
                       transitions=[
                           OnCondition('SV1 > 10', target_regime_name='R2')
                       ],
                       aliases=[Alias('A5', 'SV1 * SV2 * P8 * 2')],
                       name='R1'),
                Regime('dSV1/dt = -(P1 / P2) / (ARP2 + P3)',
                       'dSV3/dt = -(P1 / P2) / (ARP2 + P3) * (P6 ** 2 + ADP1)',
                       transitions=[
                           OnCondition('C2 > (SV1 * P1 / P8)',
                                       state_assignments=[
                                           StateAssignment(
                                               'SV1', 'SV1 - (P1 / P2) / P8')
                                       ],
                                       target_regime_name='R1')
                       ],
                       name='R2')
            ],
            analog_ports=[
                AnalogReceivePort('ARP1', dimension=un.resistance),
                AnalogReceivePort('ARP2', dimension=un.charge),
                AnalogReducePort('ADP1', dimension=un.dimensionless),
                AnalogSendPort('A5', 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.dimensionless),
                Parameter('P7', dimension=un.time),
                Parameter('P8', dimension=un.current)
            ],
            constants=[
                Constant('C1', value=10.0, units=un.unitless),
                Constant('C2', value=1.0, units=un.ohm)
            ])
Exemplo n.º 21
0
    def test_aliases(self):
        # Signature: name
                # Forwarding function to self.dynamics.aliases

        # No Aliases:
        self.assertEqual(
            list(Dynamics(name='C1').aliases),
            []
        )

        # 2 Aliases
        C = Dynamics(name='C1', aliases=['G:= 0', 'H:=1'])
        self.assertEqual(len(list((C.aliases))), 2)
        self.assertEqual(
            set(C.alias_names), set(['G', 'H'])
        )

        C = Dynamics(name='C1', aliases=['G:= 0', 'H:=1', Alias('I', '3')])
        self.assertEqual(len(list((C.aliases))), 3)
        self.assertEqual(
            set(C.alias_names), set(['G', 'H', 'I'])
        )

        # Using DynamicsBlock Parameter:
        C = Dynamics(name='C1', aliases=['G:= 0', 'H:=1'])
        self.assertEqual(len(list((C.aliases))), 2)
        self.assertEqual(
            set(C.alias_names), set(['G', 'H'])
        )

        C = Dynamics(name='C1',
                           aliases=['G:= 0', 'H:=1', Alias('I', '3')])
        self.assertEqual(len(list((C.aliases))), 3)
        self.assertEqual(
            set(C.alias_names), set(['G', 'H', 'I'])
        )

        # Invalid Construction:
        # Invalid Valid String:
        self.assertRaises(
            NineMLUsageError,
            Dynamics, name='C1', aliases=['H=0']
        )

        # Duplicate Alias Names:
        Dynamics(name='C1', aliases=['H:=0', 'G:=1'])
        self.assertRaises(
            NineMLUsageError,
            Dynamics, name='C1', aliases=['H:=0', 'H:=1']
        )

        self.assertRaises(
            NineMLUsageError,
            Dynamics, name='C1', aliases=['H:=0', Alias('H', '1')]
        )

        # Self referential aliases:
        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1', aliases=['H := H +1'],
        )
        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1', aliases=['H := G + 1', 'G := H + 1'],
        )

        # Referencing none existent symbols:
        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1',
            aliases=['H := G + I'],
            parameters=['P1'],
        )

        # Invalid Names:
        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1', aliases=['H.2 := 0'],
        )

        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1', aliases=['2H := 0'],
        )

        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1', aliases=['E(H) := 0'],
        )

        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1', aliases=['tanh := 0'],
        )
        self.assertRaises(
            NineMLUsageError,
            Dynamics,
            name='C1', aliases=['t := 0'],
        )