Changeset 94
- Timestamp:
- 06/06/07 21:26:30 (1 year ago)
- Files:
-
- branches/improved-ID/common.py (modified) (27 diffs)
- branches/improved-ID/nest.py (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/improved-ID/common.py
r92 r94 1 # encoding: utf-8 1 2 """ 2 3 Defines the PyNN classes and functions, and hence the FACETS API. … … 7 8 __version__ = "$Revision$" 8 9 9 import types, time, copy 10 import types, time, copy, sys 11 import numpy 10 12 11 13 class InvalidParameterValueError(Exception): pass … … 20 22 # Utility classes 21 23 # ============================================================================== 24 25 # The following two functions taken from 26 # http://www.nedbatchelder.com/text/pythonic-interfaces.html 27 def _functionId(obj, nFramesUp): 28 """ Create a string naming the function n frames up on the stack. """ 29 fr = sys._getframe(nFramesUp+1) 30 co = fr.f_code 31 return "%s.%s" % (obj.__class__, co.co_name) 32 33 def _abstractMethod(obj=None): 34 """ Use this instead of 'pass' for the body of abstract methods. """ 35 raise Exception("Unimplemented abstract method: %s" % _functionId(obj, 1)) 22 36 23 37 class ID(int): … … 32 46 def __init__(self,n): 33 47 int.__init__(n) 34 self. _position= None48 self.parent = None 35 49 self._cellclass = None 36 self._hocname = None 37 # The cellclass can be a global attribute of the ID object, but 38 # it may be discussed: 39 # The problem is that a call to the low-level funcitons set() and get() will need 40 # the cellclass to work. So we have to choose if we want to store that information in the ID 41 # object (as an attribute for example) or if we want to type it each time we need a call to set() 42 # or get() : p[2,3].set(SpikeSourceArray, {'spike_train' : {}}). 43 44 def set(self,param,val=None): 45 raise Exception("Not yet implemented") 46 47 def get(self,param): 48 raise Exception("Not yet implemented") 49 50 def setCellClass(self, cellclass): 51 self._cellclass = cellclass 52 53 # Here is a proposal to manage the physical position of the cell, as an 54 # attribute of the ID class. Those positions can be used by functions such 55 # as _distantDependantProbability(), setTopographicDelay()... 56 def setPosition(self,pos): 57 self._position = pos 58 59 def getPosition(self): 60 return self._position 61 50 #self._hocname = None 51 52 def __getattr__(self,name): 53 """Note that this currently does not translate units.""" 54 return _abstractMethod(self) 55 56 def __setattr__(self,name,value): 57 if name in ('parent','_cellclass','cellclass','_position','position'): 58 object.__setattr__(self,name,value) 59 else: 60 return _abstractMethod(self) 61 62 def _set_cellclass(self, cellclass): 63 if self.parent: 64 raise Exception("Cell class is determined by the Population and cannot be changed for individual neurons.") 65 else: 66 self._cellclass = cellclass # should check it is a standard cell class or a string 67 68 def _get_cellclass(self): 69 if self.parent: 70 return self.parent.celltype 71 else: 72 return self._cellclass 73 74 cellclass = property(_get_cellclass, _set_cellclass) 75 76 def _set_position(self,pos): 77 assert isinstance(pos, tuple) or isinstance(pos, numpy.ndarray) 78 assert len(pos) == 3 79 if self.parent: 80 index = numpy.where(self.parent.cell.flatten() == int(self))[0][0] 81 self.parent.positions[:,index] = pos 82 else: 83 self._position = pos 84 85 def _get_position(self): 86 if self.parent: 87 index = numpy.where(self.parent.cell.flatten() == int(self))[0][0] 88 return self.parent.positions[:,index] 89 else: 90 try: 91 return self._position 92 except (AttributeError, KeyError): 93 self._position = (int(self), 0, 0) 94 return self._position 95 96 position = property(_get_position, _set_position) 62 97 63 98 … … 162 197 'e_rev_I' : -70.0, # Reversal potential for inhibitory input in mV 163 198 'v_thresh' : -50.0, # Spike threshold in mV. 164 'v_reset' : -65.0, # Reset potential after a spike in mV.165 'i_offset' : 0.0, # Offset current in nA199 'v_reset' : -65.0, # Reset potential after a spike in mV. 200 'i_offset' : 0.0, # Offset current in nA 166 201 'v_init' : -65.0, # Membrane potential in mV at t = 0 167 202 } … … 293 328 pass 294 329 330 def __iter__(self): 331 return _abstractMethod(self) 332 333 def addresses(self): 334 return _abstractMethod(self) 335 336 def ids(self): 337 return self.__iter__() 338 339 def locate(self): 340 return _abstractMethod(self) 341 295 342 def __len__(self): 296 343 """Returns the total number of cells in the population.""" 297 344 return self.size 345 346 def _get_positions(self): 347 """ 348 Try to return self._positions. If it does not exist, create it and then return it 349 """ 350 try: 351 return self._positions 352 except AttributeError: 353 x,y,z = numpy.indices(list(self.dim) + [1]*(3-len(self.dim))).astype(float) 354 x = x.flatten(); y = y.flatten(); z = z.flatten() 355 self._positions = numpy.array((x,y,z)) 356 return self._positions 357 358 def _set_positions(self, pos_array): 359 assert isinstance(pos_array, numpy.ndarray) 360 assert pos_array.shape == (3,self.size) 361 self._positions = pos_array.copy() # take a copy in case pos_array is changed later 362 363 positions = property(_get_positions, _set_positions, 'A 3xN array (where N is the number of neurons in the Population) giving the x,y,z coordinates of all the neurons (soma, in the case of non-point models).') 298 364 299 365 def set(self,param,val=None): … … 306 372 p.set({'tau_m':20,'v_rest':-65}) 307 373 """ 308 pass374 return _abstractMethod(self) 309 375 310 376 def tset(self,parametername,valueArray): … … 313 379 valueArray, which must have the same dimensions as the Population. 314 380 """ 315 pass381 return _abstractMethod(self) 316 382 317 383 def rset(self,parametername,rand_distr): … … 320 386 rand_distr, which should be a RandomDistribution object. 321 387 """ 322 pass388 return _abstractMethod(self) 323 389 324 390 def _call(self,methodname,arguments): … … 328 394 set_background(). 329 395 """ 330 pass396 return _abstractMethod(self) 331 397 332 398 def _tcall(self,methodname,objarr): … … 338 404 p.cell[i][j].memb_init(vInitArray[i][j]) for all i,j. 339 405 """ 340 pass406 return _abstractMethod(self) 341 407 342 408 def randomInit(self,rand_distr): … … 345 411 random values. 346 412 """ 347 pass413 return _abstractMethod(self) 348 414 349 415 def record(self,record_from=None,rng=None): … … 354 420 - or a list containing the ids of the cells to record. 355 421 """ 356 pass422 return _abstractMethod(self) 357 423 358 424 def record_v(self,record_from=None,rng=None): … … 364 430 - or a list containing the ids of the cells to record. 365 431 """ 366 pass432 return _abstractMethod(self) 367 433 368 434 def printSpikes(self,filename,gather=True,compatible_output=True): … … 384 450 otherwise, a file will be written on each node. 385 451 """ 386 pass452 return _abstractMethod(self) 387 453 388 454 def print_v(self,filename,gather=True, compatible_output=True): … … 401 467 voltage files. 402 468 """ 403 pass469 return _abstractMethod(self) 404 470 405 471 def meanSpikeCount(self,gather=True): … … 408 474 """ 409 475 # gather is not relevant, but is needed for API consistency 410 pass476 return _abstractMethod(self) 411 477 412 478 # ============================================================================== … … 479 545 in row i of a 2D post population of size (n,m). 480 546 """ 481 pass547 return _abstractMethod(self) 482 548 483 549 def _fixedProbability(self,parameters,synapse_type=None): … … 560 626 """ 561 627 # Need to implement parameter parsing here... 562 pass628 return _abstractMethod(self) 563 629 564 630 # --- Methods for setting connection parameters ---------------------------- … … 569 635 value, or a list/1D array of length equal to the number of connections 570 636 in the population. 571 Weights should be in nA for current-based and uS for conductance-based637 Weights should be in nA for current-based and µS for conductance-based 572 638 synapses. 573 639 """ 574 pass640 return _abstractMethod(self) 575 641 576 642 def randomizeWeights(self,rand_distr): … … 581 647 # argument type. It could make for easier-to-read simulation code to 582 648 # give it a separate name, though. Comments? 583 pass649 return _abstractMethod(self) 584 650 585 651 def setDelays(self,d): … … 589 655 in the population. 590 656 """ 591 pass657 return _abstractMethod(self) 592 658 593 659 def randomizeDelays(self,rand_distr): … … 595 661 Set delays to random values taken from rand_distr. 596 662 """ 597 pass663 return _abstractMethod(self) 598 664 599 665 def setThreshold(self,threshold): … … 605 671 # property of the cell model, whereas in NEURON it is a property of the 606 672 # connection (NetCon). 607 pass673 return _abstractMethod(self) 608 674 609 675 … … 612 678 def setupSTDP(self,stdp_model,parameterDict): 613 679 """Set-up STDP.""" 614 pass680 return _abstractMethod(self) 615 681 616 682 def toggleSTDP(self,onoff): 617 683 """Turn plasticity on or off.""" 618 pass684 return _abstractMethod(self) 619 685 620 686 def setMaxWeight(self,wmax): 621 687 """Note that not all STDP models have maximum or minimum weights.""" 622 pass688 return _abstractMethod(self) 623 689 624 690 def setMinWeight(self,wmin): 625 691 """Note that not all STDP models have maximum or minimum weights.""" 626 pass692 return _abstractMethod(self) 627 693 628 694 # --- Methods for writing/reading information to/from file. ---------------- … … 631 697 """Save connections to file in a format suitable for reading in with the 632 698 'fromFile' method.""" 633 pass699 return _abstractMethod(self) 634 700 635 701 def printWeights(self,filename,format=None,gather=True): 636 702 """Print synaptic weights to file.""" 637 pass703 return _abstractMethod(self) 638 704 639 705 def weightHistogram(self,min=None,max=None,nbins=10): … … 645 711 # it is arguable whether functions operating on the set of weights 646 712 # should be put here or in an external module. 647 pass713 return _abstractMethod(self) 648 714 649 715 branches/improved-ID/nest.py
r86 r94 36 36 def __getattr__(self,name): 37 37 """Note that this currently does not translate units.""" 38 translated_name = self. _cellclass.translations[name][0]38 translated_name = self.cellclass.translations[name][0] 39 39 return pynest.getDict([int(self)])[0][translated_name] 40 40 … … 243 243 raise "Invalid cell type" 244 244 for id in cell_gids: 245 id.setCellClass(cellclass) 245 # #id.setCellClass(cellclass) 246 id.cellclass = cellclass 246 247 if n == 1: 247 248 return cell_gids[0] … … 447 448 448 449 for id in self.cell: 449 id.setCellClass(cellclass) 450 id.setPosition(self.locate(id)) 450 id.parent = self 451 #id.setCellClass(cellclass) 452 #id.setPosition(self.locate(id)) 451 453 452 454 if self.cellparams:

