Changeset 88
- Timestamp:
- 06/05/07 09:10:00 (1 year ago)
- Files:
-
- branches/connector-class/facetsml.py (modified) (22 diffs)
- branches/connector-class/nest.py (modified) (1 diff)
- branches/connector-class/neuron.py (modified) (12 diffs)
- branches/connector-class/pcsim.py (modified) (1 diff)
- branches/connector-class/test/nesttests.py (modified) (1 diff)
- branches/connector-class/test/neurontests.py (modified) (1 diff)
- branches/connector-class/test/pcsimtests_population.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
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 fo
