def test_state_variables(self): # No parameters; nothing to infer c = ComponentClass(name='cl') self.assertEqual(len(list(c.state_variables)), 0) # Mismatch between inferred and actual statevariables self.assertRaises(NineMLRuntimeError, ComponentClass, name='cl', state_variables=['a']) # From State Assignments and Differential Equations, and Conditionals c = ComponentClass( name='cl', aliases=['A:=a+e', 'B:=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']))) self.assertEqual(set(c.state_variables_map.keys()), set(['X', 'V'])) self.assertRaises(NineMLRuntimeError, ComponentClass, name='cl', aliases=['A:=a+e', 'B:=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(NineMLRuntimeError, ComponentClass, name='cl', aliases=['A:=a+e', 'B:=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 = ComponentClass( name='cl', dynamicsblock=DynamicsBlock(regimes=[ Regime('dX1/dt=0', name='r1', transitions=On('X>X1', do=['X=X0'], to='r2')), Regime('dX1/dt=0', name='r2', transitions=On('X>X1', do=['X=X0'], to='r3')), Regime('dX2/dt=0', name='r3', transitions=On('X>X1', do=['X=X0'], to='r4')), Regime('dX2/dt=0', name='r4', transitions=On('X>X1', do=['X=X0'], to='r1')), ])) self.assertEqual(set(c.state_variables_map.keys()), set(['X1', 'X2', 'X']))
def test_event_ports(self): # Signature: name # No Docstring # Check inference of output event ports: c = ComponentClass( 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 = ComponentClass(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 = ComponentClass(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)
def functest(self): cc = ComponentClass( name='PulsingCurrentClamp', parameters=['i', 'cycle_length'], analog_ports=[SendPort('I')], regimes=[ Regime( name='off', transitions=On('t > tchange + cycle_length', do=['tchange = t', 'I = 0'], to='on'), ), Regime( name='on', transitions=On('t > tchange + cycle_length', do=['tchange = t', 'I = i'], to='off'), ), ]) nrn = ComponentClass( name='LeakyNeuron', parameters=['Cm', 'gL', 'E'], regimes=[ Regime('dV/dt = (iInj + (E-V)*gL )/Cm'), ], analog_ports=[SendPort('V'), ReducePort('iInj', reduce_op='+')], ) combined_comp = ComponentClass(name='Comp1', subnodes={ 'nrn': nrn, 'cc1': cc }, portconnections=[('cc1.I', 'nrn.iInj')]) records = [ RecordValue(what='cc1_I', tag='Current', label='Current Clamp 1'), RecordValue(what='nrn_V', tag='Voltage', label='Neuron Voltage'), RecordValue(what='cc1_tchange', tag='Tchange', label='tChange'), RecordValue(what='regime', tag='Regime', label='Regime'), ] parameters = { 'cc1_i': 13.8, 'cc1_cycle_length': 20, 'nrn_gL': 2, 'nrn_E': -70 } results = std_pynn_simulation(test_component=combined_comp, parameters=parameters, initial_values={}, synapse_components=[], records=records, plot=True)
def test_get_fully_qualified_port_connections(self): # Signature: name(self) # Used by the flattening code. # # This method returns a d list of tuples of the # the fully-qualified port connections # from nineml.abstraction_layer.component.componentqueryer import ComponentQueryer # Signature: name(self) # Get the namespace address of this component from nineml.abstraction_layer import ComponentClass, SendPort, RecvPort from nineml.abstraction_layer import NamespaceAddress d = ComponentClass(name="D", aliases=["A:=1", "B:=2"], analog_ports=[SendPort("A"), SendPort("B")]) e = ComponentClass(name="E", analog_ports=[RecvPort("C")]) f = ComponentClass(name="F", analog_ports=[RecvPort("D")]) g = ComponentClass(name="G", analog_ports=[RecvPort("E")]) b = ComponentClass(name="B", subnodes={"d": d, "e": e}, portconnections=[("d.A", "e.C")]) c = ComponentClass( name="C", aliases=["G:=-1"], analog_ports=[SendPort("G")], subnodes={"f": f, "g": g}, portconnections=[("G", "f.D")], ) a = ComponentClass( name="A", subnodes={"b": b, "c": c}, analog_ports=[RecvPort("F")], portconnections=[("b.d.A", "F")] ) bNew = a.get_subnode("b") cNew = a.get_subnode("c") # dNew = a.get_subnode('b.d') # eNew = a.get_subnode('b.e') # fNew = a.get_subnode('c.f') # gNew = a.get_subnode('c.g') self.assertEquals( list(a.query.get_fully_qualified_port_connections()), [(NamespaceAddress("b.d.A"), NamespaceAddress("F"))] ) self.assertEquals( list(bNew.query.get_fully_qualified_port_connections()), [(NamespaceAddress("b.d.A"), NamespaceAddress("b.e.C"))], ) self.assertEquals( list(cNew.query.get_fully_qualified_port_connections()), [(NamespaceAddress("c.G"), NamespaceAddress("c.f.D"))], )
def test1(self): cc = ComponentClass( name='SimpleCurrentClamp', parameters=['i'], analog_ports=[SendPort('I')], aliases='I:=i', ) nrn = ComponentClass( name='LeakyNeuron', parameters=['Cm', 'gL', 'E'], regimes=[ Regime('dV/dt = (iInj + (E-V)*gL )/Cm'), ], analog_ports=[SendPort('V'), ReducePort('iInj', reduce_op='+')], ) combined_comp = ComponentClass(name='Comp1', subnodes={ 'nrn': nrn, 'cc1': cc }, portconnections=[('cc1.I', 'nrn.iInj')]) records = [ RecordValue(what='cc1_I', tag='Current', label='Current Clamp 1'), RecordValue(what='nrn_V', tag='Voltage', label='Neuron Voltage'), ] res = std_pynn_simulation(test_component=combined_comp, parameters={ 'cc1_i': 13.8, 'nrn_gL': 2, 'nrn_E': -70 }, initial_values={}, synapse_components=[], records=records, plot=False) t, records = res self.assertAlmostEqual(records['cc1_I'][t > 10].mean(), 13.8) self.assertAlmostEqual(records['cc1_I'][t > 10].std(), 0.0) self.assertAlmostEqual(records['nrn_V'][t > 10].mean(), -63.1) self.assertAlmostEqual(records['nrn_V'][t > 10].std(), 0.0)
def test_parameters(self): # Signature: name # No Docstring # No parameters; nothing to infer c = ComponentClass(name='cl') self.assertEqual(len(list(c.parameters)), 0) # Mismatch between inferred and actual parameters self.assertRaises(NineMLRuntimeError, ComponentClass, name='cl', parameters=['a']) # Single parameter inference from an alias block c = ComponentClass(name='cl', aliases=['A:=a']) self.assertEqual(len(list(c.parameters)), 1) self.assertEqual(list(c.parameters)[0].name, 'a') # More complex inference: c = ComponentClass(name='cl', aliases=['A:=a+e', 'B:=a+pi+b']) 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 = ComponentClass( name='cl', aliases=['A:=a+e', 'B:=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']))) 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(NineMLRuntimeError, ComponentClass, name='cl', aliases=['A:=a+e', 'B:=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_get_subns_addr(self): # Signature: name(self, component_name) # Returns the address of a subcomponent at this address. # # For example: # # >>> a = NamespaceAddress('level1.level2.level3') # >>> a.get_subns_addr('subcomponent') # NameSpaceAddress: '/level1/level2/level3/subcomponent/' # from nineml.abstraction_layer.component.namespaceaddress import NamespaceAddress from nineml.abstraction_layer import ComponentClass from nineml.abstraction_layer import NamespaceAddress d = ComponentClass(name='D',) e = ComponentClass(name='E') f = ComponentClass(name='F') g = ComponentClass(name='G') b = ComponentClass(name='B', subnodes={'atD': d, 'atE': e}) c = ComponentClass(name='C', subnodes={'atF': f, 'atG': g}) a = ComponentClass(name='A', subnodes={'atB': b, 'atC': c}) # Construction of the objects causes cloning to happen: # Therefore we test by looking up and checking that there # are the correct component names: bNew = a.get_subnode('atB') cNew = a.get_subnode('atC') dNew = a.get_subnode('atB.atD') eNew = a.get_subnode('atB.atE') fNew = a.get_subnode('atC.atF') gNew = a.get_subnode('atC.atG') self.assertEquals( gNew.get_node_addr().get_subns_addr('MyObject1'), NamespaceAddress('atC.atG.MyObject1') ) self.assertEquals( eNew.get_node_addr().get_subns_addr('MyObject2'), NamespaceAddress('atB.atE.MyObject2') ) self.assertEquals( bNew.get_node_addr().get_subns_addr('MyObject3'), NamespaceAddress('atB.MyObject3') )
def test_aliases_map(self): # Signature: name # Forwarding function to self.dynamics.alias_map self.assertEqual(ComponentClass(name='C1').aliases_map, {}) c1 = ComponentClass(name='C1', aliases=['A:=3']) self.assertEqual(c1.aliases_map['A'].rhs_as_python_func()(), 3) self.assertEqual(len(c1.aliases_map), 1) c2 = ComponentClass(name='C1', aliases=['A:=3', 'B:=5']) self.assertEqual(c2.aliases_map['A'].rhs_as_python_func()(), 3) self.assertEqual(c2.aliases_map['B'].rhs_as_python_func()(), 5) self.assertEqual(len(c2.aliases_map), 2) c3 = ComponentClass( name='C1', dynamicsblock=DynamicsBlock(aliases=['C:=13', 'Z:=15'])) self.assertEqual(c3.aliases_map['C'].rhs_as_python_func()(), 13) self.assertEqual(c3.aliases_map['Z'].rhs_as_python_func()(), 15) self.assertEqual(len(c3.aliases_map), 2)
def duplicate_port_name_event_analog(self): # Check different names are OK: ComponentClass(name='C1', aliases=['A:=1'], event_ports=[EventReceivePort('A')], analog_ports=[AnalogSendPort('A')]) self.assertRaises(NineMLRuntimeError, ComponentClass, name='C1', aliases=['A:=1'], event_ports=[EventReceivePort('A')], analog_ports=[AnalogSendPort('A')])
def test_transitions(self): c = ComponentClass( name='cl', dynamicsblock=DynamicsBlock(regimes=[ Regime('dX1/dt=0', name='r1', transitions=[ On('X>X1', do=['X=X0'], to='r2'), On('X>X2', do=['X=X0'], to='r3'), ]), Regime( 'dX1/dt=0', name='r2', transitions=On('X>X1', do=['X=X0'], to='r3'), ), Regime('dX2/dt=0', name='r3', transitions=[ On('X>X1', do=['X=X0'], to='r4'), On('X>X2', do=['X=X0'], to=None) ]), Regime('dX2/dt=0', name='r4', transitions=On('X>X1', do=['X=X0'], to=None)), ])) self.assertEquals(len(list(c.transitions)), 6) r_map = c.regimes_map r1 = r_map['r1'] r2 = r_map['r2'] r3 = r_map['r3'] r4 = r_map['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) target_regimes = lambda r: set( [tr.target_regime for tr in r.transitions]) self.assertEquals(target_regimes(r1), set([r2, r3])) self.assertEquals(target_regimes(r2), set([r3])) self.assertEquals(target_regimes(r3), set([r3, r4])) self.assertEquals(target_regimes(r4), set([r4]))
def get_component(): off_regime = Regime(name="off_regime", time_derivatives=[ "dRon/dt = -Ron/Rtau", "dRoff/dt = -Beta*Roff", ], transitions=On('spikeoutput', do=[ "t_off = t+Cdur", "r0 = r0*exp(-Beta*(t - t0))", "t0 = t", "Ron = Ron +r0", "Roff = Roff - r0" ], to="on_regime")) on_regime = Regime( name="on_regime", time_derivatives=[ "dRon/dt = (weight*Rinf - Ron)/Rtau", "dRoff/dt = -Beta*Roff", ], transitions=[ On('spikeoutput', do="t_off = t+Cdur" ), # Extend duration if input spike arrives while on On( "t_off>t", # What to do when its time to turn off do=[ "r0 = weight*Rinf + (r0 - weight*Rinf)*exp(-(t - t0)/Rtau)", "t0 = t", "Ron = Ron - r0", "Roff = Roff - r0" ], to='off_regime') ]) analog_ports = [ RecvPort("weight"), RecvPort("V"), SendPort("Isyn"), SendPort("gsyn") ] c1 = ComponentClass( "AMPA", regimes=[off_regime, on_regime], analog_ports=analog_ports, aliases=["g := (on + off)", "Isyn := g*(E-V)", "gsyn := g"]) return c1
def test_backsub_all(self): # Check the aliases: # ====================== # c2 = ComponentClass(name='C1', aliases=['A:=1+2', 'B:=5*A', 'C:=B+2']) self.assertEqual(c2.aliases_map['A'].rhs_as_python_func()(), 3) # This should assert, because its not yet back-subbed c2.backsub_all() self.assertEqual(c2.aliases_map['B'].rhs_as_python_func()(), 15) # Check the ordering: self.assertEqual(c2.aliases_map['C'].rhs_as_python_func()(), ((5 * (3)) + 2)) # ====================== # # Check the equations: # ====================== # # warnings.warn('Tests not implemented') pass
def test_accept_visitor(self): # Signature: name(self, visitor, **kwargs) # |VISITATION| # Check the Component is forwarding arguments: class TestVisitor(object): def visit(self, obj, **kwargs): return obj.accept_visitor(self, **kwargs) def visit_componentclass(self, component, **kwargs): return kwargs c = ComponentClass(name='MyComponent') v = TestVisitor() self.assertEqual(v.visit(c, kwarg1='Hello', kwarg2='Hello2'), { 'kwarg1': 'Hello', 'kwarg2': 'Hello2' })
def test_get_node_addr(self): # Signature: name(self) # Get the namespace address of this component d = ComponentClass(name='D', ) e = ComponentClass(name='E') f = ComponentClass(name='F') g = ComponentClass(name='G') b = ComponentClass(name='B', subnodes={'d': d, 'e': e}) c = ComponentClass(name='C', subnodes={'f': f, 'g': g}) a = ComponentClass(name='A', subnodes={'b': b, 'c': c}) # Construction of the objects causes cloning to happen: # Therefore we test by looking up and checking that there # are the correct component names: bNew = a.get_subnode('b') cNew = a.get_subnode('c') dNew = a.get_subnode('b.d') eNew = a.get_subnode('b.e') fNew = a.get_subnode('c.f') gNew = a.get_subnode('c.g') self.assertEquals(a.get_node_addr(), NamespaceAddress.create_root()) self.assertEquals(bNew.get_node_addr(), NamespaceAddress('b')) self.assertEquals(cNew.get_node_addr(), NamespaceAddress('c')) self.assertEquals(dNew.get_node_addr(), NamespaceAddress('b.d')) self.assertEquals(eNew.get_node_addr(), NamespaceAddress('b.e')) self.assertEquals(fNew.get_node_addr(), NamespaceAddress('c.f')) self.assertEquals(gNew.get_node_addr(), NamespaceAddress('c.g')) self.assertEquals(a.name, 'A') self.assertEquals(bNew.name, 'B') self.assertEquals(cNew.name, 'C') self.assertEquals(dNew.name, 'D') self.assertEquals(eNew.name, 'E') self.assertEquals(fNew.name, 'F') self.assertEquals(gNew.name, 'G')
def test_Constructor(self): d = ComponentClass( name='D', aliases=['D1:=dp1', 'D2 := dIn1', 'D3 := SV1'], regimes=[ Regime('dSV1/dt = -SV1/dp2', name='r1', transitions=On('input', 'SV1=SV1+1'))], analog_ports=[RecvPort('dIn1'), SendPort('D1'), SendPort('D2')], parameters=['dp1', 'dp2'] ) c = ComponentClass( name='C', aliases=['C1:=cp1', 'C2 := cIn1', 'C3 := SV1'], regimes=[ Regime( 'dSV1/dt = -SV1/cp2', 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 = DynamicsClonerVisitorPrefixNamespace().visit(c) self.assertEqual(c_clone.name, 'C') self.assertEqual(set(c_clone.aliases_map.keys()), set(['C1', 'C2', 'C3'])) # - Regimes and Transitions: self.assertEqual(set(c_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(len(list(c_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(c_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(c_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(c_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(c_clone.regimes_map['r2'].on_conditions)), 1) # - Ports & Parameters: self.assertEqual( set(c_clone.query.analog_ports_map.keys()), set(['cIn2', 'cIn1', 'C1', 'C2'])) self.assertEqual(set(c_clone.query.event_ports_map.keys()), set(['spikein', 'emit'])) self.assertEqual(set(c_clone.query.parameters_map.keys()), set(['cp1', 'cp2'])) self.assertEqual(set(c_clone.state_variables_map.keys()), set(['SV1'])) del c_clone # Test Cloner, 1 level of hierachy # Everything should be as before: b = ComponentClass(name='B', subnodes={'c1': c, 'c2': c}, portconnections=[('c1.C1', 'c2.cIn1'), ('c2.emit', 'c1.spikein'), ]) b_clone = DynamicsClonerVisitorPrefixNamespace().visit(b) c1_clone = b_clone.get_subnode('c1') c2_clone = b_clone.get_subnode('c2') self.assertEqual(c1_clone.name, 'C') self.assertEqual(c2_clone.name, 'C') self.assertEqual(set(c1_clone.aliases_map.keys()), set(['c1_C1', 'c1_C2', 'c1_C3'])) self.assertEqual(set(c2_clone.aliases_map.keys()), set(['c2_C1', 'c2_C2', 'c2_C3'])) # - Regimes and Transitions: self.assertEqual(set(c1_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(len(list(c1_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(c1_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(c1_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(c1_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(c1_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(set(c2_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(len(list(c2_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(c2_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(c2_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(c2_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(c2_clone.regimes_map['r2'].on_conditions)), 1) # - Ports & Parameters: self.assertEqual( set(c1_clone.query.analog_ports_map.keys()), set(['c1_cIn1', 'c1_cIn2', 'c1_C1', 'c1_C2'])) self.assertEqual( set(c2_clone.query.analog_ports_map.keys()), set(['c2_cIn1', 'c2_cIn2', 'c2_C1', 'c2_C2'])) self.assertEqual(set(c1_clone.query.event_ports_map.keys()), set(['c1_spikein', 'c1_emit'])) self.assertEqual(set(c2_clone.query.event_ports_map.keys()), set(['c2_spikein', 'c2_emit'])) self.assertEqual( set(c1_clone.query.parameters_map.keys()), set(['c1_cp1', 'c1_cp2'])) self.assertEqual( set(c2_clone.query.parameters_map.keys()), set(['c2_cp1', 'c2_cp2'])) self.assertEqual( set(c1_clone.state_variables_map.keys()), set(['c1_SV1'])) self.assertEqual( set(c2_clone.state_variables_map.keys()), set(['c2_SV1'])) # - Port Connections: self.assertEqual( set(b_clone.portconnections), set([(NSA('c1.c1_C1'), NSA('c2.c2_cIn1')), (NSA('c2.c2_emit'), NSA('c1.c1_spikein'))]) ) del b_clone del c1_clone del c2_clone # Two Levels of nesting: a = ComponentClass(name='A', subnodes={'b1': b, 'b2': b, 'c3': c}, portconnections=[ ('b1.c1.emit', 'c3.spikein'), ('c3.C2', 'b1.c2.cIn2') ] ) a_clone = DynamicsClonerVisitorPrefixNamespace().visit(a) b1_clone = a_clone.get_subnode('b1') b2_clone = a_clone.get_subnode('b2') b1c1_clone = a_clone.get_subnode('b1.c1') b1c2_clone = a_clone.get_subnode('b1.c2') b2c1_clone = a_clone.get_subnode('b2.c1') b2c2_clone = a_clone.get_subnode('b2.c2') c3_clone = a_clone.get_subnode('c3') clones = [b1_clone, b2_clone, b1c1_clone, b1c2_clone, b2c1_clone, b2c2_clone, c3_clone, ] # Check for duplicates: self.assertEquals(len(clones), len(set(clones))) # Names: self.assertEqual(b1_clone.name, 'B') self.assertEqual(b2_clone.name, 'B') self.assertEqual(b1c1_clone.name, 'C') self.assertEqual(b1c2_clone.name, 'C') self.assertEqual(c3_clone.name, 'C') self.assertEqual(b2c1_clone.name, 'C') self.assertEqual(b2c2_clone.name, 'C') # Aliases: self.assertEqual(set(b1_clone.aliases_map.keys()), set([])) self.assertEqual(set(b2_clone.aliases_map.keys()), set([])) self.assertEqual(set(b1c1_clone.aliases_map.keys()), set( ['b1_c1_C1', 'b1_c1_C2', 'b1_c1_C3'])) self.assertEqual(set(b1c2_clone.aliases_map.keys()), set( ['b1_c2_C1', 'b1_c2_C2', 'b1_c2_C3'])) self.assertEqual(set(b2c1_clone.aliases_map.keys()), set( ['b2_c1_C1', 'b2_c1_C2', 'b2_c1_C3'])) self.assertEqual(set(b2c2_clone.aliases_map.keys()), set( ['b2_c2_C1', 'b2_c2_C2', 'b2_c2_C3'])) self.assertEqual(set(c3_clone.aliases_map.keys()), set(['c3_C1', 'c3_C2', 'c3_C3'])) # Regimes: self.assertEqual(set(b1_clone.regimes_map.keys()), set([])) self.assertEqual(set(b2_clone.regimes_map.keys()), set([])) self.assertEqual(set(b1c1_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(set(b1c2_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(set(b2c1_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(set(b2c2_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(set(c3_clone.regimes_map.keys()), set(['r1', 'r2'])) self.assertEqual(len(list(b1c1_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(b1c1_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(b1c1_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(b1c1_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(b1c1_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(b1c2_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(b1c2_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(b1c2_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(b1c2_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(b1c2_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(b2c1_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(b2c1_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(b2c1_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(b2c1_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(b2c1_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(b2c2_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(b2c2_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(b2c2_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(b2c2_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(b2c2_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(c3_clone.regimes_map['r1'].on_events)), 1) self.assertEqual(len(list(c3_clone.regimes_map['r1'].on_conditions)), 1) self.assertEqual(len(list(c3_clone.regimes_map['r2'].on_events)), 0) self.assertEqual(len(list(c3_clone.regimes_map['r2'].on_conditions)), 1) self.assertEqual(len(list(c3_clone.regimes_map['r2'].on_conditions)), 1) # Ports, params and state-vars: # c1: self.assertEqual(set(b1c1_clone.query.analog_ports_map.keys()), set( ['b1_c1_cIn1', 'b1_c1_cIn2', 'b1_c1_C1', 'b1_c1_C2'])) self.assertEqual( set(b1c1_clone.query.event_ports_map.keys()), set(['b1_c1_spikein', 'b1_c1_emit'])) self.assertEqual( set(b1c1_clone.query.parameters_map.keys()), set(['b1_c1_cp1', 'b1_c1_cp2'])) self.assertEqual(set(b1c1_clone.state_variables_map.keys()), set(['b1_c1_SV1'])) self.assertEqual(set(b1c2_clone.query.analog_ports_map.keys()), set( ['b1_c2_cIn1', 'b1_c2_cIn2', 'b1_c2_C1', 'b1_c2_C2'])) self.assertEqual( set(b1c2_clone.query.event_ports_map.keys()), set(['b1_c2_spikein', 'b1_c2_emit'])) self.assertEqual( set(b1c2_clone.query.parameters_map.keys()), set(['b1_c2_cp1', 'b1_c2_cp2'])) self.assertEqual(set(b1c2_clone.state_variables_map.keys()), set(['b1_c2_SV1'])) self.assertEqual(set(b2c1_clone.query.analog_ports_map.keys()), set(['b2_c1_cIn1', 'b2_c1_cIn2', 'b2_c1_C1', 'b2_c1_C2'])) self.assertEqual( set(b2c1_clone.query.event_ports_map.keys()), set(['b2_c1_spikein', 'b2_c1_emit'])) self.assertEqual( set(b2c1_clone.query.parameters_map.keys()), set(['b2_c1_cp1', 'b2_c1_cp2'])) self.assertEqual(set(b2c1_clone.state_variables_map.keys()), set(['b2_c1_SV1'])) self.assertEqual(set(b2c2_clone.query.analog_ports_map.keys()), set( ['b2_c2_cIn1', 'b2_c2_cIn2', 'b2_c2_C1', 'b2_c2_C2'])) self.assertEqual( set(b2c2_clone.query.event_ports_map.keys()), set(['b2_c2_spikein', 'b2_c2_emit'])) self.assertEqual( set(b2c2_clone.query.parameters_map.keys()), set(['b2_c2_cp1', 'b2_c2_cp2'])) self.assertEqual(set(b2c2_clone.state_variables_map.keys()), set(['b2_c2_SV1'])) self.assertEqual(set(c3_clone.query.analog_ports_map.keys()), set( ['c3_cIn1', 'c3_cIn2', 'c3_C1', 'c3_C2'])) self.assertEqual( set(c3_clone.query.event_ports_map.keys()), set(['c3_spikein', 'c3_emit'])) self.assertEqual( set(c3_clone.query.parameters_map.keys()), set(['c3_cp1', 'c3_cp2'])) self.assertEqual(set(c3_clone.state_variables_map.keys()), set(['c3_SV1'])) self.assertEqual(set(b1_clone.query.analog_ports_map.keys()), set([])) self.assertEqual(set(b1_clone.query.event_ports_map.keys()), set([])) self.assertEqual(set(b1_clone.query.parameters_map.keys()), set([])) self.assertEqual(set(b1_clone.state_variables_map.keys()), set([])) self.assertEqual(set(b2_clone.query.analog_ports_map.keys()), set([])) self.assertEqual(set(b2_clone.query.event_ports_map.keys()), set([])) self.assertEqual(set(b2_clone.query.parameters_map.keys()), set([])) self.assertEqual(set(b2_clone.state_variables_map.keys()), set([])) # Port Connections self.assertEqual( set(b1_clone.portconnections), set([ (NSA('c1.b1_c1_C1'), NSA('c2.b1_c2_cIn1')), (NSA('c2.b1_c2_emit'), NSA('c1.b1_c1_spikein')), ]) ) self.assertEqual( set(b2_clone.portconnections), set([ (NSA('c1.b2_c1_C1'), NSA('c2.b2_c2_cIn1')), (NSA('c2.b2_c2_emit'), NSA('c1.b2_c1_spikein')), ]) ) self.assertEqual( set(a_clone.portconnections), set([ (NSA('b1.c1.b1_c1_emit'), NSA('c3.c3_spikein')), (NSA('c3.c3_C2'), NSA('b1.c2.b1_c2_cIn2')), ]) )
def test_regimes(self): c = ComponentClass(name='cl', ) self.assertEqual(len(list(c.regimes)), 0) c = ComponentClass(name='cl', regimes=Regime('dX/dt=0', name='r1', transitions=On('X>X1', do=['X = X0'], to=None))) self.assertEqual(len(list(c.regimes)), 1) c = ComponentClass(name='cl', regimes=[ Regime('dX/dt=0', name='r1', transitions=On('X>X1', do=['X=X0'], to='r2')), Regime('dX/dt=0', name='r2', transitions=On('X>X1', do=['X=X0'], to='r3')), Regime('dX/dt=0', name='r3', transitions=On('X>X1', do=['X=X0'], to='r4')), Regime('dX/dt=0', name='r4', transitions=On('X>X1', do=['X=X0'], to='r1')), ]) self.assertEqual(len(list(c.regimes)), 4) self.assertEqual(set(c.regimes_map.keys()), set(['r1', 'r2', 'r3', 'r4'])) c = ComponentClass( name='cl', dynamicsblock=DynamicsBlock(regimes=[ Regime('dX/dt=0', name='r1', transitions=On('X>X1', do=['X=X0'], to='r2')), Regime('dX/dt=0', name='r2', transitions=On('X>X1', do=['X=X0'], to='r3')), Regime('dX/dt=0', name='r3', transitions=On('X>X1', do=['X=X0'], to='r4')), Regime('dX/dt=0', 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(NineMLRuntimeError, ComponentClass, name='cl', regimes=[ Regime('dX/dt=0', name='r', transitions=On('X>X1', do=['X=X0'])), Regime('dX/dt=0', name='r', transitions=On( 'X>X1', do=['X=X0'], )), ])
def test_recurse_all_components(self): # Signature: name # Returns an iterator over this component and all subcomponents from nineml.abstraction_layer import ComponentClass d = ComponentClass(name="D") e = ComponentClass(name="E") f = ComponentClass(name="F") g = ComponentClass(name="G") b = ComponentClass(name="B") b.insert_subnode(namespace="d", subnode=d) b.insert_subnode(namespace="e", subnode=e) c = ComponentClass(name="C") c.insert_subnode(namespace="f", subnode=f) c.insert_subnode(namespace="g", subnode=g) a = ComponentClass(name="A") a.insert_subnode(namespace="b", subnode=b) a.insert_subnode(namespace="c", subnode=c) # Construction of the objects causes cloning to happen: # Therefore we test by looking up and checking that there # are the correct component names: bNew = a.get_subnode("b") cNew = a.get_subnode("c") dNew = a.get_subnode("b.d") eNew = a.get_subnode("b.e") fNew = a.get_subnode("c.f") gNew = a.get_subnode("c.g") self.assertEquals(set(a.query.recurse_all_components), set([a, bNew, cNew, dNew, eNew, fNew, gNew])) self.assertEquals(set(bNew.query.recurse_all_components), set([bNew, dNew, eNew])) self.assertEquals(set(cNew.query.recurse_all_components), set([cNew, fNew, gNew])) self.assertEquals(set(dNew.query.recurse_all_components), set([dNew])) self.assertEquals(set(eNew.query.recurse_all_components), set([eNew])) self.assertEquals(set(fNew.query.recurse_all_components), set([fNew])) self.assertEquals(set(gNew.query.recurse_all_components), set([gNew]))
def test_insert_subnode(self): # Signature: name(self, subnode, namespace) # Insert a subnode into this component # # # :param subnode: An object of type ``ComponentClass``. # :param namespace: A `string` specifying the name of the component in # this components namespace. # # :raises: ``NineMLRuntimeException`` if there is already a subcomponent at # the same namespace location # # .. note:: # # This method will clone the subnode. d = ComponentClass(name='D') e = ComponentClass(name='E') f = ComponentClass(name='F') g = ComponentClass(name='G') b = ComponentClass(name='B') b.insert_subnode(namespace='d', subnode=d) b.insert_subnode(namespace='e', subnode=e) c = ComponentClass(name='C') c.insert_subnode(namespace='f', subnode=f) c.insert_subnode(namespace='g', subnode=g) a = ComponentClass(name='A') a.insert_subnode(namespace='b', subnode=b) a.insert_subnode(namespace='c', subnode=c) # Construction of the objects causes cloning to happen: # Therefore we test by looking up and checking that there # are the correct component names: bNew = a.get_subnode('b') cNew = a.get_subnode('c') dNew = a.get_subnode('b.d') eNew = a.get_subnode('b.e') fNew = a.get_subnode('c.f') gNew = a.get_subnode('c.g') self.assertEquals(a.get_node_addr(), NamespaceAddress.create_root()) self.assertEquals(bNew.get_node_addr(), NamespaceAddress('b')) self.assertEquals(cNew.get_node_addr(), NamespaceAddress('c')) self.assertEquals(dNew.get_node_addr(), NamespaceAddress('b.d')) self.assertEquals(eNew.get_node_addr(), NamespaceAddress('b.e')) self.assertEquals(fNew.get_node_addr(), NamespaceAddress('c.f')) self.assertEquals(gNew.get_node_addr(), NamespaceAddress('c.g')) self.assertEquals(a.name, 'A') self.assertEquals(bNew.name, 'B') self.assertEquals(cNew.name, 'C') self.assertEquals(dNew.name, 'D') self.assertEquals(eNew.name, 'E') self.assertEquals(fNew.name, 'F') self.assertEquals(gNew.name, 'G') self.assertRaises(NineMLRuntimeError, a.get_subnode, 'x') self.assertRaises(NineMLRuntimeError, a.get_subnode, 'a.') self.assertRaises(NineMLRuntimeError, a.get_subnode, 'a.X') self.assertRaises(NineMLRuntimeError, a.get_subnode, 'a.b.') self.assertRaises(NineMLRuntimeError, a.get_subnode, 'a.b.X') # Adding to the same namespace twice: d1 = ComponentClass(name='D1') d2 = ComponentClass(name='D2') a = ComponentClass(name='B') a.insert_subnode(namespace='d', subnode=d1) self.assertRaises(NineMLRuntimeError, a.insert_subnode, namespace='d', subnode=d2)
def test_aliases(self): # Signature: name # Forwarding function to self.dynamics.aliases # No Aliases: self.assertEqual(list(ComponentClass(name='C1').aliases), []) # 2 Aliases C = ComponentClass(name='C1', aliases=['G:= 0', 'H:=1']) self.assertEqual(len(list((C.aliases))), 2) self.assertEqual(set(C.aliases_map.keys()), set(['G', 'H'])) C = ComponentClass(name='C1', aliases=['G:= 0', 'H:=1', Alias('I', '3')]) self.assertEqual(len(list((C.aliases))), 3) self.assertEqual(set(C.aliases_map.keys()), set(['G', 'H', 'I'])) # Using DynamicsBlock Parameter: C = ComponentClass( name='C1', dynamicsblock=DynamicsBlock(aliases=['G:= 0', 'H:=1'])) self.assertEqual(len(list((C.aliases))), 2) self.assertEqual(set(C.aliases_map.keys()), set(['G', 'H'])) C = ComponentClass( name='C1', dynamicsblock=DynamicsBlock( aliases=['G:= 0', 'H:=1', Alias('I', '3')])) self.assertEqual(len(list((C.aliases))), 3) self.assertEqual(set(C.aliases_map.keys()), set(['G', 'H', 'I'])) # Invalid Construction: # Invalid Valid String: self.assertRaises(NineMLRuntimeError, ComponentClass, name='C1', aliases=['H=0']) # Duplicate Alias Names: ComponentClass(name='C1', aliases=['H:=0', 'G:=1']) self.assertRaises(NineMLRuntimeError, ComponentClass, name='C1', aliases=['H:=0', 'H:=1']) self.assertRaises(NineMLRuntimeError, ComponentClass, name='C1', aliases=['H:=0', Alias('H', '1')]) # Defining through dynamics and Component: self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['H:=0'], dynamicsblock=DynamicsBlock(aliases=['G:=1']), ) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=[Alias('H', '0')], dynamicsblock=DynamicsBlock(aliases=[Alias('G', '1')]), ) # Self referential aliases: self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['H := H +1'], ) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['H := G + 1', 'G := H + 1'], ) # Referencing none existant symbols: self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['H := G + I'], parameters=[], analog_ports=[], ) # Invalid Names: self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['H.2 := 0'], ) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['2H := 0'], ) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['E(H) := 0'], ) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['tanh := 0'], ) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['pi := 0'], )
def test_connect_ports(self): # Signature: name(self, src, sink) # Connects the ports of 2 subcomponents. # # The ports can be specified as ``string`` s or ``NamespaceAddresses`` es. # # # :param src: The source port of one sub-component; this should either an # event port or analog port, but it *must* be a send port. # # :param sink: The sink port of one sub-component; this should either an # event port or analog port, but it *must* be either a 'recv' or a # 'reduce' port. tIaf = TestableComponent('iaf') tCoba = TestableComponent('coba_synapse') # Should be fine: c = ComponentClass(name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }) c.connect_ports('iaf.V', 'coba.V') c = ComponentClass(name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }, portconnections=[('iaf.V', 'coba.V')]) # Non existant Ports: c = ComponentClass(name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }) self.assertRaises(NineMLRuntimeError, c.connect_ports, 'iaf.V1', 'coba.V') self.assertRaises(NineMLRuntimeError, c.connect_ports, 'iaf.V', 'coba.V1') self.assertRaises(NineMLRuntimeError, ComponentClass, name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }, portconnections=[('iaf.V1', 'coba.V')]) self.assertRaises(NineMLRuntimeError, ComponentClass, name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }, portconnections=[('iaf.V', 'coba.V1')]) # Connect ports the wronf way around: # [Check the wright way around works:] c = ComponentClass(name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }, portconnections=[('coba.I', 'iaf.ISyn')]) # And the wrong way around: c = ComponentClass(name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }) self.assertRaises(NineMLRuntimeError, c.connect_ports, 'iaf.ISyn.', 'coba.I') self.assertRaises(NineMLRuntimeError, c.connect_ports, 'coba.V', 'iaf.V') # Error raised on duplicate port-connection: c = ComponentClass( name='C1', subnodes={ 'iaf': tIaf(), 'coba': tCoba() }, ) c.connect_ports('coba.I', 'iaf.ISyn') self.assertRaises(NineMLRuntimeError, c.connect_ports, 'coba.I', 'iaf.ISyn')
def test_analog_ports(self): # Signature: name # No Docstring c = ComponentClass(name='C1') self.assertEqual(len(list(c.analog_ports)), 0) c = ComponentClass(name='C1') self.assertEqual(len(list(c.analog_ports)), 0) c = ComponentClass(name='C1', aliases=['A:=2'], analog_ports=[AnalogSendPort('A')]) self.assertEqual(len(list(c.analog_ports)), 1) self.assertEqual(list(c.analog_ports)[0].mode, 'send') self.assertEqual(len(c.query.analog_send_ports), 1) self.assertEqual(len(c.query.analog_recv_ports), 0) self.assertEqual(len(c.query.analog_reduce_ports), 0) c = ComponentClass(name='C1', analog_ports=[AnalogReceivePort('B')]) self.assertEqual(len(list(c.analog_ports)), 1) self.assertEqual(list(c.analog_ports)[0].mode, 'recv') self.assertEqual(len(c.query.analog_send_ports), 0) self.assertEqual(len(c.query.analog_recv_ports), 1) self.assertEqual(len(c.query.analog_reduce_ports), 0) c = ComponentClass(name='C1', analog_ports=[AnalogReducePort('B', reduce_op='+')]) self.assertEqual(len(list(c.analog_ports)), 1) self.assertEqual(list(c.analog_ports)[0].mode, 'reduce') self.assertEqual(list(c.analog_ports)[0].reduce_op, '+') self.assertEqual(len(c.query.analog_send_ports), 0) self.assertEqual(len(c.query.analog_recv_ports), 0) self.assertEqual(len(c.query.analog_reduce_ports), 1) # Duplicate Port Names: self.assertRaises(NineMLRuntimeError, ComponentClass, name='C1', aliases=['A:=1'], analog_ports=[ AnalogReducePort('B', reduce_op='+'), AnalogSendPort('B') ]) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['A:=1'], analog_ports=[AnalogSendPort('A'), AnalogSendPort('A')]) self.assertRaises( NineMLRuntimeError, ComponentClass, name='C1', aliases=['A:=1'], analog_ports=[AnalogReceivePort('A'), AnalogReceivePort('A')]) self.assertRaises( NineMLRuntimeError, lambda: ComponentClass(name='C1', analog_ports=[AnalogReceivePort('1')])) self.assertRaises( NineMLRuntimeError, lambda: ComponentClass(name='C1', analog_ports=[AnalogReceivePort('?')]))
def func_test(self): emitter = ComponentClass( name='EventEmitter', parameters=['cyclelength'], regimes=[ Regime(transitions=On('t > tchange + cyclelength', do=[OutputEvent('emit'), 'tchange=t'])), ]) ev_based_cc = ComponentClass( name='EventBasedCurrentClass', parameters=['dur', 'i'], analog_ports=[SendPort('I')], regimes=[ Regime(transitions=[ On('inputevent', do=['I=i', 'tchange = t']), On('t>tchange + dur', do=['I=0', 'tchange=t']) ]) ]) pulsing_emitter = ComponentClass(name='pulsing_cc', subnodes={ 'evs': emitter, 'cc': ev_based_cc }, portconnections=[('evs.emit', 'cc.inputevent')]) nrn = ComponentClass( name='LeakyNeuron', parameters=['Cm', 'gL', 'E'], regimes=[ Regime('dV/dt = (iInj + (E-V)*gL )/Cm'), ], aliases=['iIn := iInj'], analog_ports=[SendPort('V'), ReducePort('iInj', reduce_op='+')], ) combined_comp = ComponentClass(name='Comp1', subnodes={ 'nrn': nrn, 'cc1': pulsing_emitter, 'cc2': pulsing_emitter }, portconnections=[ ('cc1.cc.I', 'nrn.iInj'), ('cc2.cc.I', 'nrn.iInj') ]) combined_comp = 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 = 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 }) res = std_pynn_simulation( test_component=combined_comp, parameters=parameters, initial_values={}, synapse_components=[], records=records, # plot = False, ) return t, records = res def check_trace(trace_name, time_period, exp_mean, exp_std=0): t_indices = (t > time_period[0] + 1) & (t < time_period[1] - 1) self.assertAlmostEqual(records[trace_name][t_indices].mean(), exp_mean, places=3) self.assertAlmostEqual(records[trace_name][t_indices].std(), exp_std, places=3) check_trace('cc1_cc_I', (00, 30), exp_mean=0.0) check_trace('cc1_cc_I', (30, 40), exp_mean=13.8) check_trace('cc1_cc_I', (40, 60), exp_mean=0.0) check_trace('cc1_cc_I', (60, 70), exp_mean=13.8) check_trace('cc1_cc_I', (70, 90), exp_mean=0.0) check_trace('cc1_cc_I', (90, 100), exp_mean=13.8) check_trace('cc2_cc_I', (00, 20), exp_mean=0.0) check_trace('cc2_cc_I', (20, 25), exp_mean=20.8) check_trace('cc2_cc_I', (25, 40), exp_mean=0.0) check_trace('cc2_cc_I', (40, 45), exp_mean=20.8) check_trace('cc2_cc_I', (45, 60), exp_mean=0.0) check_trace('cc2_cc_I', (60, 65), exp_mean=20.8) check_trace('cc2_cc_I', (65, 80), exp_mean=0.0) check_trace('cc2_cc_I', (80, 85), exp_mean=20.8) check_trace('cc2_cc_I', (85, 100), exp_mean=0.0) check_trace('nrn_iIn', (00, 20), exp_mean=0.0) check_trace('nrn_iIn', (20, 25), exp_mean=20.8) check_trace('nrn_iIn', (25, 30), exp_mean=0.0) check_trace('nrn_iIn', (30, 40), exp_mean=13.8) check_trace('nrn_iIn', (40, 45), exp_mean=20.8) check_trace('nrn_iIn', (45, 60), exp_mean=0.0) check_trace('nrn_iIn', (60, 65), exp_mean=34.6) check_trace('nrn_iIn', (65, 70), exp_mean=13.8) check_trace('nrn_iIn', (70, 80), exp_mean=0.0) check_trace('nrn_iIn', (80, 85), exp_mean=20.8) check_trace('nrn_iIn', (85, 90), exp_mean=0.0) check_trace('nrn_iIn', (90, 100), exp_mean=13.8) check_trace('nrn_V', (00 + 2, 20), exp_mean=(0.0 / 4.3) - 70) check_trace('nrn_V', (20 + 2, 25), exp_mean=(20.8 / 4.3) - 70) check_trace('nrn_V', (25 + 2, 30), exp_mean=(0.0 / 4.3) - 70) check_trace('nrn_V', (30 + 2, 40), exp_mean=(13.8 / 4.3) - 70) check_trace('nrn_V', (40 + 2, 45), exp_mean=(20.8 / 4.3) - 70) check_trace('nrn_V', (45 + 2, 60), exp_mean=(0.0 / 4.3) - 70) check_trace('nrn_V', (60 + 2, 65), exp_mean=(34.6 / 4.3) - 70) check_trace('nrn_V', (65 + 2, 70), exp_mean=(13.8 / 4.3) - 70) check_trace('nrn_V', (70 + 2, 80), exp_mean=(0.0 / 4.3) - 70) check_trace('nrn_V', (80 + 2, 85), exp_mean=(20.8 / 4.3) - 70) check_trace('nrn_V', (85 + 2, 90), exp_mean=(0.0 / 4.3) - 70) check_trace('nrn_V', (90 + 2, 100), exp_mean=(13.8 / 4.3) - 70)
def get_compound_component(): """Cannot yet be implemented in PyDSTool """ from nineml.abstraction_layer.testing_utils import RecordValue from nineml.abstraction_layer import ComponentClass, Regime, On, OutputEvent, SendPort, ReducePort emitter = ComponentClass( name='EventEmitter', parameters=['cyclelength'], regimes=[ Regime(transitions=On('t > tchange + cyclelength', do=[OutputEvent('emit'), 'tchange=t'])), ]) ev_based_cc = ComponentClass( name='EventBasedCurrentClass', parameters=['dur', 'i'], analog_ports=[SendPort('I')], regimes=[ Regime(transitions=[ On('inputevent', do=['I=i', 'tchange = t']), On('t>tchange + dur', do=['I=0', 'tchange=t']) ]) ]) pulsing_emitter = ComponentClass(name='pulsing_cc', subnodes={ 'evs': emitter, 'cc': ev_based_cc }, portconnections=[('evs.emit', 'cc.inputevent')]) nrn = ComponentClass( name='LeakyNeuron', parameters=['Cm', 'gL', 'E'], regimes=[ Regime('dV/dt = (iInj + (E-V)*gL )/Cm'), ], aliases=['iIn := iInj'], analog_ports=[SendPort('V'), ReducePort('iInj', reduce_op='+')], ) combined_comp = ComponentClass(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