- Timestamp:
- 06/05/07 09:10:00 (5 years ago)
- Location:
- branches/connector-class
- Files:
-
- 7 modified
-
facetsml.py (modified) (22 diffs)
-
nest.py (modified) (1 diff)
-
neuron.py (modified) (12 diffs)
-
pcsim.py (modified) (1 diff)
-
test/nesttests.py (modified) (1 diff)
-
test/neurontests.py (modified) (1 diff)
-
test/pcsimtests_population.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
branches/connector-class/facetsml.py
r49 r88 11 11 from xml.dom.ext import * 12 12 13 14 open_files = [] 15 16 dt = 0.1 13 gid = 0 14 ncid = 0 15 gidlist = [] 16 vfilelist = {} 17 spikefilelist = {} 18 dt = 0.1 19 running = False 20 21 # ============================================================================== 22 # Module-specific functions and classes (not part of the common API) 23 # ============================================================================== 24 25 17 26 xmldoc = Document() 18 27 … … 68 77 69 78 # ============================================================================== 70 # Module-specific functions and classes (not part of the common API) 71 # ============================================================================== 72 73 class StandardCells: # do we need this? The FACETS-ML names and the PyNN names should be the same 74 """ 75 This is a static class which which contains one method for each of the 76 standard FACETS cell models. Each method: 77 (i) has a .nest_name attribute which is the NEST-specific name for the model 78 (ii) takes a dictionary whose keys are the standard parameter names 79 (iii) returns a dictionary whose keys are the NEST-specific parameter 80 names. This dictionary also contains any extra, NEST-only parameters. 81 """ 82 83 def IF_curr_alpha(parameterDict): 84 """ 85 Integrate-and-fire cell with alpha-shaped post-synaptic current. 86 87 The keys in parameterDict must come from this list: 88 'vrest', 'cm', 'tau_m', 'tau_refrac', 'tau_syn', 'v_thresh' 89 Units: v* (mV), cm (nF), tau* (ms) 90 Any required parameters not in parameterDict will be given default values. 91 92 Returns a parameter dictionary with NEST-specific parameter names. 93 """ 94 global dt 95 96 parameters = common.default_values['IF_curr_alpha'] 97 if parameterDict: 98 for k in parameters.keys(): 99 if parameterDict.has_key(k): 100 parameters[k] = parameterDict[k] 101 if parameters['v_reset'] != parameters['v_rest']: 102 raise "It is not possible to make v_reset different from v_rest in iaf_neuron." 103 translated_parameters = { 104 'U0' : parameters['v_rest'], 105 'C' : parameters['cm']*1000.0, # C is in pF, cm in nF 106 'Tau' : parameters['tau_m'], 107 'TauR' : max(dt,parameters['tau_refrac']), 108 'TauSyn' : parameters['tau_syn'], 109 'Theta' : parameters['v_thresh'], 110 'I0' : parameters['i_offset']*1000.0, # I0 is in pA, i_offset in nA 111 'LowerBound' : -1000.0 } 112 return translated_parameters 113 114 def SpikeSourcePoisson(parameterDict): 115 """ 116 Spike source, generating spikes according to a Poisson process. 117 118 The keys in parameterDict must come from this list: 119 'rate', 'start', 'duration' 120 Units: rate (Hz), start (ms), duration (ms) 121 Any required parameters not in parameterDict will be given default values. 122 123 Returns a parameter dictionary with NEST-specific parameter names 124 """ 125 126 parameters = common.default_values['SpikeSourcePoisson'] 127 if parameterDict: 128 for k in parameters.keys(): 129 if parameterDict.has_key(k): 130 parameters[k] = parameterDict[k] 131 translated_parameters = { 132 'rate' : parameters['rate'], 133 'start' : parameters['start'], 134 'duration' : parameters['duration'], 135 'origin' : 1.0 } 136 return translated_parameters 137 138 def SpikeSourceArray(parameterDict): 139 """ 140 Spike source generating spikes at the times given in the spike_times array. 141 142 parameterDict must contain this key: spike_times, whose value should be 143 a list or numpy array containing spike times in milliseconds. 144 145 Returns a parameter dictionary with NEST-specific parameter names 146 """ 147 parameters = common.default_values['SpikeSourceArray'] 148 for k in parameters.keys(): 149 if parameterDict.has_key(k): 150 parameters[k] = parameterDict[k] 151 translated_parameters = { 152 'spike_times' : parameters['spike_times'] 153 } 154 return translated_parameters 155 156 157 setattr(IF_curr_alpha,'nest_name','iaf_neuron') 158 setattr(SpikeSourcePoisson,'nest_name','poisson_generator') 159 setattr(SpikeSourceArray,'nest_name','spike_generator') 160 IF_curr_alpha = staticmethod(IF_curr_alpha) 161 SpikeSourcePoisson = staticmethod(SpikeSourcePoisson) 162 SpikeSourceArray = staticmethod(SpikeSourceArray) 79 # Utility classes 80 # ============================================================================== 81 82 class ID(common.ID): 83 """ 84 This class is experimental. The idea is that instead of storing ids as 85 integers, we store them as ID objects, which allows a syntax like: 86 p[3,4].set('tau_m',20.0) 87 where p is a Population object. The question is, how big a memory/performance 88 hit is it to replace integers with ID objects? 89 """ 90 91 def set(self,param,val=None): 92 # We perform a call to the low-level function set() of the API. 93 # If the cellclass is not defined in the ID object, we have an error (?) : 94 if (self._cellclass == None): 95 raise Exception("Unknown cellclass") 96 else: 97 #Otherwise we use the ID one. Nevertheless, here we have a small problem in the 98 #parallel framework. Suppose a population is created, distributed among 99 #several nodes. Then a call like cell[i,j].set() should be performed only on the 100 #node who owns the cell. To do that, if the node doesn't have the cell, a call to set() 101 #do nothing... 102 ##if self._hocname != None: 103 ## set(self,self._cellclass,param,val, self._hocname) 104 set(self,self._cellclass,param,val) 105 106 def get(self,param): 107 #This function should be improved, with some test to translate 108 #the parameter according to the cellclass 109 #We have here the same problem as with set() in the parallel framework 110 if self._hocname != None: 111 return HocToPy.get('%s.%s' %(self._hocname, param),'float') 112 113 # Fonctions used only by the neuron version of pyNN, to optimize the 114 # creation of networks 115 def setHocName(self, name): 116 self._hocname = name 117 118 def getHocName(self): 119 return self._hocname 120 121 122 def checkParams(param,val=None): 123 """Check parameters are of valid types, normalise the different ways of 124 specifying parameters and values by putting everything in a dict. 125 Called by set() and Population.set().""" 126 if isinstance(param,str): 127 if isinstance(val,float) or isinstance(val,int): 128 paramDict = {param:float(val)} 129 elif isinstance(val,(str, list)): 130 paramDict = {param:val} 131 else: 132 raise common.InvalidParameterValueError 133 elif isinstance(param,dict): 134 paramDict = param 135 else: 136 raise common.InvalidParameterValueError 137 return paramDict 138 139 140 # ============================================================================== 141 # Standard cells 142 # ============================================================================== 143 144 """ 145 As I don't really care about which CellClass is it, as I will dump its parameters 146 "as it" in XML, all my CellType are a wrapper around a FacetsmlCellType 147 The creation of default parameters is done in the common constructors 148 """ 149 150 class FacetsmlCellType(object): 151 """Base class for facetsMLCellType""" 152 153 def __init__(self,facetsml_name,parameters): 154 cellsNode = initDocument('http://morphml.org/neuroml/schema','cells') 155 cellNode = xmldoc.createElementNS('http://morphml.org/neuroml/schema','cell') 156 self.domNode = cellNode 157 cellsNode.appendChild(cellNode) 158 facetsml_nameNode = xmldoc.createElementNS('http://morphml.org/neuroml/schema',facetsml_name) 159 # just dump "as it" the given parameters 160 for k in self.parameters.keys: 161 facetsml_nameNode.setAttribute(k,self.parameters[k]) 162 cellNode.appendChild(facetsml_nameNode) 163 164 165 class StandardCellType(common.StandardCellType): 166 """Base class for standardized cell model classes.""" 167 168 facetsml_name = "StandardCellType" 169 170 def __init__(self,parameters): 171 common.StandardCellType.__init__(self,parameters) 172 self.facetsmlCellType = FacetsmlCellType(facetsml_name,self.parameters) 173 174 175 class IF_curr_alpha(common.IF_curr_alpha): 176 """Leaky integrate and fire model with fixed threshold and alpha-function- 177 shaped post-synaptic current.""" 178 179 facetsml_name = "IF_curr_alpha" 180 181 def __init__(self,parameters): 182 common.IF_curr_alpha.__init__(self,parameters) 183 self.facetsmlCellType = FacetsmlCellType(facetsml_name,self.parameters) 184 185 186 class IF_curr_exp(common.IF_curr_exp): 187 """Leaky integrate and fire model with fixed threshold and 188 decaying-exponential post-synaptic current. (Separate synaptic currents for 189 excitatory and inhibitory synapses""" 190 191 facetsml_name = "IF_curr_exp" 192 193 def __init__(self,parameters): 194 common.IF_curr_exp.__init__(self,parameters) 195 self.facetsmlCellType = FacetsmlCellType(facetsml_name,self.parameters) 196 197 198 class IF_cond_alpha(common.IF_cond_alpha): 199 """Leaky integrate and fire model with fixed threshold and alpha-function- 200 shaped post-synaptic conductance.""" 201 202 facetsml_name = "IF_cond_alpha" 203 204 def __init__(self,parameters): 205 common.IF_cond_alpha.__init__(self,parameters) 206 self.facetsmlCellType = FacetsmlCellType(facetsml_name,self.parameters) 207 208 class SpikeSourcePoisson(common.SpikeSourcePoisson): 209 """Spike source, generating spikes according to a Poisson process.""" 210 211 facetsml_name = "SpikeSourcePoisson" 212 213 def __init__(self,parameters): 214 common.SpikeSourcePoisson.__init__(self,parameters) 215 self.facetsmlCellType = FacetsmlCellType(facetsml_name,self.parameters) 216 217 class SpikeSourceArray(common.SpikeSourceArray): 218 """Spike source generating spikes at the times given in the spike_times array.""" 219 220 facetsml_name = "SpikeSourceArray" 221 222 def __init__(self,parameters): 223 common.SpikeSourceArray.__init__(self,parameters) 224 self.facetsmlCellType = FacetsmlCellType(facetsml_name,self.parameters) 225 226 163 227 164 228 # ============================================================================== … … 173 237 174 238 def end(): 175 """Do any necessary cleaning up before exiting.""" 176 raise "Not yet implemented" 239 PrettyPrint(xmldoc) 177 240 178 241 def run(simtime): 179 """Run the simulation for simtime ms.""" 180 raise "Not yet implemented" 242 PrettyPrint(xmldoc) 181 243 182 244 def setRNGseeds(seedList): … … 195 257 If n==1, return just the single id. 196 258 """ 259 global gid, gidlist, nhost, myid 260 197 261 assert n > 0, 'n must be a positive integer' 198 translate = getattr(StandardCells,celltype) 199 cell_ids = None 200 raise "Not yet implemented" 262 #must look if the cellclass is not already defined 263 264 if isinstance(cellclass, type): 265 celltype = cellclass(paramDict) 266 elif isinstance(cellclass,str): 267 #define a new cellType 268 celltype = FacetsmlCellType(cellclass,paramDict) 269 270 # round-robin partitioning 271 newgidlist = [i+myid for i in range(gid,gid+n,nhost) if i < gid+n-myid] 272 for cell_id in newgidlist: 273 celltype.domNode.setAttribute("name",'cell%d' % cell_id) 274 275 gidlist.extend(newgidlist) 276 cell_list = range(gid,gid+n) 277 gid = gid+n 201 278 if n == 1: 202 return cell_ids[0] 203 else: 204 return cell_ids 205 206 def connect(source,target,weight=None,delay=None,p=1): 279 cell_list = cell_list[0] 280 return cell_list 281 282 def connect(source,target,weight=None,delay=None,synapse_type=None,p=1,rng=None): 207 283 """Connect a source of spikes to a synaptic target. source and target can 208 284 both be individual cells or lists of cells, in which case all possible 209 connections are made with probability p.""" 210 global dt 211 if weight is None: 212 weight = 0.0 213 if delay is None: 214 delay = dt 215 if type(source) != types.ListType and type(target) != types.ListType: 216 connect_id = None 217 else: 218 connect_id = [] 219 if type(source) != types.ListType: 220 source = [source] 221 if type(target) != types.ListType: 222 target = [target] 223 for src in source: 224 src = pynest.getAddress(src) 225 for tgt in target: 226 tgt = pynest.getAddress(tgt) 227 if int(p) == 1 or RandomArray.uniform(0,1)<p: 228 connect_id += [None] 229 raise "Not yet implemented" 230 return connect_id 231 232 def set(cells,celltype,param,val=None): 285 connections are made with probability p, using either the random number 286 generator supplied, or the default rng otherwise. 287 Weights should be in nA or uS.""" 288 raise Exception("Method not yet implemented") 289 290 291 def set(cells,cellclass,param,val=None): 233 292 """Set one or more parameters of an individual cell or list of cells. 234 293 param can be a dict, in which case val should not be supplied, or a string 235 294 giving the parameter name, in which case val is the parameter value. 236 celltype must be supplied for doing translation of parameter names.""" 237 translate = getattr(StandardCells,celltype) 238 if val: 239 param = {param:val} 240 if type(cells) != types.ListType: 241 cells = [cells] 242 raise "Not yet implemented" 243 244 def record(src,filename): 245 """Record spikes to a file. src can be an individual cell or a list of 246 cells.""" 247 # would actually like to be able to record to an array and choose later 248 # whether to write to a file. 249 raise "Function not yet implemented." 250 251 def record_v(source,filename): 252 """ 253 Record membrane potential to a file. source can be an individual cell or 254 a list of cells.""" 255 # would actually like to be able to record to an array and 256 # choose later whether to write to a file. 257 if type(source) == types.ListType: 258 source = [pynest.getAddress(src) for src in source] 259 else: 260 source = [pynest.getAddress(source)] 261 for src in source: 262 None 263 raise "Function not yet implemented." 264 295 cellclass must be supplied for doing translation of parameter names.""" 296 raise Exception("Method not yet implemented") 297 265 298 266 299 # ============================================================================== … … 273 306 An array of neurons all of the same type. `Population' is used as a generic 274 307 term intended to include layers, columns, nuclei, etc., of cells. 308 All cells have both an address (a tuple) and an id (an integer). If p is a 309 Population object, the address and id can be inter-converted using : 310 id = p[address] 311 address = p.locate(id) 275 312 """ 276 313 nPop = 0 … … 281 318 integer, for a one-dimensional population. 282 319 e.g., (10,10) will create a two-dimensional population of size 10x10. 283 celltype should be a string - the name of the neuron model class that 284 makes up the population. 320 cellclass should either be a standardized cell class (a class inheriting 321 from common.StandardCellType) or a string giving the name of the 322 simulator-specific model that makes up the population. 285 323 cellparams should be a dict which is passed to the neuron model 286 324 constructor 287 325 label is an optional name for the population. 288 289 example of NeuroML (completeNetwork.xml with CellGroupC example added) : 290 <net:populations> 291 <net:population name="CellGroupA"> 292 <net:cell_type>CellA</net:cell_type> 293 <net:instances> 294 <net:instance id="0"><net:location x="0" y="0" z="0"/></net:instance> 295 <net:instance id="1"><net:location x="0" y="10" z="0"/></net:instance> 296 <net:instance id="2"><net:location x="0" y="20" z="0"/></net:instance> 297 </net:instances> 298 </net:population> 299 <net:population name="CellGroupB"> 300 <net:cell_type>CellA</net:cell_type> 301 <net:instances> 302 <net:instance id="0"><net:location x="0" y="100" z="0"/></net:instance> 303 <net:instance id="1"><net:location x="20" y="100" z="0"/></net:instance> 304 </net:instances> 305 </net:population> 306 <net:population name="CellGroupC"> 307 <net:cell_type>CellC</net:cell_type> 308 <net:pop_location reference="aeag"> 309 <net:grid_arrangement> 310 <net:rectangular_location name="aefku"> 311 <meta:corner x="0" y="0" z="0"/> 312 <meta:size depth="10" height="100" width="100"/> 313 </net:rectangular_location> 314 <net:spacing x="10" y="10" z="10"/> 315 </net:grid_arrangement> 316 </net:pop_location> 317 </net:population> 318 </net:populations> 319 320 """ 326 """ 327 global gid, myid, nhost, gidlist, fullgidlist 321 328 322 329 common.Population.__init__(self,dims,cellclass,cellparams,label) 323 324 325 if not self.label: 330 #if self.ndim > 1: 331 # for i in range(1,self.ndim): 332 # if self.dim[i] != self.dim[0]: 333 # raise common.InvalidDimensionsError, "All dimensions must be the same size (temporary restriction)." 334 335 # set the steps list, used by the __getitem__() method. 336 self.steps = [1]*self.ndim 337 for i in xrange(self.ndim-1): 338 for j in range(i+1,self.ndim): 339 self.steps[i] *= self.dim[j] 340 341 if isinstance(cellclass, type): 342 #maybe we should look if the cellclass is not already defined 343 self.celltype = cellclass(cellparams) 344 self.cellparams = self.celltype.parameters 345 #not used ? 346 facetsml_name = self.celltype.facetsml_name 347 elif isinstance(cellclass, str): # not a standard model 348 #define a new cellType 349 self.celltype = FacetsmlCellType(cellclass,paramDict) 350 351 352 if not self.label: 326 353 self.label = 'population%d' % Population.nPop 327 328 354 355 356 #the <population> markup is linked, in NeuroML, to a <cell> markup, which defines the type of cells of the population 357 # the cell_type name which makes the link is here the concatenation of 'cell_type_' and population label 358 cell_type_label = 'cell_type_%s' % label 359 self.celltype.domNode. = setAttribute("name",'cell_type_%s' % label) 360 361 362 # Now the gid and cellclass are stored as instance of the ID class, which will allow a syntax like 363 # p[i,j].set(param, val). But we have also to deal with positions : a population needs to know ALL the positions 364 # of its cells, and not only those of the cells located on a particular node (i.e in self.gidlist). So 365 # each population should store what we call a "fullgidlist" with the ID of all the cells in the populations 366 # (and therefore their positions) 367 self.fullgidlist = [ID(i) for i in range(gid, gid+self.size) if i < gid+self.size] 368 369 # self.gidlist is now derived from self.fullgidlist since it contains only the cells of the population located on 370 # the node 371 self.gidlist = [self.fullgidlist[i+myid] for i in range(0, len(self.fullgidlist),nhost) if i < len(self.fullgidlist)-myid] 372 self.gid_start = gid 373 374 375 329 376 populationsNode = initDocument('http://morphml.org/networkml/schema','populations','net') 330 377 … … 332 379 populationNode.setAttribute('name',label) 333 380 populationsNode.appendChild(populationNode) 381 self.dom_node = populationNode 334 382 335 383 cell_typeNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','net:cell_type') 336 #coming from neuron.py 337 if isinstance(cellclass, type): 338 self.celltype = cellclass(cellparams) 339 self.cellparams = self.celltype.parameters 340 hoc_name = self.celltype.hoc_name 341 elif isinstance(cellclass, str): # not a standard model 342 hoc_name = cellclass 343 #end of coming 344 345 cell_typeTextNode = xmldoc.createTextNode(hoc_name) 384 cell_typeTextNode = xmldoc.createTextNode(cell_type_label) 346 385 cell_typeNode.appendChild(cell_typeTextNode) 347 386 populationNode.appendChild(cell_typeNode) 348 """ 387 388 389 390 """ 349 391 the minimal neuroml to add there is : 350 392 <net:pop_location reference="aReference"> … … 391 433 grid_arrangementNode.appendChild(spacingNode) 392 434 393 394 #cellparams would be defined in a <cell> markup which would define precisely the neuron model 395 396 397 #raise "Not yet implemented." 398 399 435 400 436 Population.nPop += 1 437 gid = gid+self.size 438 439 # We add the gidlist of the population to the global gidlist 440 gidlist += self.gidlist 441 442 # By default, the positions of the cells are their coordinates, given by the locate() 443 # method. Note that each node needs to know all the positions of all the cells 444 # in the population 445 for cell_id in self.fullgidlist: 446 cell_id.setCellClass(cellclass) 447 cell_id.setPosition(self.locate(cell_id)) 448 449 401 450 PrettyPrint(xmldoc) 402 403 404 def set(self,param,val): 451 452 453 def __getitem__(self,addr): 454 """Returns a representation of the cell with coordinates given by addr, 455 suitable for being passed to other methods that require a cell id. 456 Note that __getitem__ is called when using [] access, e.g. 457 p = Population(...) 458 p[2,3] is equivalent to p.__getitem__((2,3)). 459 """ 460 461 global gidlist 462 463 # What we actually pass around are gids. 464 if isinstance(addr,int): 465 addr = (addr,) 466 if len(addr) != len(self.dim): 467 raise common.InvalidDimensionsError, "Population has %d dimensions. Address was %s" % (self.ndim,str(addr)) 468 index = 0 469 for i,s in zip(addr,self.steps): 470 index += i*s 471 id = index + self.gid_start 472 assert addr == self.locate(id), 'index=%s addr=%s id=%s locate(id)=%s' % (index, addr, id, self.locate(id)) 473 # We return the gid as an ID object. Note that each instance of Populations 474 # distributed on several node can give the ID object, because fullgidlist is duplicated 475 # and common to all the node (not the case of global gidlist, or self.gidlist) 476 return self.fullgidlist[index] 477 478 479 def locate(self,id): 480 """Given an element id in a Population, return the coordinates. 481 e.g. for 4 6 , element 2 has coordinates (1,0) and value 7 482 7 9 483 """ 484 # id should be a gid 485 assert isinstance(id,int), "id is %s, not int" % type(id) 486 id -= self.gid_start 487 if self.ndim == 3: 488 rows = self.dim[1]; cols = self.dim[2] 489 i = id/(rows*cols); remainder = id%(rows*cols) 490 j = remainder/cols; k = remainder%cols 491 coords = (i,j,k) 492 elif self.ndim == 2: 493 cols = self.dim[1] 494 i = id/cols; j = id%cols 495 coords = (i,j) 496 elif self.ndim == 1: 497 coords = (id,) 498 else: 499 raise common.InvalidDimensionsError 500 return coords 501 502 503 def set(self,param,val=None): 405 504 """ 406 505 Set one or more parameters for every cell in the population. param 407 506 can be a dict, in which case val should not be supplied, or a string 408 507 giving the parameter name, in which case val is the parameter value. 409 e.g. p.set("tau",20.0). 410 p.set({'tau':20,'v_rest':-65}) 411 """ 412 raise "Method not yet implemented." 508 val can be a numeric value, or list of such (e.g. for setting spike times). 509 e.g. p.set("tau_m",20.0). 510 p.set({'tau_m':20,'v_rest':-65}) 511 """ 512 paramDict = checkParams(param,val) 513 514 for param,val in paramDict.items(): 515 if isinstance(val,str): 516 #I have to retrieve the <cell> markup which defines the type of cells of that population 517 # self.cellType is the cellType class, which contains the corresponding domNode 518 # self.cellType.facetsml_name, for example "IF_curr_alpha" is the name of the markup under <cell> 519 cellTypeNode = self.cellType.domNode.getElementsByTagNameNS('http://morphml.org/neuroml/schema',self.celltype.facetsml_name) 520 cellTypeNode.setAttribute(param,val) 521 522 413 523 414 524 def tset(self,parametername,valueArray): … … 417 527 valueArray, which must have the same dimensions as the Population. 418 528 """ 419 raise "Method not yet implemented" 420 421 def rset(self,parametername,rand omobj):529 raise Exception("not yet implemented") 530 531 def rset(self,parametername,rand_distr): 422 532 """ 423 533 'Random' set. Sets the value of parametername to a value taken from 424 the randomobj Random object. 425 """ 426 raise "Method not yet implemented" 427 428 def call(self,methodname,arguments): 429 """ 430 Calls the method methodname(arguments) for every cell in the population. 431 e.g. p.call("set_background","0.1") if the cell class has a method 432 set_background(). 433 """ 434 raise "Method not yet implemented" 435 436 def tcall(self,methodname,objarr): 437 """ 438 `Topographic' call. Calls the method methodname() for every cell in the 439 population. The argument to the method depends on the coordinates of the 440 cell. objarr is an array with the same dimensions as the Population. 441 e.g. p.tcall("memb_init",vinitArray) calls 442 p.cell[i][j].memb_init(vInitArray[i][j]) for all i,j. 443 """ 444 raise "Method not yet implemented" 445 446 def record(self,record_from=None): 447 """ 448 If record_from is not given, record spikes from all cells in the Population. 449 record_from can be an integer - the number of cells to record from, chosen 450 at random - or a list containing the ids (e.g., (i,j,k) tuple for a 3D 451 population) of the cells to record. 452 """ 453 raise "Method not yet implemented" 454 455 def record_v(self,record_from=None): 456 """ 457 If record_from is not given, record the membrane potential for all cells in 458 the Population. 459 record_from can be an integer - the number of cells to record from, chosen 460 at random - or a list containing the ids (e.g., (i,j,k) tuple for a 3D 461 population) of the cells to record. 462 """ 463 raise "Method not yet implemented" 464 465 466 def printSpikes(self,filename): 467 """ 468 Prints spike times to file in the two-column format 469 "spiketime cell_id" where cell_id is the index of the cell counting 470 along rows and down columns (and the extension of that for 3-D). 471 This allows easy plotting of a `raster' plot of spiketimes, with one 472 line for each cell. 473 """ 474 raise "Method not yet implemented" 475 476 def meanSpikeCount(self): 477 """ 478 Returns the mean number of spikes per neuron. 479 """ 480 raise "Method not yet implemented" 481 482 def randomInit(self,randobj): 534 rand_distr, which should be a RandomDistribution object. 535 """ 536 raise Exception("not yet implemented") 537 538 539 def randomInit(self,rand_distr): 483 540 """ 484 541 Sets initial membrane potentials for all the cells in the population to 485 542 random values. 486 543 """ 487 raise "Method not yet implemented" 488 489 def print_v(self,filename): 490 """ 491 Write membrane potential traces to file. Assumes that the cell class 492 defines an array vrecord that is used to record membrane potential. 493 """ 494 raise "Method not yet implemented" 495 544 raise Exception("not yet implemented") 545 546 496 547 497 548 class Projection(common.Projection): … … 570 621 self._targets = [] 571 622 self._sources = [] 572 #connection_method = getattr(self,'_%s' % method)573 #self.nconn = connection_method(methodParameters)574 575 576 577 578 579 623 580 624 projectionsNode = initDocument('http://morphml.org/networkml/schema','projections') … … 584 628 projectionNode.setAttribute('name',label) 585 629 projectionsNode.appendChild(projectionNode) 630 self.domNode = projectionNode 586 631 587 632 sourceNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','source') … … 606 651 postsynaptic_populationName = postsynaptic_population 607 652 608 609 653 targetTextNode = xmldoc.createTextNode(postsynaptic_populationName) 610 654 targetNode.appendChild(targetTextNode) 611 655 projectionNode.appendChild(targetNode) 612 656 613 synapse_propsNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','synapse_props') 614 615 #I don't know how to deal with that 616 projectionNode.appendChild(synapse_propsNode) 617 657 connection_method = getattr(self,'_%s' % method) 658 659 projectionNode.appendChild(connection_method(methodParameters)) 660 661 PrettyPrint(xmldoc) 662 663 664 665 # --- Connection methods --------------------------------------------------- 666 667 668 def __connect(self,synapse_type,): 669 """ 670 Here this function doesn't have the same meaning than in neuron.py, it just creates the 671 neuroML template around the connectivity_pattern 672 """ 673 """ 674 <projection name="2"> 675 <source>CellGroupA</source> 676 <target>CellGroupB</target> 677 <synapse_props> 678 <synapse_type>DoubExpSynA</synapse_type> 679 <default_values/> 680 </synapse_props> 681 <connectivity_pattern> 682 <all_to_all/> 683 </connectivity_pattern> 684 </projection> 685 """ 686 687 synapse_propsNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','synapse_props') 688 projectionNode = self.domNode 689 618 690 synapse_typeNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','synapse_type') 619 #false values to make it valid 620 synapse_typeTextNode = xmldoc.createTextNode("DoubExpSynA") 691 synapse_typeTextNode = xmldoc.createTextNode(synapse_type) 621 692 synapse_typeNode.appendChild(synapse_typeTextNode) 622 693 synapse_propsNode.appendChild(synapse_typeNode) … … 624 695 default_valuesNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','default_values') 625 696 synapse_propsNode.appendChild(default_valuesNode) 626 627 """ 628 example of connectivity_pattern to add, must be generic 629 630 <connectivity_pattern> 631 <fixed_probability probability="0.5"></fixed_probability> 632 </connectivity_pattern> 633 634 635 """ 636 697 projectionNode.appendChild(synapse_propsNode) 698 699 700 def _allToAll(self,parameters=None,synapse_type=None): 701 """ 702 Connect all cells in the presynaptic population to all cells in the 703 postsynaptic population. 704 """ 705 """ 706 <connectivity_pattern> 707 <all_to_all/> 708 </connectivity_pattern> 709 """ 710 711 #still have to create the connectivity_pattern node which will be created by its corresponding method 712 __connect(self,parameters,synapse_type) 637 713 connectivity_patternNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','connectivity_pattern') 638 projectionNode.appendChild(connectivity_patternNode) 639 640 methodNode = xmldoc.createElementNS('http://morphml.org/networkml/schema',method) 641 for key in methodParameters: 642 methodNode.setAttribute(key,methodParameters[key]) 643 644 connectivity_patternNode.appendChild(methodNode) 645 646 647 PrettyPrint(xmldoc) 648 649 650 651 652 # --- Connection methods --------------------------------------------------- 653 654 def _allToAll(self,parameters=None): 655 """ 656 Connect all cells in the presynaptic population to all cells in the postsynaptic population. 657 """ 658 allow_self_connections = True # when pre- and post- are the same population, 659 # is a cell allowed to connect to itself? 660 if parameters and parameters.has_key('allow_self_connections'): 661 allow_self_connections = parameters['allow_self_connections'] 662 raise "Method not yet implemented" 663 return len(presynaptic_neurons) * len(postsynaptic_neurons) 664 665 def _oneToOne(self): 714 715 connectivity_patternTypeNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','all_to_all') 716 connectivity_patternNode.appendChild(connectivity_patternTypeNode) 717 718 return connectivity_patternNode 719 720 721 def _oneToOne(self,synapse_type=None): 666 722 """ 667 723 Where the pre- and postsynaptic populations have the same size, connect … … 673 729 in row i of a 2D post population of size (n,m). 674 730 """ 675 raise "Method not yet implemented" 676 677 def _fixedProbability(self,parameters): 731 __connect(self,parameters,synapse_type) 732 connectivity_patternNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','connectivity_pattern') 733 734 connectivity_patternTypeNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','one_to_one') 735 connectivity_patternNode.appendChild(connectivity_patternTypeNode) 736 737 return connectivity_patternNode 738 739 740 def _fixedProbability(self,parameters,synapse_type=None): 678 741 """ 679 742 For each pair of pre-post cells, the connection probability is constant. … … 686 749 if parameters.has_key('allow_self_connections'): 687 750 allow_self_connections = parameters['allow_self_connections'] 688 689 raise "Method not yet implemented" 690 691 def _distanceDependentProbability(self,parameters): 751 752 __connect(self,parameters,synapse_type) 753 connectivity_patternNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','connectivity_pattern') 754 755 connectivity_patternTypeNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','fixed_probability') 756 connectivity_patternTypeNode.setAttribute('probability',p_connect) 757 connectivity_patternNode.appendChild(connectivity_patternTypeNode) 758 759 return connectivity_patternNode 760 761 762 def _distanceDependentProbability(self,parameters,synapse_type=None): 692 763 """ 693 764 For each pair of pre-post cells, the connection probability depends on distance. … … 695 766 for probability, involving 'd', e.g. "exp(-abs(d))", or "float(d<3)" 696 767 """ 697 allow_self_connections = True 698 if type(parameters) == types.StringType: 699 d_expression = parameters 700 else: 701 d_expression = parameters['d_expression'] 702 if parameters.has_key('allow_self_connections'): 703 allow_self_connections = parameters['allow_self_connections'] 704 raise "Method not yet implemented" 705 706 def _fixedNumberPre(self,parameters): 768 raise Exception("Method not yet implemented") 769 770 771 def _fixedNumberPre(self,parameters,synapse_type=None): 707 772 """Each presynaptic cell makes a fixed number of connections.""" 773 """ 774 <connectivity_pattern> 775 <per_cell_connection num_per_source="1.2" max_per_target="2.3" direction="PreToPost"/> 776 </connectivity_pattern> 777 """ 778 self.synapse_type = synapse_type 708 779 allow_self_connections = True 709 780 if type(parameters) == types.IntType: 710 781 n = parameters 782 assert n > 0 783 fixed = True 711 784 elif type(parameters) == types.DictType: 712 if parameters.has_key['n']: # all cells have same number of connections 713 n = parameters['n'] 714 elif parameters.has_key['rng']: # number of connections per cell follows a distribution 715 rng = parameters['rng'] 785 if parameters.has_key('n'): # all cells have same number of connections 786 n = int(parameters['n']) 787 assert n > 0 788 fixed = True 789 elif parameters.has_key('rand_distr'): # number of connections per cell follows a distribution 790 rand_distr = parameters['rand_distr'] 791 assert isinstance(rand_distr,RandomDistribution) 792 fixed = False 716 793 if parameters.has_key('allow_self_connections'): 717 794 allow_self_connections = parameters['allow_self_connections'] 718 else : # assume parameters is a rng 719 rng = parameters 720 raise "Method not yet implemented" 721 722 def _fixedNumberPost(self,parameters): #CHEAT CHEAT CHEAT 795 elif isinstance(parameters, RandomDistribution): 796 rand_distr = parameters 797 fixed = False 798 else: 799 raise Exception("Invalid argument type: should be an integer, dictionary or RandomDistribution object.") 800 801 __connect(self,parameters,synapse_type) 802 connectivity_patternNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','connectivity_pattern') 803 804 connectivity_patternTypeNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','per_cell_connection') 805 connectivity_patternTypeNode.setAttribute('num_per_source',n) 806 connectivity_patternTypeNode.setAttribute('max_per_target',n) 807 connectivity_patternTypeNode.setAttribute('direction','PreToPost') 808 connectivity_patternNode.appendChild(connectivity_patternTypeNode) 809 810 return connectivity_patternNode 811 812 813 def _fixedNumberPost(self,parameters,synapse_type=None): 723 814 """Each postsynaptic cell receives a fixed number of connections.""" 815 """ 816 <connectivity_pattern> 817 <per_cell_connection num_per_source="1.2" max_per_target="2.3" direction="PostToPre"/> 818 </connectivity_pattern> 819 """ 820 self.synapse_type = synapse_type 724 821 allow_self_connections = True 725 822 if type(parameters) == types.IntType: 726 823 n = parameters 824 assert n > 0 825 fixed = True 727 826 elif type(parameters) == types.DictType: 728 if parameters.has_key['n']: # all cells have same number of connections 729 n = parameters['n'] 730 elif parameters.has_key['rng']: # number of connections per cell follows a distribution 731 rng = parameters['rng'] 827 if parameters.has_key('n'): # all cells have same number of connections 828 n = int(parameters['n']) 829 assert n > 0 830 fixed = True 831 elif parameters.has_key('rand_distr'): # number of connections per cell follows a distribution 832 rand_distr = parameters['rand_distr'] 833 assert isinstance(rand_distr,RandomDistribution) 834 fixed = False 732 835 if parameters.has_key('allow_self_connections'): 733 836 allow_self_connections = parameters['allow_self_connections'] 734 else : # assume parameters is a rng 735 rng = parameters 736 737 raise "Method not yet implemented" 738 739 def _fromFile(self,parameters): 837 elif isinstance(parameters, RandomDistribution): 838 rand_distr = parameters 839 fixed = False 840 else: 841 raise Exception("Invalid argument type: should be an integer, dictionary or RandomDistribution object.") 842 843 __connect(self,parameters,synapse_type) 844 connectivity_patternNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','connectivity_pattern') 845 846 connectivity_patternTypeNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','per_cell_connection') 847 connectivity_patternTypeNode.setAttribute('num_per_source',n) 848 connectivity_patternTypeNode.setAttribute('max_per_target',n) 849 connectivity_patternTypeNode.setAttribute('direction','PostToPre') 850 connectivity_patternNode.appendChild(connectivity_patternTypeNode) 851 852 return connectivity_patternNode 853 854 855 856 def _fromFile(self,parameters,synapse_type=None): 740 857 """ 741 858 Load connections from a file. 742 859 """ 860 lines =[] 743 861 if type(parameters) == types.FileType: 744 862 fileobj = parameters 745 # check fileobj is already open for reading 863 # should check here that fileobj is already open for reading 864 lines = fileobj.readlines() 746 865 elif type(parameters) == types.StringType: 747 866 filename = parameters 748 867 # now open the file... 868 f = open(filename,'r') 869 lines = f.readlines() 749 870 elif type(parameters) == types.DictType: 750 871 # dict could have 'filename' key or 'file' key 751 872 # implement this... 752 pass 753 raise "Method not yet implemented" 754 755 def _fromList(self,parameters): 756 """ 757 Read connections from a list of lists, or somesuch... 758 """ 759 # Need to implement parameter parsing here... 760 raise "Method not yet implemented" 873 raise "Argument type not yet implemented" 874 875 # We read the file and gather all the data in a list of tuples (one per line) 876 input_tuples = [] 877 for line in lines: 878 single_line = line.rstrip() 879 single_line = single_line.split("\t", 4) 880 input_tuples.append(single_line) 881 f.close() 882 883 return self._fromList(input_tuples, synapse_type) 884 885 def _fromList(self,conn_list,synapse_type=None): 886 """ 887 Read connections from a list of tuples, 888 containing ['src[x,y]', 'tgt[x,y]', 'weight', 'delay'] 889 """ 890 """ 891 <projection name="NetworkConnection"> 892 <source>CellGroupA</source> 893 <target>CellGroupB</target> 894 <synapse_props> 895 <synapse_type>DoubExpSynA</synapse_type> 896 <default_values internal_delay="5" weight="1" threshold="-20"/> 897 </synapse_props> 898 <connections> 899 <connection id="1"> 900 <pre cell_id="3" segment_id = "0"/> 901 <post cell_id="1" segment_id = "1"/> 902 <properties internal_delay="10" weight="0.5"/> <!-- adjusted value --> 903 </connection> 904 </connections> 905 </projection> 906 """ 907 __connect(self,synapse_type) 908 projectionNode = self.domNode 909 connectionsNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','connections') 910 projectionNode.appendChild(connectionsNode) 911 912 # Then we go through those tuple and extract the fields 913 for i in xrange(len(conn_list)): 914 src = conn_list[i][0] 915 tgt = conn_list[i][1] 916 weight = eval(conn_list[i][2]) 917 delay = eval(conn_list[i][3]) 918 src = "[%s" %src.split("[",1)[1] 919 tgt = "[%s" %tgt.split("[",1)[1] 920 src = eval("self.pre%s" % src) 921 tgt = eval("self.post%s" % tgt) 922 923 connectionNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','connection') 924 connectionNode.setAttribute('id',i) 925 preNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','pre') 926 preNode.setAttribute('cell_id',src) 927 connectionNode.appendChild(preNode) 928 929 postNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','post') 930 postNode.setAttribute('cell_id',tgt) 931 connectionNode.appendChild(postNode) 932 933 propertiesNode = xmldoc.createElementNS('http://morphml.org/networkml/schema','properties') 934 propertiesNode.setAttribute('internal_delay',delay) 935 propertiesNode.setAttribute('weight',weight) 936 connectionNode.appendChild(propertiesNode) 937 connectionsNode.appendChild(connectionNode) 938 939 940 return connectivity_patternNode 941 761 942 762 943 # --- Methods for setting connection parameters ---------------------------- … … 765 946 """ 766 947 w can be a single number, in which case all weights are set to this 767 value, or an array with the same dimensions as the Projection array. 768 """ 769 if type(w) == types.FloatType or type(w) == types.IntType: 770 w = w*1000 771 for src,tgt in zip(self._sources,self._targets): 772 # set weight 773 raise "Method not yet implemented" 774 else: 775 raise "Method needs changing to reflect the new API" # (w can be an array) 776 777 def randomizeWeights(self,rng): 778 """ 779 Set weights to random values taken from rng. 780 """ 781 # Arguably, we could merge this with set_weights just by detecting the 782 # argument type. It could make for easier-to-read simulation code to 783 # give it a separate name, though. Comments? 784 raise "Method not yet implemented" 948 value, or a list/1D array of length equal to the number of connections 949 in the population. 950 Weights should be in nA for current-based and µS for conductance-based 951 synapses. 952 """ 953 raise Exception("Method not yet implemented") 954 955 956 def randomizeWeights(self,rand_distr): 957 """ 958 Set weights to random values taken from rand_distr. 959 """ 960 # If we have a native rng, we do the loops in hoc. Otherwise, we do the loops in 961 # Python 962 raise Exception("Method not yet implemented") 963 964 785 965 786 966 def setDelays(self,d): … … 789 969 value, or an array with the same dimensions as the Projection array. 790 970 """ 791 if type(d) == types.FloatType or type(d) == types.IntType: 792 for src,tgt in zip(self._sources,self._targets): 793 # set delays 794 raise "Method not yet implemented" 795 else: 796 raise "Method needs changing to reflect the new API" # (d can be an array) 797 798 def randomizeDelays(self,rng): 799 """ 800 Set delays to random values taken from rng. 801 """ 802 raise "Method not yet implemented" 803 971 raise Exception("Method not yet implemented") 972 973 974 def randomizeDelays(self,rand_distr): 975 """ 976 Set delays to random values taken from rand_distr. 977 """ 978 # If we have a native rng, we do the loops in hoc. Otherwise, we do the loops in 979 # Python 980 raise Exception("Method not yet implemented") 981 982 983 def setTopographicDelays(self,delay_rule,rand_distr=None): 984 """ 985 Set delays according to a connection rule expressed in delay_rule, based 986 on the delay distance 'd' and an (optional) rng 'rng'. For example, 987 the rule can be "rng*d + 0.5", with "a" extracted from the rng and 988 d being the distance. 989 """ 990 raise Exception("Method not yet implemented") 991 804 992 def setThreshold(self,threshold): 805 993 """ … … 807 995 threshold crossing, set the value of this threshold. 808 996 """ 809 raise "Method not yet implemented" 810 997 # This is a bit tricky, because in NEST the spike threshold is a 998 # property of the cell model, whereas in NEURON it is a property of the 999 # connection (NetCon). 1000 raise Exception("Method not yet implemented") 811 1001 812 1002 # --- Methods relating to synaptic plasticity ------------------------------ … … 814 1004 def setupSTDP(self,stdp_model,parameterDict): 815 1005 """Set-up STDP.""" 816 raise "Method not yet implemented" 1006 1007 # Define the objref to handle plasticity 1008 raise Exception("Method not yet implemented") 817 1009 818 1010 def toggleSTDP(self,onoff): 819 """Turn plasticity on or off.""" 820 raise "Method not yet implemented" 1011 """Turn plasticity on or off. 1012 onoff = True => ON and onoff = False => OFF. By defaut, it is on.""" 1013 # We do the loop in hoc, to speed up the code 1014 raise Exception("Method not yet implemented") 1015 821 1016 822 1017 def setMaxWeight(self,wmax): 823 1018 """Note that not all STDP models have maximum or minimum weights.""" 824 raise "Method not yet implemented" 1019 # We do the loop in hoc, to speed up the code 1020 raise Exception("Method not yet implemented") 1021 825 1022 826 1023 def setMinWeight(self,wmin): 827 1024 """Note that not all STDP models have maximum or minimum weights.""" 828 raise "Method not yet implemented" 1025 # We do the loop in hoc, to speed up the code 1026 raise Exception("Method not yet implemented") 1027 829 1028 830 1029 # --- Methods for writing/reading information to/from file. ---------------- 831 1030 832 def saveConnections(self,filename ):1031 def saveConnections(self,filename,gather=False): 833 1032 """Save connections to file in a format suitable for reading in with the 834 1033 'fromFile' method.""" 835 raise "Method not yet implemented"836 837 def printWeights(self,filename,format=None ):1034 raise Exception("Method not yet implemented") 1035 1036 def printWeights(self,filename,format=None,gather=True): 838 1037 """Print synaptic weights to file.""" 839 raise "Method not yet implemented" 840 1038 raise Exception("Method not yet implemented") 1039 1040 841 1041 def weightHistogram(self,min=None,max=None,nbins=10): 842 1042 """ … … 847 1047 # it is arguable whether functions operating on the set of weights 848 1048 # should be put here or in an external module. 849 raise "Method not yet implemented" 1049 raise Exception("Method not yet implemented") 1050 850 1051 851 1052 # ============================================================================== … … 857 1058 858 1059 # ============================================================================== 859 860 class Random:861 """Wrapper class for random number generators. The idea is to be able to use862 either simulator-native rngs, which may be more efficient, or a standard863 python rng, e.g. numpy.Random, which would allow the same random numbers to864 be used across different simulators, or simply to read externally-generated865 numbers from files."""866 867 nRand = 0868 869 def __init__(self,type='default',distribution='uniform',label=None,seed=123456789):870 """ """871 raise "Not yet implemented."872 873 def next(self,n):874 """Return n random numbers from the distribution."""875 raise "Not yet implemented." -
branches/connector-class/nest.py
r81 r88 476 476 return id 477 477 478 479 480 478 def __len__(self): 481 479 """Returns the total number of cells in the population.""" 482 480 return self.size 481 482 def __iter__(self): 483 return self.cell.flat 484 485 def __address_gen(self): 486 """ 487 Generator to produce an iterator over all cells on this node, 488 returning addresses. 489 """ 490 for i in self.__iter__(): 491 yield self.locate(i) 492 493 def addresses(self): 494 return self.__address_gen() 495 496 def ids(self): 497 return self.__iter__() 483 498 484 499 def locate(self, id): -
branches/connector-class/neuron.py
r83 r88 761 761 return self.fullgidlist[index] 762 762 763 def __iter__(self): 764 return self.__gid_gen() 765 766 def __address_gen(self): 767 """ 768 Generator to produce an iterator over all cells on this node, 769 returning addresses. 770 """ 771 for i in self.gidlist: 772 yield self.locate(i) 773 774 def __gid_gen(self): 775 """ 776 Generator to produce an iterator over all cells on this node, 777 returning gids. 778 """ 779 for i in self.gidlist: 780 yield i 781 782 def addresses(self): 783 return self.__address_gen() 784 785 def ids(self): 786 return self.__gid_gen() 763 787 764 788 def locate(self,id): … … 1132 1156 '%s = new List()' % self.hoc_label] 1133 1157 connection_method = getattr(self,'_%s' % method) 1158 self.synapse_type = target 1159 self._syn_objref = _translate_synapse_type(self.synapse_type) 1134 1160 1135 1161 if target: … … 1174 1200 # --- Connection methods --------------------------------------------------- 1175 1201 1176 def __connect(self,src,tgt ,synapse_type):1202 def __connect(self,src,tgt): 1177 1203 """ 1178 1204 Write hoc commands to connect a single pair of neurons. 1179 1205 """ 1180 syn_objref = _translate_synapse_type(synapse_type)1181 1206 cmdlist = ['nc = pc.gid_connect(%d,%s.object(%d).%s)' % (src, 1182 1207 self.post.hoc_label, 1183 1208 self.post.gidlist.index(tgt), 1184 s yn_objref),1209 self._syn_objref), 1185 1210 'tmp = %s.append(nc)' % self.hoc_label] 1186 1211 self.connections.append((src,tgt)) 1187 1212 return cmdlist 1188 1213 1189 def _allToAll(self,parameters=None ,synapse_type=None):1214 def _allToAll(self,parameters=None): 1190 1215 """ 1191 1216 Connect all cells in the presynaptic population to all cells in the … … 1200 1225 for src in self.pre.fullgidlist: 1201 1226 if allow_self_connections or self.pre != self.post or tgt != src: 1202 hoc_commands += self.__connect(src,tgt ,synapse_type)1227 hoc_commands += self.__connect(src,tgt) 1203 1228 return hoc_commands 1204 1229 1205 def _oneToOne(self, synapse_type=None):1230 def _oneToOne(self,parameters=None): 1206 1231 """ 1207 1232 Where the pre- and postsynaptic populations have the same size, connect … … 1217 1242 for tgt in self.post.gidlist: 1218 1243 src = tgt - self.post.gid_start + self.pre.gid_start 1219 hoc_commands += self.__connect(src,tgt ,synapse_type)1244 hoc_commands += self.__connect(src,tgt) 1220 1245 else: 1221 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) 1222 1247 return hoc_commands 1223 1248 1224 def _fixedProbability(self,parameters ,synapse_type=None):1249 def _fixedProbability(self,parameters): 1225 1250 """ 1226 1251 For each pair of pre-post cells, the connection probability is constant. … … 1247 1272 if HocToPy.get('rng.repick()','float') < p_connect: 1248 1273 if allow_self_connections or self.pre != self.post or tgt != src: 1249 self.__connect(src,tgt ,synapse_type)1274 self.__connect(src,tgt) 1250 1275 return hoc_commands 1251 1276 else: # use Python RNG … … 1256 1281 if rarr[j] < p_connect: 1257 1282 if allow_self_connections or self.pre != self.post or tgt != src: 1258 hoc_commands += self.__connect(src,tgt ,synapse_type)1283 hoc_commands += self.__connect(src,tgt) 1259 1284 return hoc_commands 1260 1285 1261 def _distanceDependentProbability(self,parameters ,synapse_type=None):1286 def _distanceDependentProbability(self,parameters): 1262 1287 """ 1263 1288 For each pair of pre-post cells, the connection probability depends on distance. … … 1317 1342 if alphanum: 1318 1343 if rarr[j] < eval(distance_expression): 1319 hoc_commands += self.__connect(src,tgt ,synapse_type)1344 hoc_commands += self.__connect(src,tgt) 1320 1345 elif eval(distance_expression): 1321 hoc_commands += self.__connect(src,tgt ,synapse_type)1346 hoc_commands += self.__connect(src,tgt) 1322 1347 return hoc_commands 1323 1348 1324 def _fixedNumberPre(self,parameters ,synapse_type=None):1349 def _fixedNumberPre(self,parameters): 1325 1350 """Each presynaptic cell makes a fixed number of connections.""" 1326 self.synapse_type = synapse_type1327 1351 allow_self_connections = True 1328 1352 if type(parameters) == types.IntType: … … 1358 1382 for tgt in rng.permutation(self.post.gidlist)[0:n]: 1359 1383 if allow_self_connections or (src != tgt): 1360 hoc_commands += self.__connect(src,tgt ,synapse_type)1384 hoc_commands += self.__connect(src,tgt) 1361 1385 return hoc_commands 1362 1386 1363 def _fixedNumberPost(self,parameters ,synapse_type=None):1387 def _fixedNumberPost(self,parameters): 1364 1388 """Each postsynaptic cell receives a fixed number of connections.""" 1365 self.synapse_type = synapse_type1366 1389 allow_self_connections = True 1367 1390 if type(parameters) == types.IntType: … … 1397 1420 for src in rng.permutation(self.pre.gidlist)[0:n]: 1398 1421 if allow_self_connections or (src != tgt): 1399 hoc_commands += self.__connect(src,tgt ,synapse_type)1422 hoc_commands += self.__connect(src,tgt) 1400 1423 return hoc_commands 1401 1424 1402 def _fromFile(self,parameters ,synapse_type=None):1425 def _fromFile(self,parameters): 1403 1426 """ 1404 1427 Load connections from a file. … … 1428 1451 input_tuples.append((eval(src),eval(tgt),float(w),float(d))) 1429 1452 f.close() 1430 return self._fromList(input_tuples , synapse_type)1431 1432 def _fromList(self,conn_list ,synapse_type=None):1453 return self._fromList(input_tuples) 1454 1455 def _fromList(self,conn_list): 1433 1456 """ 1434 1457 Read connections from a list of tuples, … … 1440 1463 1441 1464 # Then we go through those tuple and extract the fields 1442 self.synapse_type = synapse_type1443 1465 for i in xrange(len(conn_list)): 1444 1466 src, tgt, weight, delay = conn_list[i][:] 1445 1467 src = self.pre[tuple(src)] 1446 1468 tgt = self.post[tuple(tgt)] 1447 hoc_commands += self.__connect(src,tgt ,synapse_type)1469 hoc_commands += self.__connect(src,tgt) 1448 1470 hoc_commands += ['%s.object(%d).weight = %f' % (self.hoc_label, i, float(weight)), 1449 1471 '%s.object(%d).delay = %f' % (self.hoc_label, i, float(delay))] -
branches/connector-class/pcsim.py
r75 r88 749 749 assert orig_addr == self.locate(id), 'index=%s addr=%s id=%s locate(id)=%s' % (index, orig_addr, id, self.locate(id)) 750 750 return id 751 751 752 def __iter__(self): 753 return self.__gid_gen() 754 755 def __address_gen(self): 756 """ 757 Generator to produce an iterator over all cells on this node, 758 returning addresses. 759 """ 760 for i in self.__iter__(): 761 yield self.locate(i) 762 763 def __gid_gen(self): 764 """ 765 Generator to produce an iterator over all cells on this node, 766 returning gids. 767 """ 768 ids = self.pcsim_population.idVector() 769 for i in ids: 770 yield ID(i-ids[0]) 771 772 def addresses(self): 773 return self.__address_gen() 774 775 def ids(self): 776 return self.__iter__() 752 777 753 778 def locate(self, id): -
branches/connector-class/test/nesttests.py
r62 r88 218 218 def testInvalidIndexDimension(self): 219 219 self.assertRaises(common.InvalidDimensionsError, self.net1.__getitem__, (10,2)) 220 221 # ============================================================================== 222 class PopulationIteratorTest(unittest.TestCase): 223 """Tests of the Population class iterators.""" 224 225 def setUp(self): 226 nest.setup() 227 nest.Population.nPop = 0 228 self.net1 = nest.Population((10,),nest.IF_curr_alpha) 229 self.net2 = nest.Population((2,4,3),nest.IF_curr_exp) 230 self.net3 = nest.Population((2,2,1),nest.SpikeSourceArray) 231 self.net4 = nest.Population((1,2,1),nest.SpikeSourceArray) 232 self.net5 = nest.Population((3,3),nest.IF_cond_alpha) 233 234 def testIter(self): 235 """This needs more thought for the distributed case.""" 236 for net in self.net1, self.net2: 237 ids = [i for i in net] 238 self.assertEqual(ids, net.cell.flatten().tolist()) 239 self.assert_(isinstance(ids[0], nest.ID)) 240 241 def testAddressIter(self): 242 for net in self.net1, self.net2: 243 for id,addr in zip(net.ids(),net.addresses()): 244 self.assertEqual(id, net[addr]) 245 self.assertEqual(addr, net.locate(id)) 220 246 221 247 # ============================================================================== -
branches/connector-class/test/neurontests.py
r62 r88 238 238 def testInvalidIndexDimension(self): 239 239 self.assertRaises(common.InvalidDimensionsError, self.net1.__getitem__, (10,2)) 240 240 241 # ============================================================================== 242 class PopulationIteratorTest(unittest.TestCase): 243 """Tests of the Population class iterators.""" 244 245 def setUp(self): 246 neuron.Population.nPop = 0 247 self.net1 = neuron.Population((10,),neuron.IF_curr_alpha) 248 self.net2 = neuron.Population((2,4,3),neuron.IF_curr_exp) 249 self.net3 = neuron.Population((2,2,1),neuron.SpikeSourceArray) 250 self.net4 = neuron.Population((1,2,1),neuron.SpikeSourceArray) 251 self.net5 = neuron.Population((3,3),neuron.IF_cond_alpha) 252 253 def testIter(self): 254 """This needs more thought for the distributed case.""" 255 for net in self.net1, self.net2: 256 ids = [i for i in net] 257 self.assertEqual(ids, net.gidlist) 258 self.assert_(isinstance(ids[0], neuron.ID)) 259 260 def testAddressIter(self): 261 for net in self.net1, self.net2: 262 for id,addr in zip(net.ids(),net.addresses()): 263 self.assertEqual(id, net[addr]) 264 self.assertEqual(addr, net.locate(id)) 265 266 241 267 # ============================================================================== 242 268 class PopulationSetTest(unittest.TestCase): -
branches/connector-class/test/pcsimtests_population.py
r74 r88 93 93 self.assertRaises(common.InvalidDimensionsError, self.net1.__getitem__, (10,2)) 94 94 95 # ============================================================================== 96 class PopulationIteratorTest(unittest.TestCase): 97 """Tests of the Population class iterators.""" 98 99 def setUp(self): 100 setup() 101 Population.nPop = 0 102 self.net1 = Population((10,),IF_curr_alpha) 103 self.net2 = Population((2,4,3),IF_curr_exp) 104 self.net3 = Population((2,2,1),SpikeSourceArray) 105 self.net4 = Population((1,2,1),SpikeSourceArray) 106 self.net5 = Population((3,3),IF_curr_exp) 107 108 def testIter(self): 109 """This needs more thought for the distributed case.""" 110 for net in self.net1, self.net2: 111 ids = [i for i in net] 112 idVec = numpy.array(net.pcsim_population.idVector()) 113 idVec -= idVec[0] 114 self.assertEqual(ids, idVec.tolist()) 115 self.assert_(isinstance(ids[0], ID)) 116 117 def testAddressIter(self): 118 for net in self.net1, self.net2: 119 for id,addr in zip(net.ids(),net.addresses()): 120 self.assertEqual(id, net[addr]) 121 self.assertEqual(addr, net.locate(id)) 122 95 123 # ============================================================================== 96 124 class PopulationSetTest(unittest.TestCase):
