Changeset 89
- Timestamp:
- 06/05/07 11:26:34 (1 year ago)
- Files:
-
- branches/connector-class/common.py (modified) (3 diffs)
- branches/connector-class/nest.py (modified) (17 diffs)
- branches/connector-class/neuron.py (modified) (4 diffs)
- branches/connector-class/pcsim.py (modified) (2 diffs)
- branches/connector-class/test/nesttests.py (modified) (1 diff)
- branches/connector-class/test/neurontests.py (modified) (2 diffs)
- branches/connector-class/test/pcsimtests_population.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/connector-class/common.py
r75 r89 1 # encoding: utf-8 1 2 """ 2 3 Defines the PyNN classes and functions, and hence the FACETS API. … … 18 19 19 20 # ============================================================================== 20 # Utility classes 21 # ============================================================================== 21 # Utility classes and functions 22 # ============================================================================== 23 24 # The following two functions taken from 25 # http://www.nedbatchelder.com/text/pythonic-interfaces.html 26 def _functionId(obj, nFramesUp): 27 """ Create a string naming the function n frames up on the stack. """ 28 fr = sys._getframe(nFramesUp+1) 29 co = fr.f_code 30 return "%s.%s" % (obj.__class__, co.co_name) 31 32 def _abstractMethod(obj=None): 33 """ Use this instead of 'pass' for the body of abstract methods. """ 34 raise Exception("Unimplemented abstract method: %s" % _functionId(obj, 1)) 22 35 23 36 class ID(int): … … 649 662 650 663 # ============================================================================== 664 # Connection method classes 665 # ============================================================================== 666 667 class Connector(object): 668 """Abstract base class for Connector classes.""" 669 670 def __init__(self): 671 _abstractMethod(self) 672 673 def connect(self,projection): 674 """Connect all neurons in ``projection``""" 675 _abstractMethod(self) 676 677 class AllToAllConnector(Connector): 678 """ 679 Connects all cells in the presynaptic population to all cells in the 680 postsynaptic population. 681 """ 682 683 def __init__(self, allow_self_connections=True): 684 assert isinstance(allow_self_connections, bool) 685 self.allow_self_connections = allow_self_connections 686 687 class OneToOneConnector(Connector): 688 """ 689 Where the pre- and postsynaptic populations have the same size, connect 690 cell i in the presynaptic population to cell i in the postsynaptic 691 population for all i. 692 In fact, despite the name, this should probably be generalised to the 693 case where the pre and post populations have different dimensions, e.g., 694 cell i in a 1D pre population of size n should connect to all cells 695 in row i of a 2D post population of size (n,m). 696 """ 697 698 def __init__(self): 699 pass 700 701 702 # ============================================================================== 651 703 # Utility classes 652 704 # ============================================================================== branches/connector-class/nest.py
r88 r89 861 861 self._targets = [] # holds gids 862 862 self._sources = [] # holds gids 863 connection_method = getattr(self,'_%s' % method)864 if target:865 self.nconn = connection_method(methodParameters,synapse_type=target)866 else:863 self.synapse_type = target 864 865 if isinstance(method, str): 866 connection_method = getattr(self,'_%s' % method) 867 867 self.nconn = connection_method(methodParameters) 868 elif isinstance(method,common.Connector): 869 self.nconn = method.connect(self) 870 868 871 assert len(self._sources) == len(self._targets) == len(self._targetPorts), "Connection error. Source and target lists are of different lengths." 869 872 self.connection = Projection.ConnectionDict(self) … … 906 909 # --- Connection methods --------------------------------------------------- 907 910 908 def _allToAll(self,parameters=None ,synapse_type=None):911 def _allToAll(self,parameters=None): 909 912 """ 910 913 Connect all cells in the presynaptic population to all cells in the postsynaptic population. … … 914 917 if parameters and parameters.has_key('allow_self_connections'): 915 918 allow_self_connections = parameters['allow_self_connections'] 916 self.synapse_type = synapse_type 917 postsynaptic_neurons = numpy.reshape(self.post.cell,(self.post.cell.size,)) 918 presynaptic_neurons = numpy.reshape(self.pre.cell,(self.pre.cell.size,)) 919 for post in postsynaptic_neurons: 920 source_list = presynaptic_neurons.tolist() 921 # if self connections are not allowed, check whether pre and post are the same 922 if not allow_self_connections and post in source_list: 923 source_list.remove(post) 924 self._targets += [post]*len(source_list) 925 self._sources += source_list 926 self._targetPorts += pynest.convergentConnect(source_list,post,[1.0],[0.1]) 927 return len(self._targets) 928 929 def _oneToOne(self,synapse_type=None): 919 c = AllToAllConnector(allow_self_connections) 920 return c.connect(self) 921 922 def _oneToOne(self,parameters=None): 930 923 """ 931 924 Where the pre- and postsynaptic populations have the same size, connect … … 937 930 in row i of a 2D post population of size (n,m). 938 931 """ 939 self.synapse_type = synapse_type940 932 if self.pre.dim == self.post.dim: 941 933 self._sources = numpy.reshape(self.pre.cell,(self.pre.cell.size,)) … … 949 941 raise Exception("Method 'oneToOne' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes.") 950 942 951 def _fixedProbability(self,parameters ,synapse_type=None):943 def _fixedProbability(self,parameters): 952 944 """ 953 945 For each pair of pre-post cells, the connection probability is constant. 954 946 """ 955 self.synapse_type = synapse_type956 947 allow_self_connections = True 957 948 try: … … 976 967 return len(self._sources) 977 968 978 def _distanceDependentProbability(self,parameters ,synapse_type=None):969 def _distanceDependentProbability(self,parameters): 979 970 """ 980 971 For each pair of pre-post cells, the connection probability depends on distance. … … 982 973 for probability, involving 'd', e.g. "exp(-abs(d))", or "float(d<3)" 983 974 """ 984 self.synapse_type = synapse_type985 975 allow_self_connections = True 986 976 if type(parameters) == types.StringType: … … 1033 1023 self._targetPorts.append(pynest.connect(pre_addr,post_addr)) 1034 1024 1035 def _fixedNumberPre(self,parameters ,synapse_type=None):1025 def _fixedNumberPre(self,parameters): 1036 1026 """Each presynaptic cell makes a fixed number of connections.""" 1037 self.synapse_type = synapse_type1038 1027 allow_self_connections = True 1039 1028 if type(parameters) == types.IntType: … … 1077 1066 self._targetPorts.append(pynest.connect(pre_addr,pynest.getAddress(post))) 1078 1067 1079 def _fixedNumberPost(self,parameters ,synapse_type=None):1068 def _fixedNumberPost(self,parameters): 1080 1069 """Each postsynaptic cell receives a fixed number of connections.""" 1081 self.synapse_type = synapse_type1082 1070 allow_self_connections = True 1083 1071 if type(parameters) == types.IntType: … … 1121 1109 self._targetPorts.append(pynest.connect(pynest.getAddress(pre),post_addr)) 1122 1110 1123 def _fromFile(self,parameters ,synapse_type=None):1111 def _fromFile(self,parameters): 1124 1112 """ 1125 1113 Load connections from a file. 1126 1114 """ 1127 self.synapse_type = synapse_type1128 1115 if type(parameters) == types.FileType: 1129 1116 fileobj = parameters … … 1150 1137 f.close() 1151 1138 1152 self._fromList(input_tuples , synapse_type)1153 1154 def _fromList(self,conn_list ,synapse_type=None):1139 self._fromList(input_tuples) 1140 1141 def _fromList(self,conn_list): 1155 1142 """ 1156 1143 Read connections from a list of tuples, … … 1159 1146 lists containing the neuron array coordinates. 1160 1147 """ 1161 self.synapse_type = synapse_type1162 1148 for i in xrange(len(conn_list)): 1163 1149 src, tgt, weight, delay = conn_list[i][:] … … 1171 1157 self._targetPorts.append(pynest.connectWD(pre_addr,post_addr, 1000*weight, delay)) 1172 1158 1173 def _2D_Gauss(self,parameters ,synapse_type=None):1159 def _2D_Gauss(self,parameters): 1174 1160 """ 1175 1161 Source neuron is connected to a 2D targetd population with a spatial profile (Gauss). … … 1181 1167 sigma: sigma of the Gauss 1182 1168 """ 1183 self.synapse_type = synapse_type1184 1169 def rcf_2D(parameters): 1185 1170 rng = parameters['rng'] … … 1228 1213 rcf_2D(parameters) 1229 1214 1230 def _test_delay(self,params,synapse_type=None): 1231 self.synapse_type = synapse_type 1215 def _test_delay(self,params): 1232 1216 # debug get delays from outside 1233 1217 #delay_array = parameters['delays_array'] … … 1245 1229 print 'leaving test_delay' 1246 1230 1247 def _3D_Gauss(self,parameters ,synapse_type=None):1231 def _3D_Gauss(self,parameters): 1248 1232 """ 1249 1233 Source neuron is connected to a 3D targetd population with a spatial profile (Gauss). … … 1588 1572 # should be put here or in an external module. 1589 1573 raise Exception("Method not yet implemented") 1590 1574 1575 # ============================================================================== 1576 # Connection method classes 1577 # ============================================================================== 1578 1579 class AllToAllConnector(common.AllToAllConnector): 1580 1581 def connect(self, projection): 1582 postsynaptic_neurons = numpy.reshape(projection.post.cell,(projection.post.cell.size,)) 1583 presynaptic_neurons = numpy.reshape(projection.pre.cell,(projection.pre.cell.size,)) 1584 for post in postsynaptic_neurons: 1585 source_list = presynaptic_neurons.tolist() 1586 # if self connections are not allowed, check whether pre and post are the same 1587 if not self.allow_self_connections and post in source_list: 1588 source_list.remove(post) 1589 projection._targets += [post]*len(source_list) 1590 projection._sources += source_list 1591 projection._targetPorts += pynest.convergentConnect(source_list,post,[1.0],[0.1]) 1592 return len(projection._targets) 1593 1594 class OneToOneConnector(common.OneToOneConnector): 1595 1596 def connect(self, projection): 1597 if projection.pre.dim == projection.post.dim: 1598 projection._sources = numpy.reshape(projection.pre.cell,(projection.pre.cell.size,)) 1599 projection._targets = numpy.reshape(projection.post.cell,(projection.post.cell.size,)) 1600 for pre,post in zip(projection._sources,projection._targets): 1601 pre_addr = pynest.getAddress(pre) 1602 post_addr = pynest.getAddress(post) 1603 projection._targetPorts.append(pynest.connect(pre_addr,post_addr)) 1604 return projection.pre.size 1605 else: 1606 raise Exception("Connection method not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes.") 1607 1608 1591 1609 # ============================================================================== 1592 1610 # Utility classes branches/connector-class/neuron.py
r88 r89 1155 1155 hoc_commands = ['objref %s' % self.hoc_label, 1156 1156 '%s = new List()' % self.hoc_label] 1157 connection_method = getattr(self,'_%s' % method)1158 1157 self.synapse_type = target 1159 1158 self._syn_objref = _translate_synapse_type(self.synapse_type) 1160 1159 1161 if target: 1162 hoc_commands += connection_method(methodParameters,synapse_type=target) 1163 else: 1160 if isinstance(method, str): 1161 connection_method = getattr(self,'_%s' % method) 1164 1162 hoc_commands += connection_method(methodParameters) 1163 elif isinstance(method,common.Connector): 1164 hoc_commands += method.connect(self) 1165 1165 hoc_execute(hoc_commands, "--- Projection[%s].__init__() ---" %self.label) 1166 1166 … … 1221 1221 if parameters and parameters.has_key('allow_self_connections'): 1222 1222 allow_self_connections = parameters['allow_self_connections'] 1223 hoc_commands = [] 1224 for tgt in self.post.gidlist: 1225 for src in self.pre.fullgidlist: 1226 if allow_self_connections or self.pre != self.post or tgt != src: 1227 hoc_commands += self.__connect(src,tgt) 1228 return hoc_commands 1223 c = AllToAllConnector(allow_self_connections) 1224 return c.connect(self) 1229 1225 1230 1226 def _oneToOne(self,parameters=None): … … 1237 1233 cell i in a 1D pre population of size n should connect to all cells 1238 1234 in row i of a 2D post population of size (n,m). 1239 """ 1240 if self.pre.dim == self.post.dim: 1241 hoc_commands = [] 1242 for tgt in self.post.gidlist: 1243 src = tgt - self.post.gid_start + self.pre.gid_start 1244 hoc_commands += self.__connect(src,tgt) 1245 else: 1246 raise Exception("Method '%s' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes." % sys._getframe().f_code.co_name) 1247 return hoc_commands 1235 """ 1236 c = OneToOneConnector() 1237 return c.connect(self) 1248 1238 1249 1239 def _fixedProbability(self,parameters): … … 1758 1748 1759 1749 # ============================================================================== 1750 # Connection method classes 1751 # ============================================================================== 1752 1753 class HocConnector(object): 1754 1755 def singleConnect(self,projection,src,tgt): 1756 """ 1757 Write hoc commands to connect a single pair of neurons. 1758 """ 1759 cmdlist = ['nc = pc.gid_connect(%d,%s.object(%d).%s)' % (src, 1760 projection.post.hoc_label, 1761 projection.post.gidlist.index(tgt), 1762 projection._syn_objref), 1763 'tmp = %s.append(nc)' % projection.hoc_label] 1764 projection.connections.append((src,tgt)) 1765 return cmdlist 1766 1767 class AllToAllConnector(common.AllToAllConnector, HocConnector): 1768 1769 def connect(self, projection): 1770 hoc_commands = [] 1771 for tgt in projection.post.gidlist: 1772 for src in projection.pre.fullgidlist: 1773 if self.allow_self_connections or projection.pre != projection.post or tgt != src: 1774 hoc_commands += self.singleConnect(projection,src,tgt) 1775 return hoc_commands 1776 1777 class OneToOneConnector(common.OneToOneConnector, HocConnector): 1778 1779 def connect(self, projection): 1780 if projection.pre.dim == projection.post.dim: 1781 hoc_commands = [] 1782 for tgt in projection.post.gidlist: 1783 src = tgt - projection.post.gid_start + projection.pre.gid_start 1784 hoc_commands += self.singleConnect(projection,src,tgt) 1785 else: 1786 raise Exception("Method '%s' not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes." % sys._getframe().f_code.co_name) 1787 return hoc_commands 1788 1789 # ============================================================================== 1760 1790 # Utility classes 1761 1791 # ============================================================================== branches/connector-class/pcsim.py
r88 r89 1104 1104 1105 1105 # Determine connection decider 1106 if method == 'allToAll': 1107 decider = RandomConnections(1) 1108 wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 1109 elif method == 'fixedProbability': 1110 decider = RandomConnections(float(methodParameters)) 1111 wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 1112 elif method == 'distanceDependentProbability': 1113 decider = EuclideanDistanceRandomConnections(methodParameters[0], methodParameters[1]) 1114 wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 1115 elif method == 'fixedNumberPre': 1116 decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.incoming) 1117 wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 1118 elif method == 'fixedNumberPost': 1119 decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.outgoing) 1120 wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 1121 elif method == 'oneToOne': 1122 decider = RandomConnections(1) 1123 wiring_method = OneToOneWiringMethod(pcsim_globals.net) 1124 else: 1125 raise Exception("METHOD NOT YET IMPLEMENTED") 1126 1106 if isinstance(method, str): 1107 if method == 'allToAll': 1108 decider = RandomConnections(1) 1109 wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 1110 elif method == 'fixedProbability': 1111 decider = RandomConnections(float(methodParameters)) 1112 wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 1113 elif method == 'distanceDependentProbability': 1114 decider = EuclideanDistanceRandomConnections(methodParameters[0], methodParameters[1]) 1115 wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 1116 elif method == 'fixedNumberPre': 1117 decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.incoming) 1118 wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 1119 elif method == 'fixedNumberPost': 1120 decider = DegreeDistributionConnections(ConstantNumber(parameters), DegreeDistributionConnections.outgoing) 1121 wiring_method = SimpleAllToAllWiringMethod(pcsim_globals.net) 1122 elif method == 'oneToOne': 1123 decider = RandomConnections(1) 1124 wiring_method = OneToOneWiringMethod(pcsim_globals.net) 1125 else: 1126 raise Exception("METHOD NOT YET IMPLEMENTED") 1127 elif isinstance(method,common.Connector): 1128 decider, wiring_method = method.connect(self) 1129 1127 1130 if not target: 1128 1131 self.syn_factory = SimpleScalingSpikingSynapse(1, 1, pcsim_globals.minDelay/1000) … … 1265 1268 1266 1269 # ============================================================================== 1270 # Connection method classes 1271 # ============================================================================== 1272 1273 class AllToAllConnector(common.AllToAllConnector): 1274 1275 def connect(self, projection): 1276 # what about allow_self_connections? 1277 decider = RandomConnections(1) 1278 wiring_method = DistributedSyncWiringMethod(pcsim_globals.net) 1279 return decider, wiring_method 1280 1281 class OneToOneConnector(common.OneToOneConnector): 1282 1283 def connect(self, projection): 1284 if projection.pre.dim == projection.post.dim: 1285 decider = RandomConnections(1) 1286 wiring_method = OneToOneWiringMethod(pcsim_globals.net) 1287 return decider, wiring_method 1288 else: 1289 raise Exception("Connection method not yet implemented for the case where presynaptic and postsynaptic Populations have different sizes.") 1290 1291 1292 1293 # ============================================================================== 1267 1294 # Utility classes 1268 1295 # ============================================================================== branches/connector-class/test/nesttests.py
r88 r89 410 410 for tgtP in [self.target6, self.target33]: 411 411 prj1 = nest.Projection(srcP, tgtP, "allToAll") 412 assert len(prj1._sources) == len(prj1._targets) 413 weights = [] 414 for src,tgt in prj1.connections(): 415 weights.append(nest.pynest.getWeight(src,tgt)) 416 assert weights == [1.0]*len(prj1._sources) 417 412 prj2 = nest.Projection(srcP, tgtP, nest.AllToAllConnector()) 413 for prj in prj1,prj2: 414 assert len(prj._sources) == len(prj._targets) 415 weights = [] 416 for src,tgt in prj.connections(): 417 weights.append(nest.pynest.getWeight(src,tgt)) 418 assert weights == [1.0]*len(prj._sources) 419 420 def testoneToOne(self): 421 """For all connections created with "OneToOne" it should be possible to obtain the weight using pyneuron.getWeight()""" 422 prj1 = nest.Projection(self.source33, self.target33, 'oneToOne') 423 prj2 = nest.Projection(self.source33, self.target33, nest.OneToOneConnector()) 424 assert len(prj1) == self.source33.size 425 assert len(prj2) == self.source33.size 426 418 427 def testdistantDependentProbability(self): 419 428 """For all connections created with "distanceDependentProbability" it should be possible to obtain the weight using pyneuron.getWeight()""" branches/connector-class/test/neurontests.py
r88 r89 462 462 for tgtP in [self.target6, self.target33]: 463 463 prj1 = neuron.Projection(srcP, tgtP, 'allToAll') 464 prj2 = neuron.Projection(srcP, tgtP, neuron.AllToAllConnector()) 464 465 prj1.setWeights(1.234) 465 weights = [] 466 for connection_id in prj1.connections: 467 weights.append(HocToPy.get('%s.object(%d).weight' % (prj1.label,prj1.connections.index(connection_id)), 'float')) 468 assert weights == [1.234]*len(prj1) 469 466 prj2.setWeights(1.234) 467 for prj in prj1,prj2: 468 weights = [] 469 for connection_id in prj.connections: 470 weights.append(HocToPy.get('%s.object(%d).weight' % (prj.label,prj.connections.index(connection_id)), 'float')) 471 assert weights == [1.234]*len(prj) 472 470 473 def testFixedProbability(self): 471 474 """For all connections created with "fixedProbability" it should be possible to obtain the weight using pyneuron.getWeight()""" … … 481 484 """For all connections created with "OneToOne" it should be possible to obtain the weight using pyneuron.getWeight()""" 482 485 prj1 = neuron.Projection(self.source33, self.target33, 'oneToOne') 486 prj2 = neuron.Projection(self.source33, self.target33, neuron.OneToOneConnector()) 483 487 assert len(prj1.connections) == self.source33.size 488 assert len(prj2.connections) == self.source33.size 484 489 485 490 def testdistantDependentProbability(self): branches/connector-class/test/pcsimtests_population.py
r88 r89 124 124 class PopulationSetTest(unittest.TestCase): 125 125 126 def setUp(self):127 setup()128 Population.nPop = 0129 self.popul1 = Population((3,3),IF_curr_alpha)130 self.popul2 = Population((5,),CbLifNeuron,{'Vinit':-0.070, 'Inoise':0.001})131 132 def testSetFromDict(self):133 """Population.set(): Parameters set in a dict should all be retrievable from PyPCSIM directly"""134 self.popul1.set({'tau_m':43.21})135 self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(8)).taum, 0.04321, places = 5)126 def setUp(self): 127 setup() 128 Population.nPop = 0 129 self.popul1 = Population((3,3),IF_curr_alpha) 130 self.popul2 = Population((5,),CbLifNeuron,{'Vinit':-0.070, 'Inoise':0.001}) 131 132 def testSetFromDict(self): 133 """Population.set(): Parameters set in a dict should all be retrievable from PyPCSIM directly""" 134 self.popul1.set({'tau_m':43.21}) 135 self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(8)).taum, 0.04321, places = 5) 136 136 # 137 def testSetFromPair(self): 138 """Population.set(): A parameter set as a string,value pair should be retrievable using PyPCSIM directly""" 139 self.popul1.set('tau_m',12.34) 140 self.popul1.set('v_init',-65.0) 141 self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 0.01234, places=5) 142 self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).Vinit, -0.065, places=5) 143 144 145 def testSetInvalidFromPair(self): 146 """Population.set(): Trying to set an invalid value for a parameter should raise an exception.""" 147 self.assertRaises(common.InvalidParameterValueError, self.popul1.set, 'tau_m', []) 148 149 def testSetInvalidFromDict(self): 150 """Population.set(): When any of the parameters in a dict have invalid values, then an exception should be raised. 151 There is no guarantee that the valid parameters will be set.""" 152 self.assertRaises(common.InvalidParameterValueError, self.popul1.set, {'v_thresh':'hello','tau_m':56.78}) 153 154 def testSetNonexistentFromPair(self): 155 """Population.set(): Trying to set a nonexistent parameter should raise an exception.""" 156 self.assertRaises(common.NonExistentParameterError, self.popul1.set, 'tau_foo', 10.0) 157 158 def testSetNonexistentFromDict(self): 159 """Population.set(): When some of the parameters in a dict are inexistent, an exception should be raised. 160 There is no guarantee that the existing parameters will be set.""" 161 self.assertRaises(common.NonExistentParameterError, self.popul1.set, {'tau_foo': 10.0, 'tau_m': 21.0}) 162 163 def testSetWithNonStandardModel(self): 164 """Population.set(): Parameters set in a dict should all be retrievable using PyPCSIM interface directly""" 165 self.popul2.set({'Rm':4.5e6}) 166 self.assertAlmostEqual( pcsim_globals.net.object(self.popul2.getObjectID(3)).Rm , 4.5e6, places = 10) 137 def testSetFromPair(self): 138 """Population.set(): A parameter set as a string,value pair should be retrievable using PyPCSIM directly""" 139 self.popul1.set('tau_m',12.34) 140 self.popul1.set('v_init',-65.0) 141 self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 0.01234, places=5) 142 self.assertAlmostEqual( pcsim_globals.net.object(self.popul1.getObjectID(3)).Vinit, -0.065, places=5) 143 144 145 def testSetInvalidFromPair(self): 146 """Population.set(): Trying to set an invalid value for a parameter should raise an exception.""" 147 self.assertRaises(common.InvalidParameterValueError, self.popul1.set, 'tau_m', []) 148 149 def testSetInvalidFromDict(self): 150 """Population.set(): When any of the parameters in a dict have invalid values, then an exception should be raised. 151 There is no guarantee that the valid parameters will be set.""" 152 self.assertRaises(common.InvalidParameterValueError, self.popul1.set, {'v_thresh':'hello','tau_m':56.78}) 153 154 def testSetNonexistentFromPair(self): 155 """Population.set(): Trying to set a nonexistent parameter should raise an exception.""" 156 self.assertRaises(common.NonExistentParameterError, self.popul1.set, 'tau_foo', 10.0) 157 158 def testSetNonexistentFromDict(self): 159 """Population.set(): When some of the parameters in a dict are inexistent, an exception should be raised. 160 There is no guarantee that the existing parameters will be set.""" 161 self.assertRaises(common.NonExistentParameterError, self.popul1.set, {'tau_foo': 10.0, 'tau_m': 21.0}) 162 163 def testSetWithNonStandardModel(self): 164 """Population.set(): Parameters set in a dict should all be retrievable using PyPCSIM interface directly""" 165 self.popul2.set({'Rm':4.5e6}) 166 self.assertAlmostEqual( pcsim_globals.net.object(self.popul2.getObjectID(3)).Rm , 4.5e6, places = 10) 167 168 def testTSet(self): 169 """Population.tset(): The valueArray passed should be retrievable using the PyPCSIM interface """ 170 array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 171 self.popul1.tset('i_offset', array_in) 172 for i in 0,1,2: 173 for j in 0,1,2: 174 self.assertAlmostEqual( array_in[i,j], pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Iinject*1e9 , places = 7 ) 175 176 def testTSetArrayUnchanged(self): 177 array_in1 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 178 array_in2 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 179 self.assert_((array_in1==array_in2).all()) 180 self.popul1.tset('i_offset', array_in1) 181 self.assert_((array_in1==array_in2).all()) 182 183 def testTSetInvalidDimensions(self): 184 """Population.tset(): If the size of the valueArray does not match that of the Population, should raise an InvalidDimensionsError.""" 185 array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6]]) 186 self.assertRaises(common.InvalidDimensionsError, self.popul1.tset, 'i_offset', array_in) 187 188 def testTSetInvalidValues(self): 189 """Population.tset(): If some of the values in the valueArray are invalid, should raise an exception.""" 190 array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,'apples']]) 191 self.assertRaises(common.InvalidParameterValueError, self.popul1.tset, 'i_offset', array_in) 192 """Population.rset(): with native rng. This is difficult to test, so for now just require that all values retrieved should be different. Later, could calculate distribution and assert that the difference between sample and theoretical distribution is less than some threshold.""" 193 194 def testRSetNative(self): 195 self.popul1.rset('tau_m', 196 random.RandomDistribution(rng=NativeRNG(), 197 distribution='Uniform', 198 parameters={'a':10.0, 'b':30.0})) 199 self.assertNotEqual(pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 200 pcsim_globals.net.object(self.popul1.getObjectID(6)).taum) 201 202 def testRSetNumpy(self): 203 """Population.rset(): with numpy rng.""" 204 rd1 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 205 distribution='uniform', 206 parameters=[0.9,1.1]) 207 rd2 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 208 distribution='uniform', 209 parameters=[0.9,1.1]) 210 self.popul1.rset('cm',rd1) 211 output_values = numpy.zeros((3,3),numpy.float) 212 for i in 0,1,2: 213 for j in 0,1,2: 214 output_values[i,j] = 1e9*pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 215 input_values = rd2.next(9) 216 output_values = output_values.reshape((9,)) 217 for i in range(9): 218 self.assertAlmostEqual(input_values[i],output_values[i],places=5) 167 219 168 def testTSet(self): 169 """Population.tset(): The valueArray passed should be retrievable using the PyPCSIM interface """ 170 array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 171 self.popul1.tset('i_offset', array_in) 220 def testRSetNative2(self): 221 """Population.rset(): with native rng.""" 222 rd1 = random.RandomDistribution(rng=NativeRNG(seed=98765), 223 distribution='Uniform', 224 parameters=[0.9,1.1]) 225 rd2 = random.RandomDistribution(rng=NativeRNG(seed=98765), 226 distribution='Uniform', 227 parameters=[0.9,1.1]) 228 self.popul1.rset('cm', rd1) 229 output_values_1 = numpy.zeros((3,3),numpy.float) 230 output_values_2 = numpy.zeros((3,3),numpy.float) 172 231 for i in 0,1,2: 173 232 for j in 0,1,2: 174 self.assertAlmostEqual( array_in[i,j], pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Iinject*1e9 , places = 7 ) 175 176 def testTSetArrayUnchanged(self): 177 array_in1 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 178 array_in2 = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,0.9]]) 179 self.assert_((array_in1==array_in2).all()) 180 self.popul1.tset('i_offset', array_in1) 181 self.assert_((array_in1==array_in2).all()) 182 183 def testTSetInvalidDimensions(self): 184 """Population.tset(): If the size of the valueArray does not match that of the Population, should raise an InvalidDimensionsError.""" 185 array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6]]) 186 self.assertRaises(common.InvalidDimensionsError, self.popul1.tset, 'i_offset', array_in) 187 188 def testTSetInvalidValues(self): 189 """Population.tset(): If some of the values in the valueArray are invalid, should raise an exception.""" 190 array_in = numpy.array([[0.1,0.2,0.3],[0.4,0.5,0.6],[0.7,0.8,'apples']]) 191 self.assertRaises(common.InvalidParameterValueError, self.popul1.tset, 'i_offset', array_in) 192 """Population.rset(): with native rng. This is difficult to test, so for now just require that all values retrieved should be different. Later, could calculate distribution and assert that the difference between sample and theoretical distribution is less than some threshold.""" 193 194 def testRSetNative(self): 195 self.popul1.rset('tau_m', 196 random.RandomDistribution(rng=NativeRNG(), 197 distribution='Uniform', 198 parameters={'a':10.0, 'b':30.0})) 199 self.assertNotEqual(pcsim_globals.net.object(self.popul1.getObjectID(3)).taum, 200 pcsim_globals.net.object(self.popul1.getObjectID(6)).taum) 201 202 def testRSetNumpy(self): 203 """Population.rset(): with numpy rng.""" 204 rd1 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 205 distribution='uniform', 206 parameters=[0.9,1.1]) 207 rd2 = random.RandomDistribution(rng=random.NumpyRNG(seed=98765), 208 distribution='uniform', 209 parameters=[0.9,1.1]) 210 self.popul1.rset('cm',rd1) 211 output_values = numpy.zeros((3,3),numpy.float) 212 for i in 0,1,2: 213 for j in 0,1,2: 214 output_values[i,j] = 1e9*pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 215 input_values = rd2.next(9) 216 output_values = output_values.reshape((9,)) 217 for i in range(9): 218 self.assertAlmostEqual(input_values[i],output_values[i],places=5) 219 220 def testRSetNative2(self): 221 """Population.rset(): with native rng.""" 222 rd1 = random.RandomDistribution(rng=NativeRNG(seed=98765), 223 distribution='Uniform', 224 parameters=[0.9,1.1]) 225 rd2 = random.RandomDistribution(rng=NativeRNG(seed=98765), 226 distribution='Uniform', 227 parameters=[0.9,1.1]) 228 self.popul1.rset('cm', rd1) 229 output_values_1 = numpy.zeros((3,3),numpy.float) 230 output_values_2 = numpy.zeros((3,3),numpy.float) 231 for i in 0,1,2: 232 for j in 0,1,2: 233 output_values_1[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 234 235 self.popul1.rset('cm', rd2) 236 for i in 0,1,2: 237 for j in 0,1,2: 238 output_values_2[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 239 240 output_values_1 = output_values_1.reshape((9,)) 241 output_values_2 = output_values_2.reshape((9,)) 242 for i in range(9): 243 self.assertAlmostEqual(output_values_1[i],output_values_2[i],places=5) 233 output_values_1[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 234 235 self.popul1.rset('cm', rd2) 236 for i in 0,1,2: 237 for j in 0,1,2: 238 output_values_2[i,j] = pcsim_globals.net.object(self.popul1.getObjectID(self.popul1[i,j])).Cm 239 240 output_values_1 = output_values_1.reshape((9,)) 241 output_values_2 = output_values_2.reshape((9,)) 242 for i in range(9): 243 self.assertAlmostEqual(output_values_1[i],output_values_2[i],places=5) 244 244 245 245 # ============================================================================== 246 246 class PopulationCallTest(unittest.TestCase): # to write later 247 """Tests of the _call() and _tcall() methods of the Population class."""248 pass247 """Tests of the _call() and _tcall() methods of the Population class.""" 248 pass 249 249 250 250 # ============================================================================== 251 251 class PopulationRecordTest(unittest.TestCase): # to write later 252 """Tests of the record(), record_v(), printSpikes(), print_v() and253 meanSpikeCount() methods of the Population class."""254 255 def setUp(self):256 Population.nPop = 0257 self.popul = Population((3,3),IF_curr_alpha)258 259 def tearDown(self):260 end()261 262 def testRecordAll(self):263 """Population.record(): not a full test, just checking there are no Exceptions raised."""264 self.popul.record()265 266 def testRecordInt(self):267 """Population.record(n): not a full test, just checking there are no Exceptions raised."""268 self.popul.record(5)269 270 def testRecordWithRNG(self):271 """Population.record(n,rng): not a full test, just checking there are no Exceptions raised."""272 # self.popul.record(5,random.NumpyRNG())273 274 def testRecordList(self):275 """Population.record(list): not a full test, just checking there are no Exceptions raised."""276 self.popul.record([self.popul[(2,2)],self.popul[(1,2)],self.popul[(0,0)]])252 """Tests of the record(), record_v(), printSpikes(), print_v() and 253 meanSpikeCount() methods of the Population class.""" 254 255 def setUp(self): 256 Population.nPop = 0 257 self.popul = Population((3,3),IF_curr_alpha) 258 259 def tearDown(self): 260 end() 261 262 def testRecordAll(self): 263 """Population.record(): not a full test, just checking there are no Exceptions raised.""" 264 self.popul.record() 265 266 def testRecordInt(self): 267 """Population.record(n): not a full test, just checking there are no Exceptions raised.""" 268 self.popul.record(5) 269 270 def testRecordWithRNG(self): 271 """Population.record(n,rng): not a full test, just checking there are no Exceptions raised.""" 272 # self.popul.record(5,random.NumpyRNG()) 273 274 def testRecordList(self): 275 """Population.record(list): not a full test, just checking there are no Exceptions raised.""" 276 self.popul.record([self.popul[(2,2)],self.popul[(1,2)],self.popul[(0,0)]]) 277 277 278 278 # ============================================================================== 279 279 class PopulationOtherTest(unittest.TestCase): # to write later 280 """Tests of the randomInit() method of the Population class."""281 pass280 """Tests of the randomInit() method of the Population class.""" 281 pass 282 282 283 283 # ============================================================================== 284 284 class ProjectionInitTest(unittest.TestCase): 285 """Tests of the __init__() method of the Projection class.""" 285 """Tests of the __init__() method of the Projection class.""" 286 287 def setUp(self): 288 Population.nPop = 0 289 # Projection.nProj = 0 290 self.target33 = Population((3,3),IF_curr_alpha) 291 self.target6 = Population((6,),IF_curr_alpha) 292 self.source5 = Population((5,),SpikeSourcePoisson) 293 self.source22 = Population((2,2),SpikeSourcePoisson) 294 self.source33 = Population((3,3),SpikeSourcePoisson) 295 self.expoisson33 = Population((3,3),SpikeSourcePoisson,{'rate': 100}) 296 297 def testAllToAll(self): 298 """For all connections created with "allToAll" it should be possible to obtain the weight using pyneuron.getWeight()""" 299 for srcP in [self.source5, self.source22]: 300 for tgtP in [self.target6, self.target33]: 301 prj1 = Projection(srcP, tgtP, 'allToAll') 302 prj2 = Projection(srcP, tgtP, AllToAllConnector()) 303 for prj in prj1, prj2: 304 prj.setWeights(1.234) 305 weights = [] 306 for i in range(len(prj)): 307 weights.append(pcsim_globals.net.object(prj.pcsim_projection[i]).W) 308 for w in weights: 309 self.assertAlmostEqual(w,1.234*1e-9, places = 7) 286 310 287 def setUp(self): 288 Population.nPop = 0 289 # Projection.nProj = 0 290 self.target33 = Population((3,3),IF_curr_alpha) 291 self.target6 = Population((6,),IF_curr_alpha) 292 self.source5 = Population((5,),SpikeSourcePoisson) 293 self.source22 = Population((2,2),SpikeSourcePoisson) 294 self.source33 = Population((3,3),SpikeSourcePoisson) 295 &n
