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_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_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_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_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_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_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 get_compound_component(): """Cannot yet be implemented in PyDSTool """ from nineml.abstraction_layer.testing_utils import RecordValue from nineml.abstraction_layer import DynamicsClass, Regime, On, OutputEvent, AnalogSendPort, AnalogReducePort emitter = DynamicsClass( name='EventEmitter', parameters=['cyclelength'], regimes=[ Regime(transitions=On('t > tchange + cyclelength', do=[OutputEvent('emit'), 'tchange=t'])), ]) ev_based_cc = DynamicsClass( 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 = DynamicsClass(name='pulsing_cc', subnodes={ 'evs': emitter, 'cc': ev_based_cc }, portconnections=[('evs.emit', 'cc.inputevent')]) nrn = DynamicsClass( name='LeakyNeuron', parameters=['Cm', 'gL', 'E'], regimes=[ Regime('dV/dt = (iInj + (E-V)*gL )/Cm'), ], aliases=['iIn := iInj'], analog_ports=[ AnalogSendPort('V'), AnalogReducePort('iInj', reduce_op='+') ], ) combined_comp = DynamicsClass(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