def test_ports(self): # Signature: name # Return an iterator over all the port (Event & Analog) in the # component # from nineml.abstraction.component.componentqueryer import # ComponentClassQueryer c = Dynamics( name='Comp1', regimes=[ Regime(name='r1', transitions=[ On('spikeinput1', do=[]), On('spikeinput2', do=OutputEvent('ev_port2'), to='r2')]), Regime(name='r2', transitions=[ On('V > a', do=OutputEvent('ev_port2')), On('spikeinput3', do=OutputEvent('ev_port3'), to='r1')]) ], aliases=['A1:=0', 'C:=0'], analog_ports=[AnalogSendPort('A1'), AnalogReceivePort('B'), AnalogSendPort('C')] ) ports = list(list(c.ports)) port_names = [p.name for p in ports] self.assertEquals(len(port_names), 8) self.assertEquals(set(port_names), set(['A1', 'B', 'C', 'spikeinput1', 'spikeinput2', 'spikeinput3', 'ev_port2', 'ev_port3']) )
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')
def test_good_model(self): Dynamics(name='A', aliases=['A1:=P1 * SV2', 'A2 := ARP1 + SV2', 'A3 := SV1'], state_variables=[ StateVariable('SV1', dimension=un.voltage), StateVariable('SV2', dimension=un.current) ], regimes=[ Regime('dSV1/dt = -SV1 / P2', 'dSV2/dt = A3 / ARP2 + SV2 / P2', transitions=[ On('SV1 > P3', do=[OutputEvent('emit')]), On('spikein', do=[OutputEvent('emit')]) ], name='R1'), Regime(name='R2', transitions=On('(SV1 > C1) & (SV2 < P4)', to='R1')) ], analog_ports=[ AnalogReceivePort('ARP1', dimension=un.current), AnalogReceivePort('ARP2', dimension=(un.resistance * un.time)), AnalogSendPort('A1', dimension=un.voltage * un.current), AnalogSendPort('A2', dimension=un.current) ], parameters=[ Parameter('P1', dimension=un.voltage), Parameter('P2', dimension=un.time), Parameter('P3', dimension=un.voltage), Parameter('P4', dimension=un.current) ], constants=[Constant('C1', value=1.0, units=un.mV)])
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)))
def test_internally_inconsistent(self): self.assertRaises( NineMLDimensionError, Dynamics, name='A', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = SV1 + P1', name='R1'), ], parameters=[Parameter('P1', dimension=un.time)], ) self.assertRaises( NineMLDimensionError, Dynamics, name='A', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = SV1/t', transitions=[On('SV1 > P1', do=[OutputEvent('emit')])], name='R1'), ], parameters=[Parameter('P1', dimension=un.time)], ) self.assertRaises( NineMLDimensionError, Dynamics, name='A', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = SV1/t', transitions=[ On('SV1 > P1', do=[StateAssignment('SV1', 'SV1 + RP1')]) ], name='R1'), ], parameters=[Parameter('P1', dimension=un.voltage)], analog_ports=[AnalogReceivePort('RP1', dimension=un.time)], ) self.assertRaises( NineMLDimensionError, Dynamics, name='A', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = SV1/t', transitions=[ On('(SV1 > P1) & (P2 > 0)', do=[OutputEvent('emit')]) ], name='R1'), ], parameters=[ Parameter('P1', dimension=un.time), Parameter('P2', dimension=un.dimensionless) ], )
def test_parameters(self): # Signature: name # No Docstring # No parameters; nothing to infer c = Dynamics(name='cl') self.assertEqual(len(list(c.parameters)), 0) # Mismatch between inferred and actual parameters self.assertRaises( NineMLUsageError, Dynamics, name='cl', parameters=['a']) # Single parameter inference from an alias block c = Dynamics(name='cl', aliases=['A1:=a']) self.assertEqual(len(list(c.parameters)), 1) self.assertEqual(list(c.parameters)[0].name, 'a') # More complex inference: c = Dynamics(name='cl', aliases=['A1:=a+e', 'B1:=a+pi+b'], constants=[Constant('pi', 3.141592653589793)]) self.assertEqual(len(list(c.parameters)), 3) self.assertEqual(sorted([p.name for p in c.parameters]), ['a', 'b', 'e']) # From State Assignments and Differential Equations, and Conditionals c = Dynamics(name='cl', aliases=['A1:=a+e', 'B1:=a+pi+b'], regimes=Regime('dX/dt = (6 + c + sin(d))/t', 'dV/dt = 1.0/t', transitions=On('V>Vt', do=['X = X + f', 'V=0'])), constants=[Constant('pi', 3.1415926535)]) self.assertEqual(len(list(c.parameters)), 7) self.assertEqual( sorted([p.name for p in c.parameters]), ['Vt', 'a', 'b', 'c', 'd', 'e', 'f']) self.assertRaises( NineMLUsageError, Dynamics, name='cl', aliases=['A1:=a+e', 'B1:=a+pi+b'], regimes=Regime('dX/dt = 6 + c + sin(d)', 'dV/dt = 1.0', transitions=On('V>Vt', do=['X = X + f', 'V=0']) ), parameters=['a', 'b', 'c'])
def test_state_variables(self): # No parameters; nothing to infer c = Dynamics(name='cl') self.assertEqual(len(list(c.state_variables)), 0) # From State Assignments and Differential Equations, and Conditionals c = Dynamics( name='cl', aliases=['A1:=a+e', 'B1:=a+pi+b'], regimes=Regime('dX/dt = (6 + c + sin(d))/t', 'dV/dt = 1.0/t', transitions=On('V>Vt', do=['X = X + f', 'V=0']))) self.assertEqual( set(c.state_variable_names), set(['X', 'V'])) self.assertRaises( NineMLUsageError, Dynamics, name='cl', aliases=['A1:=a+e', 'B1:=a+pi+b'], regimes=Regime('dX/dt = 6 + c + sin(d)', 'dV/dt = 1.0', transitions=On('V>Vt', do=['X = X + f', 'V=0']) ), state_variables=['X']) # Shouldn't pick up 'e' as a parameter: self.assertRaises( NineMLUsageError, Dynamics, name='cl', aliases=['A1:=a+e', 'B1:=a+pi+b'], regimes=Regime('dX/dt = 6 + c + sin(d)', 'dV/dt = 1.0', transitions=On('V>Vt', do=['X = X + f', 'V=0']) ), state_variables=['X', 'V', 'Vt']) c = Dynamics(name='cl', regimes=[ Regime('dX1/dt=1/t', name='r1', transitions=On('X>X1', do=['X=X0'], to='r2')), 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')), Regime('dX2/dt=1/t', name='r4', transitions=On('X>X1', do=['X=X0'], to='r1'))]) self.assertEqual(set(c.state_variable_names), set(['X1', 'X2', 'X']))
def test_all_expressions(self): a = Dynamics( name='A', aliases=['A1:=P1 * SV2', 'A2 := ARP1 + SV2', 'A3 := SV1'], state_variables=[ StateVariable('SV1', dimension=un.voltage), StateVariable('SV2', dimension=un.current)], regimes=[ Regime( 'dSV1/dt = -SV1 / P2', 'dSV2/dt = A3 / ARP2 + SV2 / P2', transitions=[On('SV1 > P3', do=[OutputEvent('emit')]), On('spikein', do=[OutputEvent('emit')])], name='R1' ), Regime(name='R2', transitions=On('(SV1 > C1) & (SV2 < P4)', to='R1')) ], analog_ports=[AnalogReceivePort('ARP1', dimension=un.current), AnalogReceivePort('ARP2', dimension=(un.resistance * un.time)), AnalogSendPort('A1', dimension=un.voltage * un.current), AnalogSendPort('A2', dimension=un.current)], parameters=[Parameter('P1', dimension=un.voltage), Parameter('P2', dimension=un.time), Parameter('P3', dimension=un.voltage), Parameter('P4', dimension=un.current)], constants=[Constant('C1', value=1.0, units=un.mV)] ) self.assertEqual( set(a.all_expressions), set(( sympify('P1 * SV2'), sympify('ARP1 + SV2'), sympify('SV1'), sympify('-SV1 / P2'), sympify('-SV1 / P2'), sympify('A3 / ARP2 + SV2 / P2'), sympify('SV1 > P3'), sympify('(SV1 > C1) & (SV2 < P4)'))), "All expressions were not extracted from component class")
def test_mismatch_with_declared(self): self.assertRaises( NineMLDimensionError, Dynamics, name='A', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = SV1/t', name='R1'), ], analog_ports=[AnalogSendPort('SV1', dimension=un.current)], ) self.assertRaises( NineMLDimensionError, Dynamics, name='A', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = SV1 * P1', name='R1'), ], parameters=[Parameter('P1', dimension=un.time)], ) self.assertRaises( NineMLDimensionError, Dynamics, name='A', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = SV1/t', transitions=[ On('SV1 > P1', do=[StateAssignment('SV1', 'P2')]) ], name='R1'), ], parameters=[ Parameter('P1', dimension=un.voltage), Parameter('P2', dimension=un.time) ], )
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])
def setUp(self): self.a = Dynamics(name='A', 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')]) ], name='R1', ), Regime(name='R2', transitions=On('SV1 > 1', to='R1')) ], 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', 'A4 := SV1^3 + SV2^3' ], regimes=[ Regime( 'dSV1/dt = -SV1 / (P2*t)', 'dSV2/dt = SV1 / (ARP1*t) + SV2 / (P1*t)', 'dSV3/dt = -SV3/t + P3/t', transitions=[ On('SV1 > P1', do=[OutputEvent('emit')]), On('spikein', do=[ OutputEvent('emit'), StateAssignment('SV1', 'P1') ]) ], name='R1', ), Regime(name='R2', transitions=[ On('SV1 > 1', to='R1'), On('SV3 < 0.001', to='R2', do=[StateAssignment('SV3', 1)]) ]) ], analog_ports=[ AnalogReceivePort('ARP1'), AnalogReceivePort('ARP2'), AnalogSendPort('A1'), AnalogSendPort('A2'), AnalogSendPort('A3'), AnalogSendPort('SV3') ], parameters=['P1', 'P2', 'P3']) self.a_props = DynamicsProperties(name="AProps", definition=self.a, properties={ 'P1': 1, 'P2': 2 }) self.b_props = DynamicsProperties(name="BProps", definition=self.b, properties={ 'P1': 1, 'P2': 2, 'P3': 3 })
def test_basic_flattening(self): c = Dynamics(name='C', aliases=['C1:=cp1', 'C2 := cIn1', 'C3 := SV1'], regimes=[ Regime( 'dSV1/dt = -SV1/(cp2*t)', transitions=[ On('SV1>cp1', do=[OutputEvent('emit')]), On('spikein', do=[ OutputEvent('emit'), StateAssignment('SV1', '10') ]) ], name='r1', ), Regime(name='r2', transitions=On('SV1>1', to='r1')) ], analog_ports=[ AnalogReceivePort('cIn1'), AnalogReceivePort('cIn2'), AnalogSendPort('C1'), AnalogSendPort('C2') ], parameters=['cp1', 'cp2']) d = Dynamics(name='D', aliases=['D1:=dp1', 'D2 := dIn1', 'D3 := SV1'], regimes=[ Regime( 'dSV1/dt = -SV1/(dp2*t)', transitions=[ On('SV1>dp1', do=[OutputEvent('emit')]), On('spikein', do=[OutputEvent('emit')]) ], name='r1', ), Regime(name='r2', transitions=On('SV1>1', to='r1')) ], analog_ports=[ AnalogReceivePort('dIn1'), AnalogReceivePort('dIn2'), AnalogSendPort('D1'), AnalogSendPort('D2') ], parameters=['dp1', 'dp2']) e = MultiDynamics(name='E', sub_components={ 'a': c, 'b': d }, port_connections=[('a', 'C1', 'b', 'dIn1'), ('a', 'C2', 'b', 'dIn2')], port_exposures=[('a', 'cIn1', 'ARP1'), ('a', 'cIn2', 'ARP2'), ('a', 'spikein', 'ERP1'), ('a', 'emit', 'ESP1')]) # ===================================================================== # General properties # ===================================================================== self.assertEqual(e.name, 'E') self.assertEqual(set(e.parameter_names), set(['cp1__a', 'cp2__a', 'dp1__b', 'dp2__b'])) cp1 = e.parameter('cp1__a') self.assertEqual(cp1.dimension, un.dimensionless) self.assertEqual(set(e.analog_receive_port_names), set(['ARP1', 'ARP2'])) arp1 = e.analog_receive_port('ARP1') self.assertEqual(arp1.dimension, un.dimensionless) self.assertEqual(set(e.event_receive_port_names), set(['ERP1'])) self.assertEqual(set(e.event_send_port_names), set(['ESP1'])) self.assertEqual( set(e.alias_names), set([ 'C1__a', 'C2__a', 'C3__a', 'D1__b', 'D2__b', 'D3__b', 'cIn1__a', 'cIn2__a', 'dIn1__b', 'dIn2__b' ])) self.assertEqual(e.alias('C1__a').rhs, sympy.sympify('cp1__a')) self.assertIsInstance(e.alias('cIn1__a'), _ReceivePortExposureAlias) self.assertIsInstance(e.alias('dIn1__b'), _LocalAnalogReceivePortConnection) self.assertEqual(set(e.state_variable_names), set(['SV1__a', 'SV1__b'])) self.assertEqual( e.state_variable('SV1__a').dimension, un.dimensionless) # - Regimes and Transitions: self.assertEqual(set(e.regime_names), set(['r1___r1', 'r1___r2', 'r2___r1', 'r2___r2'])) # ===================================================================== # Regime a=1, b=2 # ===================================================================== r11 = e.regime('r1___r1') self.assertEqual(r11.num_on_conditions, 2) self.assertEqual(r11.num_on_events, 1) oe1 = r11.on_event('ERP1') self.assertEqual(oe1.num_output_events, 1) out1 = oe1.output_event('ESP1') self.assertEqual(out1.port, e.event_send_port('ESP1')) self.assertEqual(oe1.num_state_assignments, 1) self.assertEqual(oe1.state_assignment('SV1__a').rhs, 10) self.assertEqual(set(oe1.state_assignment_variables), set( ('SV1__a', ))) self.assertEqual(r11.num_on_conditions, 2) oc1 = r11.on_condition('SV1__a > cp1__a') self.assertEqual(oc1.num_output_events, 1) self.assertEqual(oc1.target_regime, r11) out1 = oc1.output_event('ESP1') self.assertEqual(out1.port, e.event_send_port('ESP1')) self.assertEqual(oc1.num_state_assignments, 0) oc2 = r11.on_condition('SV1__b > dp1__b') self.assertEqual(oc2.num_output_events, 0) self.assertEqual(oc2.num_state_assignments, 0) self.assertEqual(oc2.target_regime, r11) # ===================================================================== # Regime a=1, b=2 # ===================================================================== r12 = e.regime('r1___r2') self.assertEqual(r12.num_on_conditions, 2) oc1 = r12.on_condition('SV1__a > cp1__a') self.assertEqual(set(oc1.output_event_port_names), set(('ESP1', ))) self.assertEqual(oc1.target_regime, r12) oc2 = r12.on_condition('SV1__b > 1') self.assertEqual(oc2.num_output_events, 0) self.assertEqual(oc2.target_regime, r11) self.assertEqual(r12.num_on_events, 1) self.assertEqual( r12.on_event('ERP1').port.port, c.event_receive_port('spikein')) # ===================================================================== # Regime a=2, b=1 # ===================================================================== r21 = e.regime('r2___r1') self.assertEqual(r21.num_on_conditions, 2) oc1 = r21.on_condition('SV1__a > 1') self.assertEqual(oc1.num_output_events, 0) self.assertEqual(oc1.num_state_assignments, 0) self.assertEqual(oc1.target_regime, r11) oc2 = r21.on_condition('SV1__b > dp1__b') self.assertEqual(oc2.num_output_events, 0) self.assertEqual(oc2.num_state_assignments, 0) self.assertEqual(oc2.target_regime, r21) self.assertEqual(r21.num_on_events, 0) # ===================================================================== # Regime a=2, b=2 # ===================================================================== r22 = e.regime('r2___r2') self.assertEqual(r21.num_on_conditions, 2) oc1 = r22.on_condition('SV1__a > 1') self.assertEqual(oc1.num_output_events, 0) self.assertEqual(oc1.num_state_assignments, 0) self.assertEqual(oc1.target_regime, r12) oc2 = r22.on_condition('SV1__b > 1') self.assertEqual(oc2.num_output_events, 0) self.assertEqual(oc2.num_state_assignments, 0) self.assertEqual(oc2.target_regime, r21) # - Ports & Parameters: self.assertEqual(set(e.analog_receive_port_names), set(['ARP1', 'ARP2'])) self.assertEqual(set(e.parameter_names), set(['cp1__a', 'cp2__a', 'dp1__b', 'dp2__b'])) self.assertEqual(set(e.state_variable_names), set(['SV1__a', 'SV1__b']))
def setUp(self): self.pre_dynamics = Dynamics( name='PreDynamics', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = -SV1 / P1', transitions=[On('SV1 > P2', do=[OutputEvent('emit')])], name='R1'), ], parameters=[ Parameter('P1', dimension=un.time), Parameter('P2', dimension=un.voltage) ]) self.post_dynamics = Dynamics( name='PostDynamics', state_variables=[StateVariable('SV1', dimension=un.voltage)], regimes=[ Regime('dSV1/dt = -SV1 / P1 + ARP1 / P2', name='R1'), ], analog_ports=[AnalogReceivePort('ARP1', dimension=un.current)], parameters=[ Parameter('P1', dimension=un.time), Parameter('P2', dimension=un.capacitance) ]) self.response_dynamics = Dynamics( name='ResponseDynamics', state_variables=[StateVariable('SV1', dimension=un.current)], regimes=[ Regime('dSV1/dt = -SV1 / P1', transitions=[ On('receive', do=[StateAssignment('SV1', 'SV1 + P2')]) ], name='R1'), ], analog_ports=[AnalogSendPort('SV1', dimension=un.current)], parameters=[ Parameter('P1', dimension=un.time), Parameter('P2', dimension=un.current) ]) self.pre = Population(name="PrePopulation", size=1, cell=DynamicsProperties( name="PreDynamicsProps", definition=self.pre_dynamics, properties={ 'P1': 1 * un.ms, 'P2': -65 * un.mV })) self.post = Population(name="PostPopulation", size=1, cell=DynamicsProperties( name="PostDynamicsProps", definition=self.post_dynamics, properties={ 'P1': 1 * un.ms, 'P2': 1 * un.uF })) self.one_to_one = ConnectionRule( name="OneToOne", standard_library=(NINEML_NS + '/connectionrules/OneToOne')) self.projection = Projection( name="Projection", pre=self.pre, post=self.post, response=DynamicsProperties(name="ResponseProps", definition=self.response_dynamics, properties={ 'P1': 10 * un.ms, 'P2': 1 * un.nA }), connection_rule_properties=ConnectionRuleProperties( name="ConnectionRuleProps", definition=self.one_to_one), delay=1 * un.ms)
def test_event_send_receive_ports(self): # Signature: name(self) # Get the ``recv`` EventPorts # from nineml.abstraction.component.componentqueryer import # ComponentClassQueryer # Check inference of output event ports: c = Dynamics( name='Comp1', regimes=Regime( transitions=[ On('in_ev1', do=OutputEvent('ev_port1')), On('V < b', do=OutputEvent('ev_port1')), On('V < c', do=OutputEvent('ev_port2')), ] ), ) self.assertEquals(len(list(c.event_receive_ports)), 1) self.assertEquals((list(list(c.event_receive_ports))[0]).name, 'in_ev1') self.assertEquals(len(list(c.event_send_ports)), 2) self.assertEquals(set(c.event_send_port_names), set(['ev_port1', 'ev_port2'])) # Check inference of output event ports: c = Dynamics( name='Comp1', regimes=[ Regime(name='r1', transitions=[ On('V > a', do=OutputEvent('ev_port1'), to='r2'), On('in_ev1', do=OutputEvent('ev_port2'))]), Regime(name='r2', transitions=[ On('V > a', do=OutputEvent('ev_port2'), to='r1'), On('in_ev2', do=OutputEvent('ev_port3'))]) ] ) self.assertEquals(len(list(c.event_receive_ports)), 2) self.assertEquals(set(c.event_receive_port_names), set(['in_ev1', 'in_ev2'])) self.assertEquals(len(list(c.event_send_ports)), 3) self.assertEquals(set(c.event_send_port_names), set(['ev_port1', 'ev_port2', 'ev_port3'])) # Check inference of output event ports: c = Dynamics( name='Comp1', regimes=[ Regime(name='r1', transitions=[ On('spikeinput1', do=[]), On('spikeinput2', do=[ OutputEvent('ev_port1'), OutputEvent('ev_port2')], to='r2')]), Regime(name='r2', transitions=[ On('V > a', do=OutputEvent('ev_port2')), On('spikeinput3', do=OutputEvent('ev_port3'), to='r1')]) ] ) self.assertEquals(len(list(c.event_receive_ports)), 3) self.assertEquals(set(c.event_receive_port_names), set(['spikeinput1', 'spikeinput2', 'spikeinput3'])) self.assertEquals(len(list(c.event_send_ports)), 3) self.assertEquals(set(c.event_send_port_names), set(['ev_port1', 'ev_port2', 'ev_port3']))
def test_On(self): # Signature: name(trigger, do=None, to=None) # No Docstring # Test that we are correctly inferring OnEvents and OnConditions. self.assertEquals(type(On('V>0')), OnCondition) self.assertEquals(type(On('V<0')), OnCondition) self.assertEquals(type(On('(V<0) & (K>0)')), OnCondition) self.assertEquals(type(On('V==0')), OnCondition) self.assertEquals( type(On("q > 1 / (( 1 + mg_conc * eta * exp ( -1 * gamma*V)))")), OnCondition) self.assertEquals(type(On('SP0')), OnEvent) self.assertEquals(type(On('SP1')), OnEvent) # Check we can use 'do' with single and multiple values tr = On('V>0') self.assertEquals(len(list(tr.output_events)), 0) self.assertEquals(len(list(tr.state_assignments)), 0) tr = On('SP0') self.assertEquals(len(list(tr.output_events)), 0) self.assertEquals(len(list(tr.state_assignments)), 0) tr = On('V>0', do=OutputEvent('spike')) self.assertEquals(len(list(tr.output_events)), 1) self.assertEquals(len(list(tr.state_assignments)), 0) tr = On('SP0', do=OutputEvent('spike')) self.assertEquals(len(list(tr.output_events)), 1) self.assertEquals(len(list(tr.state_assignments)), 0) tr = On('V>0', do=[OutputEvent('spike')]) self.assertEquals(len(list(tr.output_events)), 1) self.assertEquals(len(list(tr.state_assignments)), 0) tr = On('SP0', do=[OutputEvent('spike')]) self.assertEquals(len(list(tr.output_events)), 1) self.assertEquals(len(list(tr.state_assignments)), 0) tr = On('V>0', do=['y=2', OutputEvent('spike'), 'x=1']) self.assertEquals(len(list(tr.output_events)), 1) self.assertEquals(len(list(tr.state_assignments)), 2) tr = On('SP0', do=['y=2', OutputEvent('spike'), 'x=1']) self.assertEquals(len(list(tr.output_events)), 1) self.assertEquals(len(list(tr.state_assignments)), 2)
def test_Constructor(self): d = Dynamics( name='D', aliases=['D1:=dp1', 'D2 := dIn1', 'D3 := SV1'], regimes=[ Regime('dSV1/dt = -SV1/(dp2*t)', name='r1', transitions=On('input', 'SV1=SV1+1'))], analog_ports=[RecvPort('dIn1'), SendPort('D1'), SendPort('D2')], parameters=['dp1', 'dp2'] ) c = Dynamics( name='C', aliases=['C1:=cp1', 'C2 := cIn1', 'C3 := SV1'], regimes=[ Regime( 'dSV1/dt = -SV1/(cp2*t)', transitions=[On('SV1>cp1', do=[OutputEvent('emit')]), On('spikein', do=[OutputEvent('emit')])], name='r1', ), Regime(name='r2', transitions=On('SV1>1', to='r1')) ], analog_ports=[RecvPort('cIn1'), RecvPort('cIn2'), SendPort('C1'), SendPort('C2')], parameters=['cp1', 'cp2'] ) # Test Cloner, no hierachy # Everything should be as before: c_clone = Cloner(as_class=Dynamics).visit(c) self.assertEqual(c_clone.name, 'C') self.assertEqual(set(c_clone.alias_names), set(['C1', 'C2', 'C3'])) # - Regimes and Transitions: self.assertEqual(set(c_clone.regime_names), set(['r1', 'r2'])) self.assertEqual(len(list(c_clone.regime('r1').on_events)), 1) self.assertEqual(len(list(c_clone.regime('r1').on_conditions)), 1) self.assertEqual(len(list(c_clone.regime('r2').on_events)), 0) self.assertEqual(len(list(c_clone.regime('r2').on_conditions)), 1) self.assertEqual(len(list(c_clone.regime('r2').on_conditions)), 1) # - Ports & Parameters: self.assertEqual( set(c_clone.analog_port_names), set(['cIn2', 'cIn1', 'C1', 'C2'])) self.assertEqual(set(c_clone.event_send_port_names), set(['emit'])) self.assertEqual(set(c_clone.event_receive_port_names), set(['spikein'])) self.assertEqual(set(c_clone.parameter_names), set(['cp1', 'cp2'])) self.assertEqual(set(c_clone.state_variable_names), set(['SV1'])) del c_clone # Test Cloner, 1 level of hierachy # Everything should be as before: b = MultiDynamics(name='B', sub_components={'c1': c, 'c2': c.clone()}, port_connections=[('c1', 'C1', 'c2', 'cIn1'), ('c2', 'emit', 'c1', 'spikein')], port_exposures=[('c2', 'cIn2', 'cIn2_c2'), ('c1', 'cIn1', 'cIn1_c1')]) b_clone = Cloner(as_class=Dynamics).visit(b)
def get_compound_component(): """Cannot yet be implemented in PyDSTool """ from nineml.abstraction.testing_utils import RecordValue from nineml.abstraction import Dynamics, Regime, On, OutputEvent, AnalogSendPort, AnalogReducePort emitter = Dynamics( name='EventEmitter', parameters=['cyclelength'], regimes=[ Regime(transitions=On('t > tchange + cyclelength', do=[OutputEvent('emit'), 'tchange=t'])), ]) ev_based_cc = Dynamics( name='EventBasedCurrentClass', parameters=['dur', 'i'], analog_ports=[AnalogSendPort('I')], regimes=[ Regime(transitions=[ On('inputevent', do=['I=i', 'tchange = t']), On('t>tchange + dur', do=['I=0', 'tchange=t']) ]) ]) pulsing_emitter = Dynamics(name='pulsing_cc', subnodes={ 'evs': emitter, 'cc': ev_based_cc }, portconnections=[('evs.emit', 'cc.inputevent')]) nrn = Dynamics( name='LeakyNeuron', parameters=['Cm', 'gL', 'E'], regimes=[ Regime('dV/dt = (iInj + (E-V)*gL )/Cm'), ], aliases=['iIn := iInj'], analog_ports=[ AnalogSendPort('V'), AnalogReducePort('iInj', operator='+') ], ) combined_comp = Dynamics(name='Comp1', subnodes={ 'nrn': nrn, 'cc1': pulsing_emitter, 'cc2': pulsing_emitter }, portconnections=[('cc1.cc.I', 'nrn.iInj'), ('cc2.cc.I', 'nrn.iInj')]) combined_comp = al.flattening.flatten(combined_comp) ## records = [ ## RecordValue(what='cc1_cc_I', tag='Current', label='Current Clamp 1'), ## RecordValue(what='cc2_cc_I', tag='Current', label='Current Clamp 2'), ## RecordValue(what='nrn_iIn', tag='Current', label='Total Input Current'), ## RecordValue(what='nrn_V', tag='Voltage', label='Neuron Voltage'), ## RecordValue(what='cc1_cc_tchange', tag='Tchange', label='tChange CC1'), ## RecordValue(what='cc2_cc_tchange', tag='Tchange', label='tChange CC2'), ## RecordValue(what='regime', tag='Regime', label='Regime'), ## ] parameters = al.flattening.ComponentFlattener.flatten_namespace_dict({ 'cc1.cc.i': 13.8, 'cc1.cc.dur': 10, 'cc1.evs.cyclelength': 30, 'cc2.cc.i': 20.8, 'cc2.cc.dur': 5.0, 'cc2.evs.cyclelength': 20, 'nrn.gL': 4.3, 'nrn.E': -70 }) return combined_comp, parameters
def test_regimes(self): c = Dynamics(name='cl', ) self.assertEqual(len(list(c.regimes)), 0) c = Dynamics(name='cl', regimes=Regime('dX/dt=1/t', name='r1', transitions=On('X>X1', do=['X = X0'], to=None))) self.assertEqual(len(list(c.regimes)), 1) 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(len(list(c.regimes)), 4) self.assertEqual( set(c.regime_names), set(['r1', 'r2', 'r3', 'r4']) ) 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(len(list(c.regimes)), 4) self.assertEqual( set([r.name for r in c.regimes]), set(['r1', 'r2', 'r3', 'r4']) ) # Duplicate Names: self.assertRaises( NineMLUsageError, Dynamics, name='cl', regimes=[ Regime('dX/dt=1/t', name='r', transitions=On('X>X1', do=['X=X0'])), Regime('dX/dt=1/t', name='r', transitions=On('X>X1', do=['X=X0'],)), ] )
def _strip(cls, string): return re.sub(r'\s+', ' ', string).strip() ref = Dynamics( name='dyn', aliases=['A1:=P1 * SV2', 'A2 := ARP1 + SV2', 'A3 := SV1', 'A4 := C2 * SV1'], state_variables=[ StateVariable('SV1', dimension=un.voltage), StateVariable('SV2', dimension=un.current)], regimes=[ Regime( 'dSV1/dt = -SV1 / P2', 'dSV2/dt = A3 / ARP2 + SV2 / P2', transitions=[On(Trigger('SV1 > P3'), do=[OutputEvent('ESP1')]), On('ERP1', do=[OutputEvent('ESP2')])], name='R1' ), Regime(name='R2', transitions=[ OnCondition('(SV1 > C1) & (SV2 < P4)', target_regime_name='R1')]) ], analog_ports=[AnalogReceivePort('ARP1', dimension=un.current), AnalogReceivePort('ARP2', dimension=(un.resistance * un.time)), AnalogSendPort('A1', dimension=un.voltage * un.current), AnalogSendPort('A2', dimension=un.current)], parameters=[Parameter('P1', dimension=un.voltage),
def test_event_ports(self): # Signature: name # No Docstring # Check inference of output event ports: c = Dynamics( name='Comp1', regimes=Regime( transitions=[ On('V > a', do=OutputEvent('ev_port1')), On('V > b', do=OutputEvent('ev_port1')), On('V < c', do=OutputEvent('ev_port2')), ] ), ) self.assertEquals(len(list(c.event_ports)), 2) # Check inference of output event ports: c = Dynamics( name='Comp1', regimes=[ Regime(name='r1', transitions=[ On('V > a', do=OutputEvent('ev_port1'), to='r2'), On('V < b', do=OutputEvent('ev_port2'))]), Regime(name='r2', transitions=[ On('V > a', do=OutputEvent('ev_port2'), to='r1'), On('V < b', do=OutputEvent('ev_port3'))]) ] ) self.assertEquals(len(list(c.event_ports)), 3) # Check inference of output event ports: c = Dynamics( name='Comp1', regimes=[ Regime(name='r1', transitions=[ On('spikeinput1', do=[]), On('spikeinput2', do=OutputEvent('ev_port2'), to='r2')]), Regime(name='r2', transitions=[ On('V > a', do=OutputEvent('ev_port2')), On('spikeinput3', do=OutputEvent('ev_port3'), to='r1')]) ] ) self.assertEquals(len(list(c.event_ports)), 5)
properties={'P1': 81.0 * un.unitless}) dynA = Dynamics(name='dynA', aliases=[ 'A1:=P1 * SV2', 'A2 := ARP1 + SV2', 'A3 := SV1', 'A4 := C2 * SV1' ], state_variables=[ StateVariable('SV1', dimension=un.voltage), StateVariable('SV2', dimension=un.current) ], regimes=[ Regime('dSV1/dt = -SV1 / P2', 'dSV2/dt = A3 / ARP2 + SV2 / P2', transitions=[ On(Trigger('SV1 > P3'), do=[OutputEvent('ESP1')]), On('ERP1', do=[OutputEvent('ESP2')]) ], name='R1'), Regime(name='R2', transitions=[ OnCondition('(SV1 > C1) & (SV2 < P4)', target_regime_name='R1') ]) ], analog_ports=[ AnalogReceivePort('ARP1', dimension=un.current), AnalogReceivePort('ARP2', dimension=(un.resistance * un.time)), AnalogSendPort('A1', dimension=un.voltage * un.current), AnalogSendPort('A2', dimension=un.current)
sim, options = get_simulator( ("--plot-figure", "plot a figure with the given filename")) init_logging(None, debug=True) sim.setup(timestep=0.1, min_delay=0.1, max_delay=2.0) iaf = Dynamics( name="iaf", regimes=[ Regime( name="subthresholdregime", time_derivatives=["dV/dt = ( gl*( vrest - V ) + ISyn)/(cm)"], transitions=On( "V > vthresh", do=["tspike = t", "V = vreset", OutputEvent('spikeoutput')], to="refractoryregime"), ), Regime( name="refractoryregime", transitions=[ On("t >= tspike + taurefrac", to="subthresholdregime") ], ) ], state_variables=[ StateVariable('V', un.voltage), StateVariable('tspike', un.time), ], analog_ports=[